简介
Claude Code的本质是"大模型+工具调用循环+有限上下文窗口",而工具调用循环(agent loop)的能力上限,就是工具集的上限——内置工具止步于本地文件、shell与通用的网页抓取,接不进数据库、Issue系统、浏览器自动化这类真实工程里天天要碰的外部系统。《5.Hooks》中的Hooks(钩子)把循环内部的固定点管住了,但它管的是流程节点,扩展不了工具集的能力边界;那一章Hook类型里留下的mcp_tool伏笔,本章回收:它引用的正是MCP工具。
给循环补上外部系统这块能力,逐个写脚本、手工导数据都不可持续,需要的是一个标准协议:外部系统按协议把能力暴露出来,Claude Code按协议接入,两边各实现一次。这就是MCP。本章完整展开MCP在交互式使用下的形态:协议提供什么能力、如何添加与管理服务器、认证、权限与命名、性能与安全,最后是排障经验。
- 官方文档:https://code.claude.com/docs/en/mcp
- 快速开始:https://code.claude.com/docs/en/mcp-quickstart
- 协议规范:https://modelcontextprotocol.io/
MCP是什么
MCP(Model Context Protocol,模型上下文协议)是一个开源标准协议。外部系统实现一个MCP服务器,把自己的能力以标准形式暴露出来;Claude Code作为MCP客户端接入这台服务器,循环里就多了一批可调用的能力。数据库、Jira、GitHub、浏览器,接法完全一致。
一台MCP服务器可以暴露三类能力,它们在Claude Code中各有对应的入口:
| 能力 | 是什么 | 在Claude Code中的入口 |
|---|---|---|
| Tools(工具) | 供Claude调用的可执行函数,如查询数据、调用API | 进入工具调用循环,与内置工具一样被自动选用,规范名为mcp__<server>__<tool> |
| Resources(资源) | 可按需读取的数据实体,如一条Issue、一个文件 | 会话中用@server:scheme://id引用,如@github:issue://123 |
| Prompts(提示) | 服务器预置的提示模板 | 成为斜杠命令/mcp__server__name,如/mcp__github__list_prs |
三类能力里,Tools覆盖绝大多数场景;Resources适合把一份外部数据精确拉进上下文;Prompts则把服务器作者写好的任务模板变成一条斜杠命令(提示名与服务器名中的空格会转换为下划线)。
添加与管理服务器
CLI命令
MCP服务器用claude mcp命令族管理:
| 命令 | 说明 |
|---|---|
claude mcp add |
添加服务器;远程形式为claude mcp add <name> <url>,本地stdio形式把启动命令放在--之后 |
claude mcp list |
列出所有已配置服务器及连接状态 |
claude mcp get <name> |
查看单台服务器的详细配置与错误详情 |
claude mcp remove <name> |
删除服务器,可用--scope指定从哪个范围删 |
claude mcp add-json <name> '<json>' |
用一段JSON直接配置服务器 |
claude mcp add-from-claude-desktop |
从Claude Desktop导入已配置的服务器 |
claude mcp login <name> / claude mcp logout <name> |
OAuth登录与清除凭证,见下文认证一节 |
claude mcp serve |
把Claude Code自身作为一台MCP服务器启动,供其他MCP客户端调用 |
claude mcp reset-project-choices |
重置项目级服务器的批准状态 |
claude mcp add的常用参数:
| 参数 | 说明 |
|---|---|
--transport {http\|sse\|stdio\|ws} |
传输方式,默认stdio,远程推荐http |
--scope {local\|project\|user} |
配置存储范围,默认local |
--header "Key: Value" |
附加请求头,常用于传Bearer token |
--env KEY=value |
传递给服务器的环境变量 |
--client-id、--client-secret、--callback-port <PORT> |
预配置OAuth凭证,见下文认证一节 |
传输方式
| 传输 | 用途 | 特点 | 认证方式 |
|---|---|---|---|
| HTTP | 远程托管服务(推荐) | 标准请求响应,可靠性高 | OAuth、Bearer token、headersHelper |
| SSE | 远程托管(已废弃) | Server-Sent Events单向推送,仅为兼容旧配置保留 | 静态header |
| stdio | 本地进程 | 以子进程方式启动本地程序,可访问本地文件与数据库socket | 环境变量、本地权限 |
| WebSocket | 持久连接、事件推送 | 双向通信,不支持OAuth | 静态header、headersHelper |
选型准则一句话:本地进程选stdio,远程一律HTTP;SSE只在迁移旧配置时会遇到,WebSocket留给需要持久双向连接的场景。另外,stdio服务器的进程环境里会注入CLAUDE_PROJECT_DIR(项目根目录),本地服务器可据此定位项目文件。
配置范围
同一台服务器登记在哪个范围,决定了它对谁生效、存在哪个文件里:
| 范围 | 存储位置 | 生效范围 | 进版本库 |
|---|---|---|---|
| local | ~/.claude.json中当前项目的条目 |
仅当前项目、当前用户 | 否 |
| project | 项目根目录的.mcp.json |
克隆该仓库的所有人 | 是 |
| user | ~/.claude.json顶层的mcpServers |
当前用户的所有项目 | 否 |
| plugin | 插件内打包的.mcp.json |
插件启用时自动加载,见《9.Plugins》 | 随插件分发 |
| claude.ai | 云端(claude.ai的connectors配置页) | 登录该账户的Claude Code | 否(云端) |
同名服务器同时存在于多个范围时,按local>project>user>plugin>claude.ai取高优先级的那个。不想加载claude.ai连接器时,可在settings.json中设disableClaudeAiConnectors: true,或以环境变量ENABLE_CLAUDEAI_MCP_SERVERS=false启动。
.mcp.json
claude mcp add --scope project写入的就是项目根目录的.mcp.json,也可以直接手写。示例代码:
1 | { |
主要字段:
| 字段 | 适用传输 | 说明 |
|---|---|---|
type |
全部 | http、sse、stdio、ws之一 |
url |
HTTP/SSE/WS | 服务器端点 |
headers |
HTTP/SSE/WS | 静态请求头 |
headersHelper |
HTTP/WS | 指向一个脚本,运行时用其输出作为请求头,见下文认证一节 |
oauth |
HTTP | 预配置OAuth:clientId、callbackPort、scopes、authServerMetadataUrl |
command、args、env |
stdio | 本地进程的启动命令、参数与环境变量 |
timeout |
全部 | 超时,毫秒 |
alwaysLoad |
全部 | 跳过工具延迟加载,见下文性能一节 |
配置值支持环境变量展开:${VAR}在运行时替换为环境变量值,${VAR:-default}在变量未设置时使用默认值;展开在command、args、url、headers、env字段中都生效。这是把.mcp.json安全提交进仓库的关键——文件里只留${GITHUB_TOKEN}这样的引用,真实凭证在每个人自己的环境变量里。
会话内管理
会话内运行/mcp打开交互面板,可以查看各服务器的连接状态与工具数量、发起认证、手动重连或切断连接。
注意:.mcp.json在会话启动时一次性读取,改动配置后必须重启会话才生效。
认证
远程服务器的标准认证是OAuth,流程是:
- 添加服务器,如
claude mcp add --transport http <name> <url>; - 会话内运行
/mcp,选中该服务器,执行Authenticate; - 浏览器完成登录后,token由Claude Code保存并自动刷新。
不进会话也可以直接在命令行认证:claude mcp login <name>;在SSH或没有图形界面的机器上加--no-browser,会改为给出URL让我们在别处完成登录。claude mcp logout <name>清除已存储的凭证。
有些服务器不支持OAuth动态注册,需要预先配置凭证。示例代码:
1 | claude mcp add --transport http \ |
注意:--client-secret不直接跟值,命令会提示输入,避免密钥留在shell历史里。
不走OAuth的自定义认证(如公司SSO换token),用headersHelper字段指向一个脚本,由脚本动态生成请求头,见下文示例一节。
token刷新失败时,交互会话里会收到通知,指引回/mcp面板重新认证;非交互运行(-p或Agent SDK)时没有人可提示,Claude会被告知相应工具不可用,并指名需要重新认证的服务器。
权限与命名
每台服务器的每个工具,在Claude Code里都有一个规范名,模式为mcp__<server_name>__<tool_name>,例如GitHub服务器的create_issue工具就是mcp__github__create_issue。服务器名与工具名中不属于A-Z、a-z、0-9、_、-的字符会被替换为_。
这个命名空间可以直接用在权限规则里:写完整工具名精确控制单个工具,写mcp__<server>__*通配整台服务器。示例代码:
1 | { |
权限规则的通用语法、六种模式与deny>ask>allow的优先级见《1.概述》,本节只是MCP命名空间下的增量。
另外,项目级.mcp.json来自仓库、可能由别人提交,所以其中的服务器首次使用前需要我们显式批准;批准状态可用claude mcp reset-project-choices整体重置。
性能与安全
性能
- 工具延迟加载(默认启用)
启动时只加载服务器名与说明,具体的工具定义在需要时才查询。这使得配置大量服务器也不会把上下文成本抬高。加载策略由环境变量ENABLE_TOOL_SEARCH控制,取值true、false、auto、auto:N。 alwaysLoad
对少数关键服务器,在配置中设"alwaysLoad": true,其工具定义始终加载,跳过按需查询。- 输出上限
MCP工具单次返回超过10000 tokens会触发警告,上限可用环境变量MAX_MCP_OUTPUT_TOKENS调整(如MAX_MCP_OUTPUT_TOKENS=50000)。服务器作者可在工具元数据_meta["anthropic/maxResultSizeChars"]中声明支持更大的结果,硬上限500000字符。 - 远程超时
HTTP服务器的首字节等待预算至少60秒;空闲5分钟无响应会自动中止,可用环境变量CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT(毫秒)调整。stdio本地进程不受这两条限制。
安全
第一是信任问题。MCP服务器有权访问Claude会话中的全部内容与工具结果,接入一台服务器等于把会话敞开给它,只连接我们信任的服务器(Anthropic Directory中的服务器经过审查)。
第二是凭证安全。OAuth token由Claude Code自动刷新,存储在系统密钥链(macOS)或凭证文件(Windows/Linux)中,不落入项目目录;而静态Bearer token一旦明文写进.mcp.json,就会随仓库提交而泄露。敏感值按上文的${VAR}约定引用环境变量,或改用headersHelper动态获取,不要硬编码。
还要警惕提示注入风险。MCP服务器返回的内容会进入Claude的上下文,恶意服务器可以在返回数据里夹带指令(如"忽略之前的所有指令")。权限系统与上下文隔离是主要防线,但根本办法仍是只用可信来源的服务器。
示例
三个示例来自同一个场景:一个Web项目团队,要让Claude Code接入GitHub、项目数据库和公司内部API。
第一步,接GitHub,HTTP传输加Bearer token。示例代码:
1 | claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \ |
默认写入local范围,只对当前项目、当前用户生效。添加后三类能力全部就位:让Claude"把刚才的报错整理成issue提交"走的是工具调用;@github:issue://123把一条issue精确拉进上下文;/mcp__github__list_prs直接执行服务器预置的提示。
第二步,接项目数据库,用项目范围让全组共享。示例代码:
1 | claude mcp add --scope project \ |
--scope project把配置写进项目根目录的.mcp.json,提交后同事克隆仓库即用;--之后是stdio服务器的启动命令,单引号防止shell提前展开,让${DB_URL:-...}字面量原样写进.mcp.json,运行时再按上文的环境变量展开规则取值:设置了DB_URL环境变量的人连自己的库,没设的用默认的本地连接串,真实凭证始终不进仓库。给Claude的数据库账号建议用只读账号,把风险从"会不会误操作"降为"最多读到什么"。
第三步,接公司内部API。它走SSO而非标准OAuth,手写.mcp.json配headersHelper。示例代码:
1 | { |
headersHelper指向的脚本在标准输出打印一个JSON对象作为附加请求头(如{"X-Token": "..."}),token的获取与刷新逻辑都在脚本里,配置文件中不出现任何凭证;timeout按内网延迟收紧到30秒;alwaysLoad让这台高频服务器的工具始终加载。改完重启会话,claude mcp list确认三台服务器都在线。
经验
排障优先看这张表:
| 症状 | 原因 | 处理 |
|---|---|---|
| 提示"No MCP servers configured" | local范围的服务器绑在别的项目上 | 用--scope user重新添加,或回到原项目根目录运行claude |
| “Failed to connect"或"Connection error” | HTTP端点404/502,或stdio命令不存在 | 远程用curl -I <url>检查端点;本地在终端直接运行该命令看报错 |
| “Needs authentication” | 服务器返回401/403,或必须OAuth | /mcp面板选中服务器执行Authenticate,或claude mcp login <name> |
| 启动超时 | stdio服务器首次下载依赖太慢 | 以MCP_TIMEOUT=60000 claude(毫秒)延长启动等待 |
| 工具输出过大的警告 | 单次返回超过10000 tokens | 调大MAX_MCP_OUTPUT_TOKENS;同时让查询自带收敛条件(如LIMIT) |
.mcp.json改动不生效 |
配置在会话启动时一次性读取 | 重启会话 |
| 项目服务器显示"Pending approval" | 新的项目级配置未经批准 | 交互运行claude完成确认;需要重新决定时用claude mcp reset-project-choices |
MCP相关的环境变量集中如下:
| 环境变量 | 作用 |
|---|---|
MCP_TIMEOUT |
服务器启动超时(毫秒) |
MAX_MCP_OUTPUT_TOKENS |
工具输出token上限 |
ENABLE_TOOL_SEARCH |
工具延迟加载策略(true/false/auto/auto:N) |
CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT |
远程工具空闲超时(毫秒) |
ENABLE_CLAUDEAI_MCP_SERVERS |
设为false时不加载claude.ai连接器 |
范围的选择有个简单次序:个人通用工具放user,团队共享放project,单项目试验用默认的local;排障时先用claude mcp get <name>确认服务器到底登记在哪一层,再谈连接问题。
除本章的交互形态外,MCP还有两处延伸:Agent SDK可以在进程内直接定义MCP服务器、不需要独立进程,见《8.SDK》;MCP服务器也可以随插件打包分发、随插件启用自动加载,见《9.Plugins》。
至此,工具调用循环的能力边界补齐了:数据库、Issue系统、浏览器都能以标准方式接进来。但这一切仍发生在有人守着的终端里——答权限提示、读输出、发下一轮指令。把人从循环里移出去,让Claude Code以Headless模式(非交互模式)在脚本与CI/CD中无人值守地运行(那里的MCP配置改由--mcp-config参数传入),是下一章《7.Headless》的主题。