This commit is contained in:
锦恢 2025-06-01 03:40:16 +08:00
parent ab81e276d3
commit 97f89b0833
19 changed files with 253 additions and 64 deletions

View File

@ -1,5 +1,13 @@
# Change Log # Change Log
## [main] 0.1.2
- 新特性:用户发送的信息增加「重新发送」按钮。
- 支持特性 issue#17 「关于左侧添加mcp服务器操作优化问题」增加强制聚焦功能用户创建mcp服务器连接的过程中不会让输入框失去焦点。
- 更新 MCP & OpenAI 协议内容。
- 解决 issue#21 vscode插件界面bug在高度有限情况下无法通过滚动完全显示连接按钮。
- 解决 issue#21 最后一个标签页关闭并恢复默认页面。
- 解决 issue#22 工具模块UI异常现在 openmcp 支持解析 pydantic 进行 typing 的 python mcp 了。
## [main] 0.1.1 ## [main] 0.1.1
- 修复 SSH 连接 Ubuntu 的情况下的部分 bug - 修复 SSH 连接 Ubuntu 的情况下的部分 bug
- 修复 python 项目点击 openmcp 进行连接时,初始化参数错误的问题 - 修复 python 项目点击 openmcp 进行连接时,初始化参数错误的问题

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 62 KiB

169
package-lock.json generated
View File

@ -1,23 +1,23 @@
{ {
"name": "openmcp", "name": "openmcp",
"version": "0.1.0", "version": "0.1.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "openmcp", "name": "openmcp",
"version": "0.1.0", "version": "0.1.1",
"workspaces": [ "workspaces": [
"service", "service",
"renderer", "renderer",
"software" "software"
], ],
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.12.1",
"@seald-io/nedb": "^4.1.1", "@seald-io/nedb": "^4.1.1",
"axios": "^1.7.7", "axios": "^1.7.7",
"bson": "^6.8.0", "bson": "^6.8.0",
"openai": "^4.93.0", "openai": "^5.0.1",
"pako": "^2.1.0", "pako": "^2.1.0",
"tesseract.js": "^6.0.1", "tesseract.js": "^6.0.1",
"uuid": "^11.1.0", "uuid": "^11.1.0",
@ -1516,12 +1516,12 @@
} }
}, },
"node_modules/@modelcontextprotocol/sdk": { "node_modules/@modelcontextprotocol/sdk": {
"version": "1.11.4", "version": "1.12.1",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.4.tgz", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.12.1.tgz",
"integrity": "sha512-OTbhe5slIjiOtLxXhKalkKGhIQrwvhgCDs/C2r8kcBTy5HR/g43aDQU0l7r8O0VGbJPTNJvDc7ZdQMdQDJXmbw==", "integrity": "sha512-KG1CZhZfWg+u8pxeM/mByJDScJSrjjxLc8fwQqbsS8xCjBmQfMNEBTotYdNanKekepnfRI85GtgQlctLFpcYPw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ajv": "^8.17.1", "ajv": "^6.12.6",
"content-type": "^1.0.5", "content-type": "^1.0.5",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-spawn": "^7.0.5", "cross-spawn": "^7.0.5",
@ -1537,6 +1537,28 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@modelcontextprotocol/sdk/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"license": "MIT"
},
"node_modules/@openmcp/electron": { "node_modules/@openmcp/electron": {
"resolved": "software", "resolved": "software",
"link": true "link": true
@ -3238,6 +3260,7 @@
"version": "8.17.1", "version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
@ -5852,7 +5875,6 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-redact": { "node_modules/fast-redact": {
@ -5874,6 +5896,7 @@
"version": "3.0.6", "version": "3.0.6",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
"integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -7360,6 +7383,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/json-stringify-safe": { "node_modules/json-stringify-safe": {
@ -8389,19 +8413,10 @@
} }
}, },
"node_modules/openai": { "node_modules/openai": {
"version": "4.100.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.100.0.tgz", "resolved": "https://registry.npmjs.org/openai/-/openai-5.0.1.tgz",
"integrity": "sha512-9soq/wukv3utxcuD7TWFqKdKp0INWdeyhUCvxwrne5KwnxaCp4eHL4GdT/tMFhYolxgNhxFzg5GFwM331Z5CZg==", "integrity": "sha512-Do6vxhbDv7cXhji/4ct1lrpZYMAOmjYbhyA9LJTuG7OfpbWMpuS+EIXkRT7R+XxpRB1OZhU/op4FU3p3uxU6gw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
},
"bin": { "bin": {
"openai": "bin/cli" "openai": "bin/cli"
}, },
@ -8418,21 +8433,6 @@
} }
} }
}, },
"node_modules/openai/node_modules/@types/node": {
"version": "18.19.101",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.101.tgz",
"integrity": "sha512-Ykg7fcE3+cOQlLUv2Ds3zil6DVjriGQaSN/kEpl5HQ3DIGM6W0F2n9+GkWV4bRt7KjLymgzNdTnSKCbFUUJ7Kw==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/openai/node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"node_modules/opencollective-postinstall": { "node_modules/opencollective-postinstall": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
@ -8965,7 +8965,6 @@
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
@ -9198,6 +9197,7 @@
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@ -10725,7 +10725,6 @@
"version": "4.4.1", "version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"punycode": "^2.1.0" "punycode": "^2.1.0"
@ -11448,6 +11447,51 @@
"node": ">=14.14" "node": ">=14.14"
} }
}, },
"renderer/node_modules/openai": {
"version": "4.104.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz",
"integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==",
"license": "Apache-2.0",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
},
"bin": {
"openai": "bin/cli"
},
"peerDependencies": {
"ws": "^8.18.0",
"zod": "^3.23.8"
},
"peerDependenciesMeta": {
"ws": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"renderer/node_modules/openai/node_modules/@types/node": {
"version": "18.19.110",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.110.tgz",
"integrity": "sha512-WW2o4gTmREtSnqKty9nhqF/vA0GKd0V/rbC0OyjSk9Bz6bzlsXKT+i7WDdS/a0z74rfT2PO4dArVCSnapNLA5Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"renderer/node_modules/openai/node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"renderer/node_modules/vite": { "renderer/node_modules/vite": {
"version": "6.3.5", "version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
@ -11603,9 +11647,9 @@
"version": "0.0.1", "version": "0.0.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.12.1",
"@seald-io/nedb": "^4.1.1", "@seald-io/nedb": "^4.1.1",
"openai": "^4.96.0", "openai": "^5.0.1",
"pako": "^2.1.0", "pako": "^2.1.0",
"pino": "^9.6.0", "pino": "^9.6.0",
"pino-pretty": "^13.0.0", "pino-pretty": "^13.0.0",
@ -11785,6 +11829,51 @@
"electron-builder": "^24.13.3", "electron-builder": "^24.13.3",
"typescript": "^5.6.3" "typescript": "^5.6.3"
} }
},
"software/node_modules/@types/node": {
"version": "18.19.110",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.110.tgz",
"integrity": "sha512-WW2o4gTmREtSnqKty9nhqF/vA0GKd0V/rbC0OyjSk9Bz6bzlsXKT+i7WDdS/a0z74rfT2PO4dArVCSnapNLA5Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"software/node_modules/openai": {
"version": "4.104.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz",
"integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==",
"license": "Apache-2.0",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
},
"bin": {
"openai": "bin/cli"
},
"peerDependencies": {
"ws": "^8.18.0",
"zod": "^3.23.8"
},
"peerDependenciesMeta": {
"ws": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"software/node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
} }
} }
} }

