ClaudeMap

·MCP 服务器

MCP 服务器配置 2026 实战——Claude Desktop 和 Claude Code 各自的配置文件路径、三层优先级(企业 / / 用户)、stdio 与 HTTP 配置形态、filesystem / GitHub / Postgres 三个真实服务器示例、OAuth scope 漂移调试,以及 7 步排错清单。

在 Claude Desktop 和 Claude Code 里配置 MCP 服务器(2026)

MCP 真正发挥价值的时刻,是当你把服务器接进日常用的 Host。本指南基于 MCP 2025-11-25 规范,详细讲清楚 Claude Desktop / Claude Code / Cursor / Zed 的统一 JSON 配置格式、filesystem / GitHub / Postgres 三个真实参考服务器的完整可运行示例、双 Host 的差异(stdio vs stdio+OAuth)、以及「服务器死活加载不出来」的 7 步排错清单。

TL;DR

  • 所有 MCP Host 都读同一份 JSON 配置,结构是 {mcpServers: {name: {command, args, env}}}
  • stdin 服务器command + args + envHTTP 服务器url + headers
  • Claude Desktop 配置:~/Library/Application Support/Claude/claude_desktop_config.json(macOS)
  • Claude Code 配置:项目级 .mcp.json + 用户级 ~/.claude.json —— 比 Desktop 多一层优先级
  • 排错顺序:先 Inspector 跑得通 → 看 Host 日志 → 验证环境变量透传 → 检查权限与 sandbox
  • 2026 年新坑:claude_desktop_config.jsonclaude.json 字段名不同,OAuth scope 漂移

各个 Host 的配置文件在哪里

动手之前,先搞清楚文件放在哪。

Claude Desktop 读取一个单一配置文件:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json
  • Linux:~/.config/Claude/claude_desktop_config.json

Claude Desktop 也在 UI 里暴露了这个文件:打开 Settings → Developer → Edit Config,它就会用你的编辑器打开该文件,你也能在里面启用、停用、查看服务器。

Claude Code 从多个层级读取 MCP 服务器并合并:

  • 项目根目录下的 .mcp.json(提交到仓库、团队共享)
  • ~/.claude.json 或你的用户级设置(个人服务器)
  • 插件提供的服务器

项目的 .mcp.json 是你应该提交到 git 的那个,它是把一组 MCP 服务器分享给所有在这个仓库工作的人的标准方式。

两个 Host 都使用相同的 mcpServers 结构,所以你写一次的服务器条目,只需改改路径就能在它们之间迁移。

配置的结构

每个配置都是一个对象,带一个 mcpServers 键,其值是一个「服务器名 → 服务器定义」的 map。名字只是你自己起的标签——它会显示在 Host UI 里,也出现在工具名里。每个定义需要 commandargs,可选 env

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/absolute/path/to/index.js"],
      "env": {
        "API_KEY": "sk-..."
      }
    }
  }
}

有几条规则值得记住:

  • 用绝对路径。 相对路径是相对 Host 的工作目录解析的,而那个目录不总是你以为的那个。把服务器入口的绝对路径写死,能消掉一大类「我这能跑」的 bug。
  • command 是一个可执行文件,不是 shell 字符串。 如果你需要 shell,就跑 bashcmd,在 args 里带 -c 和脚本。
  • env 是叠加的。 被拉起的进程会继承 Host 的环境变量,这里的条目会合并到上面。API token 和配置标志都放这里。
  • 服务器名在一个配置文件里必须唯一。 重复的键会静默覆盖。

文件系统服务器

官方的 @modelcontextprotocol/server-filesystem 把一组目录以可读、可写资源的形式暴露给模型。它是配置起来最简单的真实服务器,也很适合作为第一个冒烟测试。

先全局安装一次,让 Host 能找到它:

npm install -g @modelcontextprotocol/server-filesystem

然后把它加进 claude_desktop_config.json

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/me/projects",
        "/Users/me/notes"
      ]
    }
  }
}

末尾的路径参数是允许服务器访问的目录。列表之外的任何东西对模型都是不可见的——这个边界就是安全模型,所以精确列出你想暴露的根目录,不要多列。保存文件并重启 Claude Desktop 后,你可以问「我 projects 目录里有哪些文件?」,模型就会调用文件系统服务器来回答。

