Cursor MCP server 连不上或看不到工具

在 Cursor 里加了 MCP server,却一直 disconnected,或聊天里看不到工具。九成是 PATH 不对、JSON 写错、或日志漏到了 stdout。五分钟内定位修好。

你在 Cursor 里加了一个 MCP server——filesystem、GitHub、或自定义的——状态点一直红。或者变绿了,可聊天里就是没工具出现。或者刚启动连上了,几分钟后又掉。Cursor 的 MCP 层很薄:拉起一个进程,走 stdio(或远程 HTTP/SSE 端点)讲 JSON-RPC,然后把 server 声明的工具注册进来。出问题几乎都集中在四处:spawn(路径不对、runtime 不在)、配置文件(一个 JSON typo 让整个文件作废)、handshake(server 把文本漏到了 stdout)、或 transport(远程 URL 用了 stdio 格式,或反过来)。

能解决大多数情况的最快一招: 打开最新的 MCP 日志(Output 面板,Cmd/Ctrl + Shift + U,再从下拉里选 MCP Logs),读第一行报错,然后(a)给 command 用绝对路径,(b)把 mcp.json 丢给 python3 -m json.tool 查有没有多余逗号。截至 2026 年 6 月,这两步能覆盖绝大部分断连。

各项东西在哪(2026 年 6 月)

2026 年初 Cursor 把面板改了名。当前路径如下:

  • 设置面板: Cmd/Ctrl + Shift + J 打开 Cursor Settings,对应区块现在叫 Tools & MCP(旧版本叫 Features → MCP)。还有一个总开关 Enable MCP servers,在某些安装里默认是的——先确认它开着。
  • 用 UI 加 server: Tools & MCP → + Add New MCP Server,弹出三个字段:NameTransport Typestdio / SSE / Streamable HTTP)、Command or URL。它会替你写进 mcp.json
  • 配置文件(全局): ~/.cursor/mcp.json,对所有项目生效。
  • 配置文件(项目): 仓库根目录的 .cursor/mcp.json,可随团队共享。两个都存在时两个都加载。
  • 日志: Output 面板(Cmd/Ctrl + Shift + U)→ MCP Logs 频道。真正的错误字符串(ENOENT、JSON parse error、鉴权失败、崩溃)都在这里。

常见原因

按命中率从高到低。

1. 一个 JSON typo 让整个文件作废

一个多余的逗号、漏掉的引号、或不配对的花括号,会让 Cursor 直接忽略整个 mcp.json——没有弹窗,所有 server 一起消失。这是”什么都不出现”最常见的原因。

怎么判断: 别靠肉眼,用解析器跑:

python3 -m json.tool ~/.cursor/mcp.json   # 或:jq . ~/.cursor/mcp.json

报错并给出行号,就是它。如果能把文件格式化打印出来,说明 JSON 没问题,bug 在别处。