View File

@ -2,7 +2,7 @@
"name": "openmcp", "name": "openmcp",
"displayName": "OpenMCP", "displayName": "OpenMCP",
"description": "An all in one MCP Client/TestTool", "description": "An all in one MCP Client/TestTool",
"version": "0.1.1", "version": "0.1.2",
"publisher": "kirigaya", "publisher": "kirigaya",
"author": { "author": {
"name": "kirigaya", "name": "kirigaya",
@ -233,11 +233,11 @@
"build:task-loop": "webpack --config webpack/webpack.task-loop.js" "build:task-loop": "webpack --config webpack/webpack.task-loop.js"
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.12.1",
"@seald-io/nedb": "^4.1.1", "@seald-io/nedb": "^4.1.1",
"axios": "^1.7.7", "axios": "^1.7.7",
"bson": "^6.8.0", "bson": "^6.8.0",
"openai": "^4.93.0", "openai": "^5.0.1",
"pako": "^2.1.0", "pako": "^2.1.0",
"tesseract.js": "^6.0.1", "tesseract.js": "^6.0.1",
"uuid": "^11.1.0", "uuid": "^11.1.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -16,6 +16,9 @@
<el-button @click="copy"> <el-button @click="copy">
<span class="iconfont icon-copy"></span> <span class="iconfont icon-copy"></span>
</el-button> </el-button>
<el-button @click="reload">
<span class="iconfont icon-restart"></span>
</el-button>
<el-button @click="toggleEdit"> <el-button @click="toggleEdit">
<span class="iconfont icon-edit2"></span> <span class="iconfont icon-edit2"></span>
</el-button> </el-button>
@ -91,6 +94,16 @@ const copy = async () => {
} }
}; };
const reload = async () => {
const index = tabStorage.messages.findIndex(msg => msg.extraInfo === props.message.extraInfo);
if (index !== -1 && chatContext.handleSend) {
// index index
tabStorage.messages.splice(index);
chatContext.handleSend(props.message.content);
}
};
</script> </script>
<style> <style>