对 Claude Code 来说,同样的条目放在项目根目录的 .mcp.json 里。Claude Code 也支持交互式添加:

claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /Users/me/projects

CLI 会把条目写进正确的配置层级,并在写入时校验 JSON。

GitHub 服务器

官方的 GitHub MCP 服务器(@modelcontextprotocol/server-github)让模型通过 GitHub REST API 读取 issue、pull request 和仓库元数据。它需要一个个人访问 token,这正是 env 块的用武之地。

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    }
  }
}

github.com/settings/tokens 创建 token 时,只勾你实际需要的 scope(私有仓库勾 repo,组织数据勾 read:org)。把 token 当成密码——绝不要把带真实 token 的配置提交进仓库。如果你要分享项目配置,就用占位符并注明真实值放哪,或者从一个 gitignore 掉的本地文件加载。

加载好之后,你可以问模型类似「列出我仓库里标签为 bug 的 open issue」或「总结一下 PR #1234 的评论」,它会调用 GitHub 服务器去取数据。在 Claude Code 里,工具会以 mcp__github__<工具名> 的形式出现,这样一眼就能看出某个工具来自哪个服务器。

Postgres 服务器

官方的 Postgres 服务器(@modelcontextprotocol/server-postgres)以只读(默认)方式暴露一个数据库:表、schema,以及运行 SELECT 查询的能力。你传一个连接字符串:

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-postgres",
        "postgresql://user:password@localhost:5432/mydb"
      ]
    }
  }
}

数据库场景下有几点要注意:

  • 优先用只读角色。 Postgres 服务器默认只读,但用一个只有 SELECT 权限的角色连接是双保险。绝不要把生产环境的写用户连接串交给模型。
  • schema 很重要。 模型靠读 schema 来决定运行什么查询,所以命名清晰的 schema 能产生质量高得多的查询。
  • 连接池。 每个 MCP 服务器进程持有一个自己的连接。本地开发库没问题;对共享数据库,把它指向像 PgBouncer 这样的连接池。

Claude Desktop 与 Claude Code

两个 Host 重合度很高,但有几个实际差异。

Claude Desktop 是一个带图形设置面板的桌面应用。你编辑 claude_desktop_config.json、重启应用,服务器就会出现在输入框旁的锤子图标下。它没有按项目的配置——每个聊天看到的是同一组服务器。

Claude Code 是一个跟你的代码住在一起的终端工具。它的 .mcp.json 按项目存在并提交到 git,所以一个仓库可以声明自己依赖的服务器。它还会在上面叠加用户级和插件提供的服务器。你可以把服务器限定到某个项目、用 claude mcp list 查看、用 claude mcp remove <名字> 移除。工具前缀约定(mcp__<服务器>__<工具>)让每一次工具调用的来源都一目了然。

实践上:Claude Desktop 配置适合放个人、跨项目的服务器(你的笔记、你的日历);项目的 .mcp.json 适合放跟某个代码库运作方式绑定的服务器(它的数据库、它的 issue 追踪器、它的内部 API)。

让改动生效

MCP 服务器是由 Host 拉起的,所以配置改动只有在 Host 重新加载后才会生效:

  • Claude Desktop —— 完整退出并重启应用。关掉窗口不算数;服务器进程会一直跑到应用退出。
  • Claude Code —— 开一个新会话,或者在运行中的会话里执行 /mcp 重新连接。

如果重启后服务器还是不出现,第一件事是检查 JSON 能不能解析。一个多余的逗号或缺失的大括号会让 Host 静默忽略整个配置,所有服务器都加载不上。不确定的话,把文件丢进 JSON 校验器过一遍。

字段优先级:Claude Code 的多层覆盖模型

Claude Desktop 只读一份配置(claude_desktop_config.json),但 Claude Code 用三层叠加——这是新用户最容易踩坑的地方:

| 层 | 路径 | 用途 | 优先级 | |---|---|---|---| | 企业托管 | MDM 推送 / managed settings | 公司统一分发 | 最高(不可覆盖) | | 项目级 | <project>/.mcp.json | 团队共享,提交到 git | 高 | | 用户级 | ~/.claude.jsonmcpServers 字段 | 个人常用工具,跨项目可用 | 低 |

