Merge pull request #20 from LSTM-Kirigaya/main

sync
This commit is contained in:
Li Yaning 2025-05-26 21:40:31 +08:00 committed by GitHub
commit fc68a12b30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 52 additions and 24 deletions

View File

@ -1,5 +1,11 @@
# Change Log
## [main] 0.1.1
- 修复 SSH 连接 Ubuntu 的情况下的部分 bug
- 修复 python 项目点击 openmcp 进行连接时,初始化参数错误的问题
- 取消 service 底层的 mcp 连接复用技术,防止无法刷新
- 修复连接后,可能无法在欢迎界面选择调试选项的 bug
## [main] 0.1.0
- 新特性:支持同时连入多个 mcp server
- 新特性:更新协议内容,支持 streamable http 协议,未来将逐步取代 SSE 的连接方式

View File

@ -9,6 +9,8 @@
<a href="https://discord.gg/af5cfB9a" target="_blank" style="display: inline-block; padding: 8px 16px; background-color: rgb(84, 176, 84); color: white; border-radius: .5em; text-decoration: none;"> 加入 OpenMCP Discord频道</a>
<a href="https://github.com/LSTM-Kirigaya/openmcp-document" target="_blank" style="display: inline-block; padding: 8px 16px; background-color: rgb(84, 176, 84); color: white; border-radius: .5em; text-decoration: none;"> 📄OpenMCP 文档仓库</a>
</div>
@ -17,6 +19,7 @@
一款用于 MCP 服务端调试的一体化 vscode/trae/cursor 插件。
<video src="https://github.com/user-attachments/assets/ab214d58-b77c-4bd3-8b6e-55552f4036ff" width="100%"></video>
<video src="https://github.com/user-attachments/assets/c17a4ad7-83b4-47ff-8627-85b57ad18940" width="100%"></video>

View File