2. 命令不在 PATH 上(spawn ENOENT

你配了 "command": "npx""command": "uvx",但从 Dock / 开始菜单启动的 Cursor 不会加载你的 shell rc,于是 nvm/fnm/asdf/Homebrew 加的 PATH 不在里面。哪怕同样的命令在终端能跑,server 也起不来。

怎么判断: 在 MCP Logs 里找 spawn npx ENOENTspawn uvx ENOENT、或 command not found。出现这串字符,每次都是这个 bug。

3. Stdio server 把日志打到了 stdout

MCP stdio server 的 stdout 必须只走 JSON-RPC 帧。banner、log、warning 一旦出现在 stdout 上,Cursor 读到非法 JSON 就断开。

怎么判断: 在终端手动跑一遍 server 命令。stdout 上有任何非 JSON 内容就是这个 bug。所有诊断信息都该走 stderr。

4. mcp.json 里 transport 格式写错

远程 server 要 url(外加 headers);本地 server 要 command + args。混着写——stdio 格式里塞 url,或远程条目里写 command——会静默失败。

怎么判断: 打开 mcp.json。Stdio 条目用 command / args / env;远程条目用 url / headers,transport 是 streamable-httpsse。UI 里的 Transport Type 必须和这些 key 对得上。

5. server 需要的环境变量 Cursor 没传

GitHub 本地 server 要 GITHUB_PERSONAL_ACCESS_TOKEN,自定义 server 要 API key。只在 shell rc 里设没用——spawn 出来的进程只看得到 env 里的(或 envFile 指向的文件里的)。

怎么判断: 用同一份环境变量在 Cursor 外手跑 server 命令。外面能跑、Cursor 里不行——就是 env 没传。

6. 工具加载了但在聊天里被禁用

Tools & MCP 显示绿、工具数也对,可模型从不调用工具。Cursor 在聊天面板顶部的工具列表里给每个工具单独留了开关,新工具可能默认是关的。

怎么判断: 打开聊天面板顶部的工具列表。你的 server 工具在列表里但开关是关的——把它打开。

7. Cursor 缓存了一次失败的 handshake

底层问题修好后,Cursor 有时还把 server 卡在 failed 状态,必须手动 toggle。

怎么判断: Tools & MCP → 把 server 关掉,等约 3 秒,再开。这下连上了,就是缓存的锅。

你属于哪一类?

UI 里的症状最可能的原因跳到
一个 server 都不出现JSON typo 让文件作废,或总开关关了原因 1、面板开关
某个 server 红,日志里 spawn ... ENOENT命令不在 PATH原因 2、Step 2
绿点过一会就掉server 崩了(常是 stdout 漏日志)原因 3、Step 4
绿点但工具数 = 0handshake 失败 / transport 写错原因 4、Step 4
绿点、有工具、从不被调用工具在聊天里被禁用原因 6、Step 7
远程 URL 返回 HTML/401/404URL 或鉴权 header 不对原因 4、Step 5

开始前

  • 弄清楚你的 server 是 stdio(本地进程)还是远程(HTTP/SSE),两者配置完全不同。
  • 把 server 的 README 放手边,照着写 commandargs、env 变量、或 url
  • 一次只调一个 server,两个一起调痛苦翻倍。

一步一步修复

Step 1:先验 JSON,再在 Cursor 外把 server 跑起来

先解析文件(python3 -m json.tool ~/.cursor/mcp.json)。然后把 commandargs 复制到终端跑。健康的 stdio server 应该 stdout 空(或只有 JSON),然后挂着等输入。立刻崩——bug 在 server 自己身上,跟 Cursor 无关。

Step 2:command 用绝对路径

"npx" 换成全路径。用 which npx(Windows 上 where npx)查到后粘进去。uvxpythonnode 同理。这是修 spawn ENOENT 最稳的一招。

{
  "mcpServers": {
    "filesystem": {
      "command": "/Users/you/.nvm/versions/node/v22.14.0/bin/npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"]
    }
  }
}

Step 3:env 显式传(或用 envFile)

server 需要的所有东西都要写在条目的 env 里,或用 envFile 从文件读。Cursor 给 spawn 出来的 MCP 进程不会继承你 shell 的环境。

{
  "mcpServers": {
    "github-local": {
      "command": "/usr/local/bin/docker",
      "args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "github_pat_..." }
    }
  }
}

注意环境变量名是 GITHUB_PERSONAL_ACCESS_TOKEN。旧的 @modelcontextprotocol/server-github npm 包已弃用;GitHub 现在提供官方 server(上面的 Docker 镜像,或 Step 5 的托管远程版)。

Step 4:去 MCP 日志里看 handshake

Output 面板(Cmd/Ctrl + Shift + U)→ MCP Logs,搜 server 名。你想看到 initialize 请求和成功的响应。常见失败:

  • Failed to parse JSON / Unexpected token——server 把文本漏到 stdout 了(把日志改成只走 stderr)。
  • spawn ... ENOENT——回 Step 2。
  • 0 toolsNo tools or prompts——handshake 完成了但 server 没声明任何工具;检查 server 自己的启动参数。

Step 5:远程 server 优先用托管端点,并先验一下