合并规则:同一 slug 的服务器,企业层覆盖项目层覆盖用户层。这意味着 (1) 团队里某个老员工的本地工具不会泄露给整个项目(被项目级覆盖),(2) 公司 MDN 推的强制审计服务器无法被个人绕过。

.mcp.jsonclaude_desktop_config.json关键字段差异

  • .mcp.json(Claude Code 项目级)支持 trust 字段——true 时跳过 Host 启动时的二次确认提示。
  • ~/.claude.json(Claude Code 用户级)有 enableMcpServers 列表——显式 allowlist,未列出的 server 即使配置了也不启动(这是 2026 年新增的 safety feature)。
  • Desktop 与 Code 共享字段名:command / args / env / url / headers 都一致,但 Desktop 的 claude_desktop_config.json 顶层是 mcpServers,Code 的 ~/.claude.json 顶层是 mcpServers 但会嵌套在其它用户级配置中(参考 code.claude.com/docs/en/mcp)。

反模式:把含敏感 token 的 server 放在 ~/.claude.json 然后推到 git。用户级配置的 token 应该只对单台机器有效——任何需要在团队共享的配置都必须放 .mcp.json 且 token 通过 secret store 注入。

stdio vs HTTP:何时该切换配置形态

{command, args, env} 适合本地的 stdio 服务器(MCP 2025-11-25 transports 规范)——Host 把 server 当子进程拉起,三字段直接映射到 child_process.spawn优势:零网络、零鉴权、零运维。劣势:server 必须与 Host 同机、无法团队共享。

{url, headers} 适合远端 Streamable HTTP 服务器——Host 通过 HTTP POST + SSE 与独立机器上的 server 通信。OAuth 2.1 + Bearer Token 通过 headers.Authorization 透传authorization 规范)。优势:可跨机器、可团队共享、可被 Claude Desktop / Code / Cursor 同时调用。劣势:多一层 OAuth 运维。

配置示例:stdio → HTTP 切换

// stdio:server 在本机
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..." }
    }
  }
}

// HTTP:server 在远端,需要 OAuth
{
  "mcpServers": {
    "github": {
      "url": "https://mcp.example.com/github",
      "headers": {
        "Authorization": "Bearer ${GITHUB_MCP_TOKEN}"
      }
    }
  }
}

