diff --git a/.gitignore b/.gitignore index 1170717..a1a86bf 100644 --- a/.gitignore +++ b/.gitignore @@ -126,7 +126,7 @@ dist .tern-port # Stores VSCode versions used for testing VSCode extensions -.vscode-test +.openmcp-test # yarn v2 .yarn/cache diff --git a/.vscode/openmcp_connection.json b/.vscode/openmcp_connection.json deleted file mode 100644 index 36fe563..0000000 --- a/.vscode/openmcp_connection.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "items": [ - [], - [], - [], - [ - { - "connectionType": "SSE", - "name": "SSE-1748530644202", - "version": "1.0", - "url": "http://localhost:8000/mcp", - "oauth": "" - } - ], - [], - [], - [], - [], - [], - [ - { - "connectionType": "SSE", - "name": "SSE-1748531219080", - "version": "1.0", - "url": "http://localhost:8000/sse", - "oauth": "" - } - ], - [] - ] -} \ No newline at end of file diff --git a/.vscode/tabs.my-browser.json b/.vscode/tabs.my-browser.json deleted file mode 100644 index 0c226c8..0000000 --- a/.vscode/tabs.my-browser.json +++ /dev/null @@ -1,215 +0,0 @@ -{ - "clientId": "81b3b1d6-b1d6-53b1d63c156-83b1d63c156a678-6a678e36", - "currentIndex": 0, - "tabs": [ - { - "name": "交互测试", - "icon": "icon-robot", - "type": "blank", - "componentIndex": 3, - "storage": { - "activeNames": [ - 0 - ], - "messages": [ - { - "role": "user", - "content": "使用 ffmpeg 把视频 (0, 65) 到 (1173, 769) 的位置截取出来,视频的格式是 mov,我希望导出为 mp4", - "extraInfo": { - "created": 1749111492698, - "state": "success", - "serverName": "deepseek" - } - }, - { - "role": "assistant", - "content": "你可以使用 `ffmpeg` 的 `crop` 滤镜来截取视频的指定区域,并将 `.mov` 转换为 `.mp4` 格式。以下是具体的命令:\n\n### 命令解析:\n1. **输入文件**:`input.mov`(替换为你的文件名)\n2. **裁剪参数**:\n - `crop=w:h:x:y`:从坐标 `(x,y)` 开始,截取宽度 `w`、高度 `h` 的区域。\n - 你的需求是从 `(0, 65)` 到 `(1173, 769)`,因此:\n - 宽度 `w = 1173 - 0 = 1173`\n - 高度 `h = 769 - 65 = 704`\n - 起始坐标 `(x,y) = (0, 65)`\n3. **输出格式**:`mp4`(默认使用 H.264 编码)\n\n### 完整命令:\n```bash\nffmpeg -i input.mov -filter:v \"crop=1173:704:0:65\" -c:a copy output.mp4\n```\n\n### 参数说明:\n- `-i input.mov`:指定输入文件。\n- `-filter:v \"crop=1173:704:0:65\"`:视频裁剪滤镜。\n- `-c:a copy`:直接复制音频流(无需重新编码,节省时间)。\n- `output.mp4`:输出文件名。\n\n### 其他选项:\n- 如果需要控制视频质量,可以添加 `-crf` 参数(默认 23,值越小质量越高):\n ```bash\n ffmpeg -i input.mov -filter:v \"crop=1173:704:0:65\" -crf 18 -c:a copy output.mp4\n ```\n- 如果需要硬件加速(如 NVIDIA GPU),可以添加 `-hwaccel cuda` 等参数。\n\n### 注意:\n1. 确保 `ffmpeg` 已安装并添加到系统路径。\n2. 如果视频有旋转/缩放等元数据,可能需要先处理(如用 `-vf \"transpose=1\"` 旋转)。\n\n运行命令后,`output.mp4` 就是你需要的裁剪后视频。", - "extraInfo": { - "created": 1749111520497, - "state": "success", - "serverName": "deepseek", - "usage": { - "prompt_tokens": 42, - "completion_tokens": 487, - "total_tokens": 529, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "prompt_cache_hit_tokens": 0, - "prompt_cache_miss_tokens": 42 - } - } - } - ], - "settings": { - "modelIndex": 0, - "enableTools": [ - { - "name": "k_navigate", - "description": "Navigate to a URL", - "inputSchema": { - "type": "object", - "properties": { - "url": { - "type": "string", - "description": "URL to navigate to" - }, - "launchOptions": { - "type": "object", - "description": "PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: { headless: true, args: ['--no-sandbox'] }" - }, - "allowDangerous": { - "type": "boolean", - "description": "Allow dangerous LaunchOptions that reduce security. When false, dangerous args like --no-sandbox will throw errors. Default false." - } - }, - "required": [ - "url" - ] - }, - "enabled": true - }, - { - "name": "k_screenshot", - "description": "Take a screenshot of the current page or a specific element", - "inputSchema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name for the screenshot" - }, - "selector": { - "type": "string", - "description": "CSS selector for element to screenshot" - }, - "width": { - "type": "number", - "description": "Width in pixels (default: 800)" - }, - "height": { - "type": "number", - "description": "Height in pixels (default: 600)" - } - }, - "required": [ - "name" - ] - }, - "enabled": true - }, - { - "name": "k_click", - "description": "Click an element on the page", - "inputSchema": { - "type": "object", - "properties": { - "selector": { - "type": "string", - "description": "CSS selector for element to click" - } - }, - "required": [ - "selector" - ] - }, - "enabled": true - }, - { - "name": "k_fill", - "description": "Fill out an input field", - "inputSchema": { - "type": "object", - "properties": { - "selector": { - "type": "string", - "description": "CSS selector for input field" - }, - "value": { - "type": "string", - "description": "Value to fill" - } - }, - "required": [ - "selector", - "value" - ] - }, - "enabled": true - }, - { - "name": "k_select", - "description": "Select an element on the page with Select tag", - "inputSchema": { - "type": "object", - "properties": { - "selector": { - "type": "string", - "description": "CSS selector for element to select" - }, - "value": { - "type": "string", - "description": "Value to select" - } - }, - "required": [ - "selector", - "value" - ] - }, - "enabled": true - }, - { - "name": "k_hover", - "description": "Hover an element on the page", - "inputSchema": { - "type": "object", - "properties": { - "selector": { - "type": "string", - "description": "CSS selector for element to hover" - } - }, - "required": [ - "selector" - ] - }, - "enabled": true - }, - { - "name": "k_evaluate", - "description": "Execute JavaScript in the browser console", - "inputSchema": { - "type": "object", - "properties": { - "script": { - "type": "string", - "description": "JavaScript code to execute" - } - }, - "required": [ - "script" - ] - }, - "enabled": true - }, - { - "name": "k_get_full_page_text", - "description": "获取页面所有文本内容", - "inputSchema": { - "type": "object", - "properties": {} - }, - "enabled": true - } - ], - "enableWebSearch": false, - "temperature": 0.6, - "contextLength": 20, - "systemPrompt": "猫娘", - "parallelToolCalls": true - } - } - } - ] -} \ No newline at end of file diff --git a/plugin-tutorial/usage/connect-mcp.md b/plugin-tutorial/usage/connect-mcp.md index c74bec9..267d008 100644 --- a/plugin-tutorial/usage/connect-mcp.md +++ b/plugin-tutorial/usage/connect-mcp.md @@ -66,10 +66,10 @@ MCP 客户端是指能够通过 MCP 协议进行通信的大模型对话客户 ![](./images/openmcp-control-panel.png) -当前工作区曾经连接过的 mcp 服务器会出现在这里,这是因为 openmcp 默认将工作区启动的 mcp 的连接信息存储在了 `.vscode/tabs.{server-name}.json` 中,其中 `{server-name}` 就是 mcp 服务器连接成功的服务器名称。 +当前工作区曾经连接过的 mcp 服务器会出现在这里,这是因为 openmcp 默认将工作区启动的 mcp 的连接信息存储在了 `.openmcp/tabs.{server-name}.json` 中,其中 `{server-name}` 就是 mcp 服务器连接成功的服务器名称。 :::warning -注意,同一个项目中,你不应该有两个名字完全相同的 mcp 服务器,这会导致 `.vscode/tabs.{server-name}.json` 连接信息存储冲突,发生未知错误。 +注意,同一个项目中,你不应该有两个名字完全相同的 mcp 服务器,这会导致 `.openmcp/tabs.{server-name}.json` 连接信息存储冲突,发生未知错误。 ::: 如果你想要在任意工作区都能使用同一个 mcp 服务器,可以考虑在「安装的 MCP 服务器」中添加成熟耐用的 mcp 服务器,这个位置添加的 mcp 服务器全局可用。 diff --git a/plugin-tutorial/usage/debug.md b/plugin-tutorial/usage/debug.md index 50359db..c38fd98 100644 --- a/plugin-tutorial/usage/debug.md +++ b/plugin-tutorial/usage/debug.md @@ -11,10 +11,10 @@ openmcp 具备自动保存测试结果的功能。如下的行为会触发 openm - 创建标签页,并选择一个有效的调试项目 - 在调试页进行调试行为(选择工具,执行工具,询问大模型等) -当前 mcp 项目的测试数据会被保存在 `.vscode/tabs.{server-name}.json` 中,其中 `{server-name}` 就是 mcp 服务器连接成功的服务器名称。 +当前 mcp 项目的测试数据会被保存在 `.openmcp/tabs.{server-name}.json` 中,其中 `{server-name}` 就是 mcp 服务器连接成功的服务器名称。 :::warning -注意,同一个项目中,你不应该有两个名字完全相同的 mcp 服务器,这会导致 `.vscode/tabs.{server-name}.json` 连接信息存储冲突,发生未知错误。 +注意,同一个项目中,你不应该有两个名字完全相同的 mcp 服务器,这会导致 `.openmcp/tabs.{server-name}.json` 连接信息存储冲突,发生未知错误。 ::: ## 快速调试 diff --git a/plugin-tutorial/usage/distribute-result.md b/plugin-tutorial/usage/distribute-result.md index 1c33557..2ea20c1 100644 --- a/plugin-tutorial/usage/distribute-result.md +++ b/plugin-tutorial/usage/distribute-result.md @@ -1 +1,44 @@ -# 分发您的实验结果 \ No newline at end of file +# 分发您的实验结果 + +## 标签页恢复 + +openmcp 默认会实时保存您的实验结果,每一个在工作区开启的服务器默认会将结果存储在 `.openmcp/tabs.{server-name}.json` 中,其中 `{server-name}` 就是 mcp 服务器连接成功的服务器名称。 + +请确保您的 `.gitignore` 文件中没有包含匹配到 .openmcp 文件夹的规则。这样,当您通过 git 提交你的代码,对 agent 的代码进行管理时,当你在别的电脑上 clone 或者他人 clone 你的项目时,就能快速恢复你上一次的实验内容,继续进行实验或者开发调试。 + +## 连接恢复 + +每一个 mcp 服务器的连接信息会被保存在 `.openmcp/connection.json` 中,下面是一个例子: + +```json +{ + "items": [ + [ + { + "connectionType": "STDIO", + "command": "mcp", + "args": [ + "run", + "main.py" + ], + "url": "", + "cwd": "{workspace}/simple-mcp", + "oauth": "", + "clientName": "openmcp.connect.STDIO", + "clientVersion": "0.0.1", + "env": {}, + "serverInfo": { + "name": "锦恢的 MCP Server", + "version": "1.9.2" + }, + "filePath": "{workspace}/simple-mcp/main.py", + "name": "锦恢的 MCP Server", + "version": "1.9.2" + } + ] + ] +} +``` + + +当您打开左侧的控制面板或者打开一个过去打开过的 mcp 服务器时, mcp 默认会根据上面的信息来获取工作区的服务器列表或者尝试进行自动连接。如果 openmcp 在连接 mcp 时发生了初始化错误或者保存错误,除了向 openmcp 官方求助外,您还可以尝试手动管理 `.openmcp/connection.json` 文件。 \ No newline at end of file diff --git a/plugin-tutorial/usage/images/drag-to-fill.png b/plugin-tutorial/usage/images/drag-to-fill.png new file mode 100644 index 0000000..e2ce8e9 Binary files /dev/null and b/plugin-tutorial/usage/images/drag-to-fill.png differ diff --git a/plugin-tutorial/usage/multi-server.md b/plugin-tutorial/usage/multi-server.md index d3f0290..d12bb56 100644 --- a/plugin-tutorial/usage/multi-server.md +++ b/plugin-tutorial/usage/multi-server.md @@ -11,4 +11,25 @@ openmcp 支持连接多个 MCP 服务器。 假设,我们已经连接了第一个 mcp,也就是 crawl4ai mcp,我们可以添加额外的 mcp 服务器: -![](./images/add-new-mcp.png) \ No newline at end of file +![](./images/add-new-mcp.png) + +## 添加方法一:拖拽 + +直接把需要加入的 mcp 服务器的文件,按住 shift 点击拖拽进入 openmcp 界面就能自动完成参数的填充。 + +![](./images/drag-to-fill.png) + +:::warning +自动填充的命令不一定总是准确的,在 [STDIO 连接的启动](http://localhost:5173/openmcp/plugin-tutorial/usage/connect-mcp.html#stdio-%E8%BF%9E%E6%8E%A5%E7%9A%84%E5%90%AF%E5%8A%A8) 中我们说过这一点。具体的连接方法请阅读 [附录:关于 uv 启动 mcp 你必须知道的](http://localhost:5173/openmcp/plugin-tutorial/quick-start/first-mcp.html#%E9%99%84%E5%BD%95-%E5%85%B3%E4%BA%8E-uv-%E5%90%AF%E5%8A%A8-mcp-%E4%BD%A0%E5%BF%85%E9%A1%BB%E7%9F%A5%E9%81%93%E7%9A%84) 后自行判断。 +::: + +## 添加方法二:手动填写参数 + +手动填写参数,没啥好说的。 + + +## 使用多服务器 + +多服务器连接后的使用和单服务器没有太大的区别,openmcp 内部会自动完成工具的调度和选择。唯一需要注意的是,多服务器的 tool name 一定不要重名,否则会出现冲突。 + +如果您认为 tool 重名有存在的必要性,请通过 [issue](https://github.com/LSTM-Kirigaya/openmcp-client/issues) 让我们知道您的场景和想法,根据讨论,我们会支持。 \ No newline at end of file diff --git a/scripts/move-image.js b/scripts/move-image.js index ebee575..044db7f 100644 --- a/scripts/move-image.js +++ b/scripts/move-image.js @@ -2,7 +2,7 @@ const fs = require('fs'); const path = require('path'); // 要排除的文件夹 -const excludedDirs = ['node_modules', '.vitepress', '.vscode', 'scripts']; +const excludedDirs = ['node_modules', '.vitepress', '.openmcp', 'scripts']; // 递归搜索图片文件夹 function findImageDirs(rootDir, currentDir = '', results = []) {