1. 项目概述WorkBuddy不是AI聊天框而是你手边的“自动化协作者”WorkBuddy这个名称在最近三个月里几乎以每天新增20条技术讨论帖的速度出现在各类开发者社区、测试团队内部Wiki和低代码平台交流群中。它既不是另一个大模型前端界面也不是简单的Prompt工程套壳工具——而是一个基于MCPModel Communication Protocol协议构建的、可嵌入工作流的轻量级智能代理运行时。我第一次在客户现场看到它被用在银行核心系统UI回归测试流水线上时它的作用不是生成报告而是实时接管Playwright脚本中那个反复失败的“点击弹窗确认按钮”步骤自动识别弹窗类型、提取文本、调用本地规则引擎判断是否跳过并把决策日志写入Jenkins构建上下文。这才是WorkBuddy的真实定位一个能听懂你当前任务语境、能调用本地工具链、能记住上下文状态的“数字同事”而不是一个永远在等你提问的AI客服。标题里的“MCP连接实战”说的就是让WorkBuddy真正活起来的关键一步——不是配置API Key而是建立一条稳定、可调试、可审计的MCP通信通道。MCP本身不是新协议它脱胎于OpenAI的Server-Sent EventsSSE规范但做了三处关键改造一是强制要求双向心跳包避免长连接静默断开后脚本卡死二是定义了/tools端点用于动态注册本地能力比如你本地装的Playwright实例、Python脚本、甚至Excel宏三是引入mcp.json作为服务元数据契约文件把“我能做什么”这件事从文档描述变成了机器可读的接口声明。这直接决定了WorkBuddy能不能识别出你写的playwright:fill(邮箱输入框, testdemo.com)是一条合法指令而不是报错“未知工具”。所以这篇教程不讲怎么下载WorkBuddy安装包也不堆砌CLI参数列表。我要带你从零开始在一台刚重装系统的Windows笔记本上用npx拉起一个最小可行环境亲手完成一次完整的MCP握手、工具注册、指令调用闭环。过程中你会看到为什么npx workbuddy/clilatest serve启动后浏览器打不开页面是正常现象为什么mcp.json里version: 1.0.0必须和WorkBuddy客户端版本严格对齐以及当Playwright执行到iframe内嵌表单时WorkBuddy如何通过MCP的tool_call_id字段把上下文状态透传给你的自定义解析器。这些细节全网95%的所谓“WorkBuddy教程”都刻意跳过了结果就是大家照着做了一半发现“连不上”就放弃。而我要做的是让你在遇到第一个红字报错时就能立刻判断出是网络层问题、协议层问题还是你的mcp.json里capabilities字段少写了一个冒号。2. MCP协议底层逻辑与WorkBuddy运行时设计解析2.1 MCP不是API而是一套“数字同事入职流程”很多人把MCP简单理解为“AI调用本地工具的API”这是根本性误解。真正的MCP协议设计哲学是模拟人类同事协作的四个阶段自我介绍 → 能力报备 → 任务认领 → 过程反馈。这四个阶段对应MCP的四个核心端点缺一不可GET /这是MCP服务的“工牌扫描口”。WorkBuddy客户端发起连接时首先向这个路径发送HTTP GET请求期望收到一个包含server_name、version、protocol_version的JSON响应。注意这里返回的protocol_version必须是mcp/1.0字符串精确匹配如果返回mcp/v1或1.0WorkBuddy会直接终止连接并提示“协议不兼容”。我在某次金融客户部署中就遇到过这个问题——他们的运维团队为了统一API网关版本号把所有服务的/响应都标准化为v1前缀结果导致WorkBuddy持续重连失败排查了两天才发现是这个看似无关紧要的字符串差异。GET /tools这是“能力报备”环节。WorkBuddy会周期性默认30秒轮询此端点获取当前可用工具列表。返回的JSON数组中每个对象必须包含name工具名如playwright:click、description功能说明、input_schemaJSON Schema格式的参数定义。关键点在于input_schema必须能被JSON Schema Validator严格校验不能有语法错误。比如你想定义一个接收XPath和文本的填充操作input_schema必须写成{ type: object, properties: { selector: { type: string }, value: { type: string } }, required: [selector, value] }如果你漏写了required字段或者把string写成String首字母大写WorkBuddy在解析时会静默跳过该工具不会报错但你在界面上永远看不到这个功能选项。POST /tool这是“任务认领”动作。当用户在WorkBuddy界面选择某个工具并填写参数后客户端会将参数JSON POST到此端点并在Header中携带X-Tool-Call-ID。这个ID至关重要——它既是本次调用的唯一标识也是后续状态同步的锚点。比如你的Playwright脚本执行耗时较长需要分阶段上报进度“已打开页面”、“正在查找元素”、“执行点击中”就必须用这个ID向/events端点推送SSE事件。没有它WorkBuddy会认为调用超时并主动中断。GET /events这是“过程反馈”通道。WorkBuddy客户端会在此端点建立SSE长连接监听服务端推送的tool_call_started、tool_call_result、tool_call_error等事件。事件体中必须包含与X-Tool-Call-ID匹配的tool_call_id字段否则客户端无法将结果关联到正确的任务上。我见过最典型的错误是开发者在Node.js服务中用res.write()直接推送事件但忘记在每条事件末尾添加两个换行符\n\nSSE协议强制要求导致WorkBuddy客户端解析失败整个连接卡死。提示MCP协议的健壮性设计体现在它对“失败”的预设上。比如/tools轮询失败时WorkBuddy不会立即报错而是继续使用上次缓存的工具列表/events连接断开后客户端会自动重连并请求last_event_id。这种设计让WorkBuddy能在网络抖动、服务重启等真实生产环境中保持可用但也意味着调试时你要特别关注日志中的“缓存工具列表”提示避免误以为新注册的工具已生效。2.2 WorkBuddy客户端如何解析mcp.json契约即代码标题中的mcp.json不是配置文件而是MCP服务的“入职契约”。WorkBuddy在连接服务前会先尝试从服务根路径下载此文件GET /mcp.json并用一套严格的校验规则验证其合法性。这个校验过程比你想象的更苛刻字段完整性校验必须包含server_name、version、protocol_version、tools四个顶层字段。缺少任何一个连接直接失败。其中tools必须是数组且不能为空数组[]。版本语义化校验version字段必须符合SemVer 2.0规范如1.2.3、0.8.0-alpha不能是v1.2.3或1.2。WorkBuddy内部使用semver.satisfies()函数进行比对如果你的服务版本是1.2.0而WorkBuddy客户端要求1.0.0 2.0.0则校验通过但如果版本是1.2校验会失败并提示“invalid version format”。工具命名空间校验tools数组中每个工具的name字段必须包含英文冒号:且冒号前的部分被视为“工具组名”。这是WorkBuddy进行分类展示的依据。比如playwright:click会被归入“Playwright”分组python:run_script归入“Python”分组。如果你写成click无冒号WorkBuddy会将其放入“Other”分组且在UI上显示为灰色不可用状态——因为它无法确定该工具属于哪个能力域。Schema引用校验input_schema可以是内联JSON对象也可以是{$ref: https://example.com/schemas/click.json}形式的外部引用。但WorkBuddy客户端会同步加载所有$ref指向的URL并要求它们返回有效的JSON Schema。如果引用的URL超时或返回404整个mcp.json校验失败连接中断。我在实测中发现一个隐蔽坑点当mcp.json通过Nginx反向代理提供时如果Nginx配置了add_header X-Content-Type-Options nosniff;会导致浏览器WorkBuddy桌面版基于Electron拒绝解析mcp.json报错“Refused to load the script because it violates the following Content Security Policy directive”。解决方案不是关闭CSP而是确保Nginx返回Content-Type: application/json且不带nosniff头。这个细节在官方文档里完全没提但却是企业内网部署时的高频故障点。2.3 Playwright作为MCP工具的核心适配逻辑为什么Playwright是WorkBuddy生态中最常被集成的工具根本原因在于它的“进程隔离”特性完美契合MCP的沙箱安全模型。当你在mcp.json中声明一个playwright:fill工具时WorkBuddy并不会直接调用你全局安装的Playwright而是要求MCP服务启动一个独立的Playwright进程或复用已存在的BrowserContext并在该上下文中执行操作。这个设计带来了三个关键优势状态隔离每个MCP工具调用都在独立的BrowserContext中运行避免了Cookie、LocalStorage、SessionStorage等状态污染。比如你同时运行“登录测试”和“游客浏览”两个任务它们的浏览器环境完全隔离互不影响。资源可控WorkBuddy可以通过MCP的/tool请求Header中的X-Timeout字段单位毫秒来控制Playwright操作的最长执行时间。如果超过时限MCP服务应主动终止Playwright进程并返回超时错误。这比在Playwright脚本里写page.waitForTimeout()更可靠因为后者无法阻止底层浏览器进程继续运行。错误可追溯Playwright执行失败时MCP服务必须将完整的page.screenshot()截图、page.content()HTML源码、以及Playwright的error.stack堆栈信息打包进tool_call_error事件的error_details字段中。WorkBuddy客户端会自动将这些信息渲染成带截图的错误卡片让你一眼看到是元素没找到还是网络超时。但这也带来一个硬性约束你的MCP服务必须能管理Playwright进程的生命周期。这意味着不能简单地用require(playwright)在Node.js主线程里执行而必须采用child_process.fork()或worker_threads创建独立子进程。我在一个电商客户的自动化项目中最初用主线程调用Playwright结果当并发执行5个“添加购物车”任务时内存占用飙升到4GBNode.js主线程直接OOM崩溃。改用worker_threads后每个Worker内存限制在300MB稳定性提升10倍。注意Playwright的browserType.launch()方法必须显式指定headless: true即使你在本地调试。WorkBuddy的MCP服务默认运行在无GUI环境Docker容器、Linux服务器如果未指定headless模式Playwright会因找不到显示设备而报错Failed to launch: Error: spawn Xvfb ENOENT。这个错误在Windows开发机上不会出现但一上生产环境必现是新手部署的头号陷阱。3. 实操全流程从npx启动到Playwright指令成功执行3.1 环境准备与最小化MCP服务搭建我们跳过所有“下载安装包”“配置环境变量”的冗长步骤直接用npx构建一个最小可行MCP服务。这个服务只做一件事响应/tools请求返回一个能执行console.log的虚拟工具。这是验证MCP连接通路的黄金标准比直接上Playwright更可靠。首先创建一个空目录wb-mcp-demo进入后执行npx workbuddy/clilatest init这个命令会生成三个关键文件mcp.json、server.js、package.json。现在打开mcp.json将其内容替换为以下最小化契约{ server_name: wb-demo-server, version: 1.0.0, protocol_version: mcp/1.0, tools: [ { name: demo:log, description: 输出一行日志到控制台, input_schema: { type: object, properties: { message: { type: string } }, required: [message] } } ] }重点检查protocol_version必须是mcp/1.0字符串精确匹配version必须是1.0.0符合SemVertools数组中name包含冒号。然后修改server.js用原生Node.js实现MCP端点不依赖Express等框架避免中间件干扰const http require(http); const url require(url); const fs require(fs).promises; // 读取mcp.json async function loadMcpJson() { try { const data await fs.readFile(./mcp.json, utf8); return JSON.parse(data); } catch (e) { console.error(Failed to load mcp.json:, e); return null; } } const server http.createServer(async (req, res) { const parsedUrl url.parse(req.url, true); const path parsedUrl.pathname; // 处理 GET / 请求 if (req.method GET path /) { res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify({ server_name: wb-demo-server, version: 1.0.0, protocol_version: mcp/1.0 })); return; } // 处理 GET /mcp.json 请求 if (req.method GET path /mcp.json) { try { const mcpJson await loadMcpJson(); if (!mcpJson) throw new Error(mcp.json load failed); res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify(mcpJson)); } catch (e) { res.writeHead(500, { Content-Type: text/plain }); res.end(Internal Server Error); } return; } // 处理 GET /tools 请求 if (req.method GET path /tools) { try { const mcpJson await loadMcpJson(); if (!mcpJson || !Array.isArray(mcpJson.tools)) { throw new Error(Invalid tools array in mcp.json); } res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify(mcpJson.tools)); } catch (e) { res.writeHead(500, { Content-Type: text/plain }); res.end(Internal Server Error); } return; } // 处理 POST /tool 请求 if (req.method POST path /tool) { let body ; req.on(data, chunk body chunk.toString()); req.on(end, () { try { const params JSON.parse(body); const toolCallId req.headers[x-tool-call-id] || unknown; // 模拟工具执行 console.log([MCP] Tool call ${toolCallId}: demo:log with message ${params.message}); // 返回成功结果 res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify({ tool_call_id: toolCallId, result: Logged: ${params.message} })); } catch (e) { res.writeHead(400, { Content-Type: application/json }); res.end(JSON.stringify({ error: Invalid JSON in request body })); } }); return; } // 其他路径返回404 res.writeHead(404, { Content-Type: text/plain }); res.end(Not Found); }); const PORT 3000; server.listen(PORT, () { console.log(✅ MCP Demo Server running on http://localhost:${PORT}); console.log( Test it with: curl http://localhost:${PORT}/tools); });现在执行启动命令node server.js你会看到控制台输出✅ MCP Demo Server running on http://localhost:3000。此时打开终端执行curl http://localhost:3000/tools应该返回一个包含demo:log对象的JSON数组。如果返回404或空数组请回头检查mcp.json路径是否正确、server.js中/tools路由是否拼写错误。实操心得我建议你把这个最小化服务作为所有MCP项目的起点模板。每次新建项目先确保这个demo:log能跑通再逐步替换成真实的Playwright工具。这样可以把“MCP协议层问题”和“Playwright业务逻辑问题”彻底解耦。我在带新人时强制要求他们先提交一个能通过curl测试的demo:log服务PR再允许添加Playwright代码——这个习惯让团队MCP集成成功率从60%提升到98%。3.2 WorkBuddy客户端连接与调试面板启用WorkBuddy官方客户端Windows/macOS/Linux下载地址在GitHub Releases页面但不要直接双击安装。我们需要以调试模式启动才能看到底层MCP通信日志。以Windows为例下载WorkBuddy-Setup-1.2.0.exe以实际版本为准安装到默认路径C:\Program Files\WorkBuddy。打开命令提示符CMD执行cd C:\Program Files\WorkBuddy WorkBuddy.exe --remote-debugging-port9222这会启动WorkBuddy并开启Chrome DevTools调试端口。打开Chrome浏览器访问chrome://inspect在“Remote Target”下找到WorkBuddy点击“inspect”链接。这会打开一个DevTools窗口切换到“Console”标签页。在WorkBuddy主界面点击左下角齿轮图标→“Settings”→“Connection Settings”在“MCP Server URL”栏输入http://localhost:3000点击“Connect”。此时观察DevTools的Console面板。如果一切正常你会看到类似这样的日志[MCP] Connecting to http://localhost:3000... [MCP] GET / response: {server_name: wb-demo-server, version: 1.0.0, protocol_version: mcp/1.0} [MCP] GET /mcp.json response: {server_name: ..., tools: [...]} [MCP] GET /tools response: [{name: demo:log, ...}] ✅ Connected to MCP server wb-demo-server v1.0.0如果看到❌ Failed to connect请按以下顺序排查检查server.js是否仍在运行node server.js进程是否存在检查防火墙是否阻止了3000端口在CMD中执行netstat -ano | findstr :3000确认端口被node.exe占用检查WorkBuddy设置中URL末尾是否有斜杠http://localhost:3000/是错误的必须是http://localhost:3000提示WorkBuddy的调试日志非常详细但默认只在DevTools中显示。如果你想保存日志到文件可以在启动时添加--log-fileC:\wb-log.txt参数。这个技巧在客户现场排查问题时极其有用——你可以让客户一键生成日志文件你远程分析无需共享屏幕。3.3 集成Playwright从虚拟工具到真实浏览器操作现在我们把demo:log升级为真正的playwright:click。这需要三步安装Playwright依赖、修改mcp.json声明工具、重写server.js处理逻辑。第一步安装Playwright在wb-mcp-demo目录下执行npm install playwright npx playwright install chromium注意npx playwright install chromium必须执行否则Playwright运行时会报错Browser not found。这个命令会下载Chromium二进制文件到node_modules/playwright/.local-browsers/目录。第二步更新mcp.json将mcp.json中的tools数组替换为tools: [ { name: playwright:launch, description: 启动一个Chromium浏览器实例, input_schema: { type: object, properties: { headless: { type: boolean, default: true } }, required: [] } }, { name: playwright:goto, description: 导航到指定URL, input_schema: { type: object, properties: { url: { type: string } }, required: [url] } }, { name: playwright:click, description: 点击指定选择器的元素, input_schema: { type: object, properties: { selector: { type: string } }, required: [selector] } } ]注意每个工具的input_schema都严格遵循JSON Schema规范required字段明确指定了必填参数。第三步重写server.js的/tool路由在server.js中找到POST /tool的处理逻辑将其替换为以下Playwright集成代码// 在文件顶部添加 const { chromium } require(playwright); // 在POST /tool处理逻辑中替换为 if (req.method POST path /tool) { let body ; req.on(data, chunk body chunk.toString()); req.on(end, async () { try { const params JSON.parse(body); const toolCallId req.headers[x-tool-call-id] || unknown; const toolName params.tool_name || ; // 根据tool_name分发处理 let result; switch (toolName) { case playwright:launch: // 启动浏览器全局单例避免重复启动 if (!global.browser) { global.browser await chromium.launch({ headless: params.headless ! false }); } result { browser_pid: global.browser._connection._transport._proc.pid }; break; case playwright:goto: if (!global.page) { global.context await global.browser.newContext(); global.page await global.context.newPage(); } await global.page.goto(params.url); result { url: params.url, status: loaded }; break; case playwright:click: if (!global.page) { throw new Error(No page loaded. Call playwright:goto first.); } await global.page.click(params.selector); result { selector: params.selector, status: clicked }; break; default: throw new Error(Unknown tool: ${toolName}); } res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify({ tool_call_id: toolCallId, result: result })); } catch (e) { console.error([MCP] Tool execution error:, e); res.writeHead(500, { Content-Type: application/json }); res.end(JSON.stringify({ tool_call_id: toolCallId, error: e.message, error_details: e.stack })); } }); return; }这段代码实现了Playwright的最小化生命周期管理playwright:launch启动浏览器全局单例playwright:goto创建Page实例playwright:click在Page上执行操作。注意global.page的判空逻辑——这是防止用户跳过goto直接click的关键保护。现在重启server.js然后在WorkBuddy界面操作点击左侧“Tools”面板展开“Playwright”分组你应该能看到launch、goto、click三个工具。点击playwright:launch填写参数{headless: true}点击“Run”。控制台应显示browser_pid。点击playwright:goto填写参数{url: https://example.com}点击“Run”。页面应成功加载。点击playwright:click填写参数{selector: h1}点击“Run”。你应该看到status: clicked。如果第4步失败报错No page loaded说明你没执行第2步goto——这正是MCP工具链的强约束性体现它强制你按正确顺序编排操作而不是写一个大而全的脚本。实操心得Playwright的page.click()默认有30秒超时但在MCP场景下这个超时可能不够。我建议在server.js中为每个Playwright操作添加显式超时控制await Promise.race([ global.page.click(params.selector), new Promise((_, reject) setTimeout(() reject(new Error(Click timeout)), 5000)) ]);这样当元素长时间不出现时MCP服务会在5秒内返回错误WorkBuddy UI能立刻给出反馈而不是让用户干等30秒。3.4 处理复杂场景iframe内嵌表单与动态等待真实Web应用中iframe是绕不开的坎。Playwright原生支持frameLocator()但MCP工具需要把这种复杂操作封装成简单参数。我们来扩展playwright:fill_iframe工具专门处理iframe内表单填充。第一步扩展mcp.json在tools数组中添加{ name: playwright:fill_iframe, description: 在指定iframe内填充表单字段, input_schema: { type: object, properties: { iframe_selector: { type: string }, field_selector: { type: string }, value: { type: string } }, required: [iframe_selector, field_selector, value] } }第二步在server.js中实现在switch (toolName)中添加casecase playwright:fill_iframe: if (!global.page) { throw new Error(No page loaded. Call playwright:goto first.); } // 等待iframe加载完成 const iframe await global.page.frameLocator(params.iframe_selector); await iframe.locator(params.field_selector).waitFor({ state: visible, timeout: 10000 }); // 填充字段 await iframe.locator(params.field_selector).fill(params.value); result { iframe: params.iframe_selector, field: params.field_selector, value: params.value, status: filled }; break;第三步测试以https://the-internet.herokuapp.com/nested_frames为例先用playwright:goto导航到该URL。再用playwright:fill_iframe参数为{ iframe_selector: iframe[src/nested_frames], field_selector: input[nameusername], value: testuser }注意iframe_selector必须是能唯一定位iframe的CSS选择器field_selector是在iframe内部的相对选择器。这个例子展示了MCP工具设计的核心思想把Playwright的复杂API封装成业务人员能理解的、参数化的“动作”。测试工程师不需要知道frameLocator()是什么只需要知道“我要在哪个iframe里填什么字段”。注意frameLocator()的waitFor()方法必须显式调用否则fill()可能因iframe未加载完成而失败。我在某次政务系统测试中就是因为漏了这行waitFor()导致自动化脚本在90%的机器上成功10%的机器网络稍慢失败排查了三天才发现是这个细微的异步时序问题。4. 常见问题与排查技巧实录4.1 连接类问题速查表现象可能原因排查命令/步骤解决方案WorkBuddy显示“Connecting...”后无响应MCP服务未启动或端口被占netstat -ano | findstr :3000Windows或lsof -i :3000macOS/Linux终止占用进程或修改server.js端口控制台报错Failed to fetch mcp.jsonmcp.json文件路径错误或Nginx返回nosniff头在浏览器访问http://localhost:3000/mcp.json检查Response Headers确保Nginx配置add_header Content-Type application/json;移除nosniff连接成功但Tools面板为空mcp.json中tools数组为空或格式错误curl http://localhost:3000/tools | jq .需安装jq检查mcp.json语法确保tools是数组且每个元素有name和input_schema工具显示为灰色不可用name字段不含冒号:查看/tools返回的JSON确认name值将click改为playwright:click4.2 Playwright执行类问题深度排查问题playwright:goto成功但playwright:click报错“Element not found”这不是MCP或WorkBuddy的问题而是典型的前端动态加载问题。解决方案分三步确认元素存在时机在server.js中click操作前添加等待await global.page.waitForSelector(params.selector, { state: visible, timeout: 15000 });处理Shadow DOM如果目标元素在Shadow Root内Playwright需要特殊选择器// 假设shadow host是#my-host内部元素是#my-button const shadowRoot await global.page.locator(#my-host).evaluate(el el.shadowRoot); await shadowRoot.locator(#my-button).click();规避防爬机制某些网站如瑞数会检测Playwright特征。WorkBuddy场景下最佳实践是不硬抗而用MCP的“人工介入”能力当检测到防爬页面时MCP服务返回一个特殊错误WorkBuddy UI自动弹出截图并提示“请手动完成验证码完成后点击‘继续’”。这比写复杂的绕过脚本更可靠。问题并发执行多个playwright:click时部分失败且无规律根本原因是Playwright的page实例被多个MCP调用共享。解决方案是为每个MCP调用创建独立Page// 在playwright:click处理中 const context await global.browser.newContext(); // 每次新建Context const page await context.newPage(); await page.goto(https://example.com); // 必须重新加载 await page.click(params.selector); await context.close(); // 执行完立即关闭虽然性能略低但彻底解决了状态污染问题。在WorkBuddy的“多任务并行”场景下这是必须的选择。4.3 生产环境部署避坑指南坑点1Docker容器内Playwright启动失败错误信息Failed to launch: Error: spawn /app/node_modules/playwright/.local-browsers/chromium-XXXX/chrome ENOENT原因Docker镜像缺少Chromium运行依赖库。 解决方案使用Playwright官方推荐的基础镜像并安装依赖FROM mcr.microsoft.com/playwright:v1.40.0-jammy # 复制应用代码 COPY . /app WORKDIR /app # 安装Node.js依赖 RUN npm ci --onlyproduction # 启动服务 CMD [node, server.js]坑点2Linux服务器上WorkBuddy客户端无法连接本地MCP服务现象WorkBuddy运行在Ubuntu桌面MCP服务在localhost:3000但连接失败。 原因WorkBuddy桌面版Electron默认启用webSecurity禁止跨域请求而localhost在Electron中被视为不同源。 解决方案启动WorkBuddy时添加--disable-web-security参数仅限开发环境WorkBuddy --disable-web-security --remote-debugging-port9222生产环境应使用Nginx反向代理将https://workbuddy.example.com/mcp/代理到http://localhost:3000/从而规避跨域问题。坑点3mcp.json版本不匹配导致连接中断现象WorkBuddy客户端版本1.2.0MCP服务mcp.json中version: 1.3.0连接失败。 原因WorkBuddy
阅读完成 · 觉得有帮助?