决策原则

  • 个人本地工具 → stdio 永远够用
  • 团队共享 server → HTTP,唯一选择
  • 一个 server 被多个 Host 复用(Desktop + Code + Cursor 都想用)→ HTTP,stdio 下每个 Host 各 fork 一份,配置无法同步
  • SaaS / 公共目录 → HTTP + MCP Registry(modelcontextprotocol/registry

迁移步骤:(1(1) 把 server 业务逻辑与 transport 适配解耦;(2) 用 官方 SDK 的 Streamable HTTP transport 重新包一层;(3) 配置 OAuth 2.1 与 headers.Authorization;(4) 在 server 端实施 session 隔离(Mcp-Session-Id);(5) 跑 security best practices) 清单(Origin 校验 + DNS rebinding 防御)。

OAuth scope 漂移:远端 server 最常见的"昨天能调今天不行"

当你切换到 HTTP server 后,最容易出现的诡异问题是:本地用 Inspector 调得通,Host 一调就 401 with no body。90% 是 OAuth scope 漂移——Host 拿到的 token 不包含 server 实际需要的 resource scope。

OAuth 2.1 + RFC 8707 Resource Indicators 在 MCP 里的具体表现:

| 症状 | 根因 | 修法 | |---|---|---| | Inspector OK,Host 401 | Host 用的 token scope 不含此 resource | 在 headers.Authorization 用 scope 正确的 token,或触发 OAuth refresh | | 调得通但 tools/list 空 | server 没声明 capabilities.tools | server 端 SDK 补 capabilities 字段 | | 间歇性 401 | token 过期未自动 refresh | 配 OAuth client 的 refresh_token rotation | | 所有 call 都 401 | token audience 错(resource binding 失效) | 重新跑 OAuth 授权流,token 必须与 server URL audience 一致 |

调试步骤

  1. 用 Inspector 直接打 server(绕过 Host):OK → 问题在 Host 拿 token 的环节;不 OK → 问题在 server。
  2. 抓 Host 日志里的 Authorization header,确认 token scope(一般需要 server 端日志辅助)。
  3. 让 server 端在 initialize 时打印收到的 token scopes(debug 模式)。

预防:在 CI 里跑 OAuth 授权 → token 验证 → 真实调用一次 tools/list 三步自动化测试,每次 server SDK 升级都跑一次。

排错清单

当服务器死活加载不出来,或工具不出现时,按以下顺序排查:

  1. JSON 能解析吗? 一个语法错误会让文件里所有服务器失效。
  2. 路径是绝对且正确的吗? 把配置里的完整命令打印出来,在终端里跑一遍。如果在终端都报错,在 Host 里必然也报错。
  3. 依赖装了吗? npx -y <包> 首次运行会下载,需要网络。在内网环境里先把包全局装好。
  4. 环境变量设了吗? 一个需要 GITHUB_PERSONAL_ACCESS_TOKEN 却拿不到的服务器,会启动成功,但在第一次工具调用时失败。检查 token 是否有正确的 scope。
  5. 服务器有没有往 stderr 打印什么? Claude Desktop 在 macOS 上把服务器日志写到 ~/Library/Logs/Claude/mcp-server-<名字>.log;Claude Code 通过 /mcp 面板展示。先读日志再猜。
  6. 是不是版本不匹配? MCP 还在成熟中。如果某个服务器是按较旧的协议版本写的,就在 args 里把版本钉死(例如 @modelcontextprotocol/server-filesystem@0.6.0),等 Host 跟上。

最快的调试循环通常是:在终端里直接跑服务器命令,看它打印启动横幅,然后杀掉,让 Host 来拉起它。如果独立运行没问题但 Host 运行不行,问题在配置或环境,不在服务器。

常见问题

编辑配置文件后需要重启 Claude Desktop 吗?

需要。Claude Desktop 在应用启动时拉起 MCP 服务器,并在整个会话期间保活。编辑 claude_desktop_config.json 在你完整退出并重启应用之前不会生效;关掉窗口不算重启。

claude_desktop_config.json 和 .mcp.json 有什么区别?

claude_desktop_config.json 是 Claude Desktop 的单一全局配置文件,对每个聊天都生效。.mcp.json 是 Claude Code 按项目存在的配置文件,提交到 git 让整个团队拿到同一组服务器。两者都用相同的 mcpServers 结构。

服务器能访问我的整个文件系统吗?

只有你明确允许的才行。文件系统服务器把允许访问的目录作为命令行参数接收,列表之外的东西对模型不可见。把这个允许清单当成安全边界,精确列出你想暴露的根目录。

怎么安全地给服务器传 API token?

把它放在服务器定义的 env 块里。Host 会把这些变量传给被拉起的进程。绝不要把真实 token 提交进共享的配置文件——用占位符、从 gitignore 掉的本地文件加载,或者在部署时从密钥管理器注入。

Claude Code 的 .mcp.json 和用户级 ~/.claude.json 冲突时谁赢?

按层数从高到低:企业托管(MDM)覆盖项目级覆盖用户级。同一 slug 的 server 出现多次时,Host 取优先级最高的版本。如果你想强制用户级覆盖项目级,把项目级的 server 设 disabled: true;但企业托管层无法被任何下层覆盖。

远端 HTTP server 突然 401 with no body 怎么办?

按 4 步排:(1) Inspector 直连 server 看是否 OK——是 → Host 拿 token 的环节有问题;否 → server 端问题。(2) 抓 Host 日志里的 Authorization header,确认 token scope 是否够。(3) 触发 OAuth refresh——token 可能过期。(4) 验证 token audience 是否与 server URL 一致(RFC 8707 强制绑定)。90% 的"昨天能调今天不行"是第 3 或第 4 步——token 自动 rotate 或 client 误换了 audience。

官方参考资料

本文基于截至 2026 年 7 月的公开信息,相关 API 可能演进。