GitHub 的托管 server 最省事——不用 runtime、不用 Docker。用 url 格式加 bearer header:

{
  "mcpServers": {
    "github": {
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer github_pat_..." }
    }
  }
}

在怪 Cursor 之前先独立验证端点:

curl -X POST https://api.githubcopilot.com/mcp/ \
  -H "Authorization: Bearer github_pat_..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'

健康的响应是一个含 serverInfocapabilities 的 JSON。返回 HTML、401/403、或 404,说明 URL 或 token 不对(重新生成带正确 scope 的 PAT)。如果 server 用 OAuth 而非静态 token,Cursor 会处理浏览器授权流程,并注册回调地址 cursor://anysphere.cursor-mcp/oauth/callback

Step 6:toggle,然后完全重启

Tools & MCP → 把 server 关再开。还不生效就完全退出 Cursor(Cmd+Q / 从托盘退出——不是只关窗口),重新打开。MCP server 只在启动和 toggle 时 re-spawn,存盘不会。

Step 7:在聊天里把工具打开

打开聊天面板顶部的工具列表,找到你的 server,把 server 级和工具级开关全部打开。某些 Cursor 版本新工具默认是关的,看起来和 server 坏了一模一样。

怎么验证修好了

  • Tools & MCP 显示绿点、工具数大于 0。
  • MCP Logs 里 initialize 成功,后面没有 parse 报错。
  • 在聊天里发一个该触发工具的 prompt(比如「List my GitHub repos」),看有没有工具调用卡片执行并返回结果。
  • 退出再重启 Cursor,确认 server 自动重连、工具数一致。

长期预防

  • 给 server 钉死版本(如 @modelcontextprotocol/server-filesystem@2026.1.0),别用浮动 tag,免得上游一次坏发布把你的环境拖垮。
  • mcp.json 纳入版本管理但不含 secret;token 用 envFile 或 shell wrapper 加载。
  • CI 加一步 python3 -m json.tool .cursor/mcp.json,typo 进不来。
  • 把需要的 env 变量和 scope 写到 README 的 MCP 配置块旁边。
  • 厂商有托管/远程版就优先用——比本地 runtime 少很多变数。

容易踩的坑

  • Cursor 开着改 mcp.json 还指望它 hot reload。它只在启动和 toggle 时读。
  • 把 user 级 ~/.cursor/mcp.json 和 workspace 级 .cursor/mcp.json 搞混——两个都存在时两个都加载,过时的全局条目还会盖掉你的项目条目。
  • stdio server 在 stdout 上打了一行「Server started on port 3000」就把协议破坏了。
  • GitHub server 要 GITHUB_PERSONAL_ACCESS_TOKEN,你却用了 GITHUB_TOKEN
  • 以为 Cursor 会发现启动后新加的工具——不会,重启。

常见问答

  • mcp.json 在哪里? 全局是 ~/.cursor/mcp.json,项目里是 .cursor/mcp.json。两个都在就两个都加载。
  • Stdio 还是远程选哪个? 本地进程(filesystem、git)用 stdio。托管或团队共享 server 用远程(HTTP/SSE),比如 GitHub 的 https://api.githubcopilot.com/mcp/。远程能绕开 PATH 和 runtime 的麻烦。
  • 改完文件整个列表空了,为什么? 几乎都是 JSON 语法错误让文件作废。跑 python3 -m json.tool ~/.cursor/mcp.json,再确认总开关 Enable MCP servers 是开着的。
  • 为什么几分钟后状态点变红? server 进程退出了。开 MCP Logs 或手跑命令,在 stderr 上看崩溃原因。
  • 在终端能跑、Cursor 里不行。 典型 PATH 缺失——从 Dock 启动的 Cursor 不加载 shell rc。给 command 用绝对路径(Step 2)。
  • MCP 配置能和团队共享吗? 能——提交 .cursor/mcp.json,secret 留外面(用 envFile),把需要的 env 变量和 scope 在 README 里写清楚。

相关

标签: #Cursor #mcp #排查 #排查