@ -2,7 +2,7 @@
"name": "openmcp",
"displayName": "OpenMCP",
"description": "An all in one MCP Client/TestTool",
"version": "0.1.0",
"version": "0.1.1",
"publisher": "kirigaya",
"author": {
"name": "kirigaya",

View File

@ -6,7 +6,7 @@
</span>
<p>
OpenMCP Client 0.1.0 OpenMCP@<a href="https://www.zhihu.com/people/can-meng-zhong-de-che-xian">锦恢</a> 开发
OpenMCP Client 0.1.1 OpenMCP@<a href="https://www.zhihu.com/people/can-meng-zhong-de-che-xian">锦恢</a> 开发
</p>
<p>

View File

@ -471,7 +471,8 @@ class McpClientAdapter {
for (const item of launchSignature) {
// 创建一个新的客户端
const client = reactive(new McpClient());
// const client = reactive(new McpClient());
const client = new McpClient();
// 同步连接参数
await client.acquireConnectionSignature(item);
@ -562,6 +563,10 @@ class McpClientAdapter {
return msg;
}
public get connected() {
return this.clients.length > 0 && this.clients[0].connectionResult.success;
}
public async loadPanels() {
const masterNode = this.clients[0];
await loadPanels(masterNode);

View File

@ -62,11 +62,11 @@ function selectServer(index: number) {
}
function addServer() {
const client = reactive(new McpClient());
// const client = reactive(new McpClient());
const client = new McpClient();
mcpClientAdapter.clients.push(client);
mcpClientAdapter.currentClientIndex = mcpClientAdapter.clients.length - 1;
client.handleEnvSwitch(true);
mcpClientAdapter.clients.at(-1)!.handleEnvSwitch(true);
}

View File

@ -7,7 +7,7 @@
<!-- TODO: 支持更多的 server -->
<span
class="debug-option"
:class="{ 'disable': !client.connectionResult.success }"
:class="{ 'disable': !mcpClientAdapter.connected }"
v-for="(option, index) of debugOptions"
:key="index"
@click="chooseDebugMode(index)"
@ -32,7 +32,6 @@ import { mcpClientAdapter } from '../connect/core';
defineComponent({ name: 'welcome' });
const { t } = useI18n();
const client = mcpClientAdapter.masterNode;
const debugOptions = [
{
@ -60,7 +59,7 @@ const debugOptions = [
function chooseDebugMode(index: number) {
// TODO: server
if (client.connectionResult.success) {
if (mcpClientAdapter.connected) {
const activeTab = tabs.activeTab;
activeTab.component = markRaw(debugModes[index]);

View File

@ -30,6 +30,7 @@ export async function routeMessage(command: string, data: any, webview: PostMess
webview.postMessage({ command, data: res });
}
} catch (error) {
console.error(error);
webview.postMessage({
command, data: {
code: 500,

View File

@ -133,8 +133,12 @@ export class McpClient {
// 调用工具
public async callTool(options: { name: string; arguments: Record<string, any>, callToolOption?: any }) {
const { callToolOption, ...methodArgs } = options;
console.log('methodArgs', methodArgs);
console.log('callToolOption', callToolOption);
return await this.client.callTool(methodArgs, undefined, callToolOption);
const res = await this.client.callTool(methodArgs, undefined, callToolOption);
console.log('callTool res', res);
return res;
}
}

View File

@ -249,12 +249,15 @@ export async function connectService(
const uuid = await deterministicUUID(JSON.stringify(option));
const reuseConntion = clientMap.has(uuid);
if (!clientMap.has(uuid)) {
// if (!clientMap.has(uuid)) {
// const client = await connect(option);
// clientMap.set(uuid, client);
// }
// const client = clientMap.get(uuid)!;
const client = await connect(option);
clientMap.set(uuid, client);
}
const client = clientMap.get(uuid)!;
const versionInfo = client.getServerVersion();

View File

@ -1,6 +1,6 @@
{
"clientId": "83313e18-3e18-513e1883c06-813e1883c060a6b-60a6b641",
"currentIndex": 1,
"currentIndex": 0,
"tabs": [
{
"name": "交互测试",

View File

@ -22,8 +22,8 @@ export class McpInstalledConnectProvider implements vscode.TreeDataProvider<Conn
const connection = getConnectionConfig();
const sidebarItems = connection.items.map((item, index) => {
// 连接的名字
item = Array.isArray(item)? item[0] : item;
const itemName = `${item.name} (${item.type || item.connectionType})`
const nItem = Array.isArray(item)? item[0] : item;
const itemName = `${nItem.name} (${nItem.type || nItem.connectionType})`
return new ConnectionViewItem(itemName, vscode.TreeItemCollapsibleState.None, item, 'server');
})

View File

@ -22,8 +22,8 @@ export class McpWorkspaceConnectProvider implements vscode.TreeDataProvider<Conn
const connection = getWorkspaceConnectionConfig();
const sidebarItems = connection.items.map((item, index) => {
// 连接的名字
item = Array.isArray(item) ? item[0] : item;
const itemName = `${item.name} (${item.type || item.connectionType})`
const nItem = Array.isArray(item) ? item[0] : item;
const itemName = `${nItem.name} (${nItem.type || nItem.connectionType})`
return new ConnectionViewItem(itemName, vscode.TreeItemCollapsibleState.None, item, 'server');
})

View File

@ -5,6 +5,9 @@ export async function deleteUserConnection(item: McpOptions[] | McpOptions) {
// 弹出确认对话框
const masterNode = Array.isArray(item) ? item[0] : item;
const name = masterNode.name;
console.log('enter delete');
const confirm = await vscode.window.showWarningMessage(
`确定要删除连接 "${name}" 吗?`,
{ modal: true },
@ -18,6 +21,10 @@ export async function deleteUserConnection(item: McpOptions[] | McpOptions) {
const workspaceConnectionConfig = getWorkspaceConnectionConfig();
// 从配置中移除该连接项
console.log(item);
console.log(workspaceConnectionConfig.items);
// TODO: 改成基于 path 进行搜索
const index = workspaceConnectionConfig.items.indexOf(item);
if (index !== -1) {
workspaceConnectionConfig.items.splice(index, 1);

View File

@ -1,7 +1,8 @@
import * as vscode from 'vscode';
import { RegisterCommand } from "../common";
import { getDefaultLanunchSignature, getLaunchCWD, revealOpenMcpWebviewPanel } from './webview.service';
import { getDefaultLanunchSignature, getWorkspacePath, revealOpenMcpWebviewPanel } from './webview.service';
import { getWorkspaceConnectionConfigItemByPath } from '../global';
import path from 'path';
export class WebviewController {
@RegisterCommand('openmcp.showOpenMCP')
@ -10,8 +11,7 @@ export class WebviewController {
if (!connectionItem) {
// 项目不存在连接信息
const cwd = getLaunchCWD(context, uri);
const cwd = path.dirname(uri.fsPath);
const signature = getDefaultLanunchSignature(uri.fsPath, cwd);
if (!signature) {

View File

@ -24,7 +24,7 @@ export function getWebviewContent(context: vscode.ExtensionContext, panel: vscod
return html;
}
export function getLaunchCWD(context: vscode.ExtensionContext, uri: vscode.Uri) {
export function getWorkspacePath(context: vscode.ExtensionContext, uri: vscode.Uri) {
// TODO: 启动上下文?
// 获取当前打开的项目的路径
const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);