View File

@ -60,7 +60,7 @@ export function createTab(type: string, index: number): Tab {
if (customName !== null) { if (customName !== null) {
return customName; return customName;
} }
return t('blank-test') + ` ${index}`; return t('blank-test');
}, },
set name(value: string) { set name(value: string) {
customName = value; // 允许外部修改 name customName = value; // 允许外部修改 name
@ -85,8 +85,6 @@ export function addNewTab() {
export function closeTab(index: number) { export function closeTab(index: number) {
if (tabs.content.length <= 1) return; // 至少保留一个标签页
tabs.content.splice(index, 1); tabs.content.splice(index, 1);
console.log(tabs.content); console.log(tabs.content);
@ -95,4 +93,8 @@ export function closeTab(index: number) {
if (tabs.activeIndex >= index) { if (tabs.activeIndex >= index) {
tabs.activeIndex = Math.max(0, tabs.activeIndex - 1); tabs.activeIndex = Math.max(0, tabs.activeIndex - 1);
} }
if (tabs.content.length === 0) {
addNewTab();
}
} }

View File

@ -90,16 +90,23 @@ console.log(tabStorage.formData);
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const loading = ref(false); const loading = ref(false);
const currentTool = computed(() => { const currentTool = computed(() => {
for (const client of mcpClientAdapter.clients) { for (const client of mcpClientAdapter.clients) {
const tool = client.tools?.get(tabStorage.currentToolName); const tool = client.tools?.get(tabStorage.currentToolName);
if (tool) return tool; if (tool) {
console.log(tool);
return tool;
}
} }
}); });
const formRules = computed<FormRules>(() => { const formRules = computed<FormRules>(() => {
const rules: FormRules = {}; const rules: FormRules = {};
if (!currentTool.value?.inputSchema?.properties) return rules; if (!currentTool.value?.inputSchema?.properties) return rules;
Object.entries(currentTool.value.inputSchema.properties).forEach(([name, property]) => { Object.entries(currentTool.value.inputSchema.properties).forEach(([name, property]) => {

View File

@ -10,6 +10,7 @@ export interface InputSchema {
properties: Record<string, SchemaProperty>; properties: Record<string, SchemaProperty>;
required?: string[]; required?: string[];
title?: string; title?: string;
$defs?: any;
} }
export interface Argument { export interface Argument {
@ -40,6 +41,7 @@ export interface ToolItem {
name: string; name: string;
description: string; description: string;
inputSchema: InputSchema; inputSchema: InputSchema;
anyOf?: any;
} }
export interface ToolsListResponse { export interface ToolsListResponse {
tools: ToolItem[] tools: ToolItem[]

View File

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

View File

@ -121,4 +121,9 @@ const validateForm = async () => {
border-radius: 4px; border-radius: 4px;
margin-bottom: 16px; margin-bottom: 16px;
} }
.connection-option .el-form-item {
margin-bottom: 0;
}
</style> </style>

View File

@ -53,7 +53,7 @@ function clearLogs() {
<style> <style>
.connection-log { .connection-log {
height: 90vh; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: 12px;

View File

@ -1,5 +1,5 @@
<template> <template>
<el-scrollbar> <el-scrollbar height="98%">
<div class="connection-container" @dragover.prevent="handleDragOver" @drop.prevent="handleDrop"> <div class="connection-container" @dragover.prevent="handleDragOver" @drop.prevent="handleDrop">
<div v-if="isDraging" class="drag-mask"> <div v-if="isDraging" class="drag-mask">
<span class="iconfont icon-connect"></span> <span class="iconfont icon-connect"></span>
@ -24,7 +24,6 @@
</div> </div>
</div> </div>
</el-scrollbar> </el-scrollbar>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -126,6 +125,7 @@ function handleDrop(event: DragEvent) {
<style> <style>
.connection-container { .connection-container {
display: flex; display: flex;
max-height: 85vh;
} }
@ -133,7 +133,6 @@ function handleDrop(event: DragEvent) {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 45%; width: 45%;
max-height: 85vh;
max-width: 500px; max-width: 500px;
min-width: 350px; min-width: 350px;
padding: 5px 20px; padding: 5px 20px;
@ -143,7 +142,6 @@ function handleDrop(event: DragEvent) {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 55%; width: 55%;
max-height: 85vh;
min-width: 450px; min-width: 450px;
padding: 5px 20px; padding: 5px 20px;
} }

View File

@ -30,6 +30,66 @@ function prettifyMapKeys(keys: MapIterator<string>) {
return result.join('\n'); return result.join('\n');
} }
function _processSchemaNode(node: any, defs: Record<string, any> = {}): any {
// Handle $ref references
if ('$ref' in node) {
const refPath = node['$ref'];
if (refPath.startsWith('#/$defs/')) {
const refName = refPath.split('/').pop();
if (refName && refName in defs) {
// Process the referenced definition
return _processSchemaNode(defs[refName], defs);
}
}
}
// Start with a new schema object
const result: Record<string, any> = {};
// Copy the basic properties
if ('type' in node) {
result.type = node.type;
}
// Handle anyOf (often used for optional fields with None)
if ('anyOf' in node) {
const nonNullTypes = node.anyOf.filter((t: any) => t?.type !== 'null');
if (nonNullTypes.length > 0) {
// Process the first non-null type
const processed = _processSchemaNode(nonNullTypes[0], defs);
Object.assign(result, processed);
}
}
// Handle description
if ('description' in node) {
result.description = node.description;
}
// Handle object properties recursively
if (node?.type === 'object' && 'properties' in node) {
result.type = 'object';
result.properties = {};
// Process each property
for (const [propName, propSchema] of Object.entries(node.properties)) {
result.properties[propName] = _processSchemaNode(propSchema as any, defs);
}
// Add required fields if present
if ('required' in node) {
result.required = node.required;
}
}
// Handle arrays
if (node?.type === 'array' && 'items' in node) {
result.type = 'array';
result.items = _processSchemaNode(node.items, defs);
}
return result;
}
export class McpClient { export class McpClient {
// 连接入参 // 连接入参
@ -139,6 +199,11 @@ export class McpClient {
this.tools = new Map<string, ToolItem>(); this.tools = new Map<string, ToolItem>();
msg.tools.forEach(tool => { msg.tools.forEach(tool => {
const standardSchema = _processSchemaNode(tool.inputSchema, tool.inputSchema.$defs || {});
console.log(standardSchema);
tool.inputSchema = standardSchema;
this.tools!.set(tool.name, tool); this.tools!.set(tool.name, tool);
}); });

View File

@ -104,18 +104,15 @@ function deleteServer(index: number) {
display: flex; display: flex;
align-items: center; align-items: center;
width: 150px; width: 150px;
height: 50px;
border-right: 1px solid var(--border-color); border-right: 1px solid var(--border-color);
padding: 15px 25px; padding: 0 25px;
} }
.server-name { .server-name {
font-size: 15px; font-size: 12px;
} }
.server-item { .server-item {
padding: 10px;
margin-bottom: 5px;
cursor: pointer; cursor: pointer;
border-radius: 4px; border-radius: 4px;
display: flex; display: flex;

View File

@ -36,9 +36,9 @@
"webpack-node-externals": "^3.0.0" "webpack-node-externals": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2", "@modelcontextprotocol/sdk": "^1.12.1",
"@seald-io/nedb": "^4.1.1", "@seald-io/nedb": "^4.1.1",
"openai": "^4.96.0", "openai": "^5.0.1",
"pako": "^2.1.0", "pako": "^2.1.0",
"pino": "^9.6.0", "pino": "^9.6.0",
"pino-pretty": "^13.0.0", "pino-pretty": "^13.0.0",

View File

@ -58,7 +58,8 @@ export async function acquireInstalledConnection(): Promise<McpOptions[]> {
// 让用户选择连接类型 // 让用户选择连接类型
const connectionType = await vscode.window.showQuickPick(['STDIO', 'SSE', 'STREAMABLE_HTTP'], { const connectionType = await vscode.window.showQuickPick(['STDIO', 'SSE', 'STREAMABLE_HTTP'], {
placeHolder: '请选择连接类型', placeHolder: '请选择连接类型',
canPickMany: false canPickMany: false,
ignoreFocusOut: true,
}); });
if (!connectionType) { if (!connectionType) {

View File

@ -59,8 +59,10 @@ export async function validateAndGetCommandPath(command: string, cwd?: string):
export async function acquireUserCustomConnection(): Promise<McpOptions[]> { export async function acquireUserCustomConnection(): Promise<McpOptions[]> {
// 让用户选择连接类型 // 让用户选择连接类型
const connectionType = await vscode.window.showQuickPick(['STDIO', 'SSE'], { const connectionType = await vscode.window.showQuickPick(['STDIO', 'SSE', 'STREAMABLE_HTTP'], {
placeHolder: '请选择连接类型' placeHolder: '请选择连接类型',
canPickMany: false,
ignoreFocusOut: true,
}); });
if (!connectionType) { if (!connectionType) {