1. MCP 协议到底是什么,为什么说它是智能体的扩展坞
MCP 全称 Model Context Protocol,模型上下文协议,2024 年 11 月由 Anthropic 开源。你可以把它理解成 AI 世界里的 USB-C 接口标准:以前每个大模型要接一个外部工具,就得单独写一套适配代码,接十个工具写十套;有了 MCP 之后,工具方只要实现一个 MCP Server,任何支持 MCP 的客户端都能即插即用。这就是“智能体扩展坞”这个说法的来源——主机(Host)提供插槽,客户端(Client)负责握手,服务器(Server)提供能力。
它解决的核心问题有三个。第一是数据壁垒,大模型的训练数据有截止日期,也拿不到你公司内部的数据库、文件系统、工单系统,MCP 让模型可以按需去查。第二是接口碎片化,Function Calling 各家格式不一样,OpenAI 一套、Anthropic 一套、国内厂商又一套,MCP 把它统一成 tools/resources/prompts 三类原语。第三是复用成本,一个高德地图的 MCP Server 写完之后,Cline 能用、Windsurf 能用、Claude Code 也能用,不需要为每个 IDE 重写。
适合谁来读这篇?如果你正在用 Cline、Windsurf、Claude Code、Cursor 这类 AI 编程工具,想让它们能读你的本地文件、查你的数据库、调你的内部 API,那 MCP 就是当前最省事的路子。如果你只是想聊天问答,那暂时用不上。这篇会从零把服务端配置、客户端连接参数、一次真实的工具调用验证全部走一遍,配置片段可以直接复制。
需要先明确一个概念区分:MCP Server 不是模型,它不产生 token,它只是一个按协议暴露能力的进程。模型决定“我要调用 getWeather 这个工具”,客户端负责把这次调用转发给 Server,Server 执行完把结果返回,模型再基于结果组织语言。整条链路里,模型是大脑,MCP 是神经,Server 是手脚。
2. 接入前的准备:TaoToken 作为模型侧入口的配置
MCP 链路要跑通,前提是客户端本身能正常调用大模型。Cline、Windsurf BYOK 这些工具都要求你填一个兼容 OpenAI 或 Anthropic 格式的 Base URL 和 API Key。我这边统一用 TaoToken 作为模型侧入口,原因是它同时提供 OpenAI 兼容和 Anthropic 兼容两种端点,MCP 客户端里不管选哪种协议都能对上,省得来回换。
先拿 Key。打开 https://taotoken.net/api-keys ,登录后创建一个新的 API Key,复制出来存好,这个 Key 只在创建时完整显示一次。注意不要把它提交到 Git 仓库,建议放在环境变量里。
Base URL 分两种,按你客户端支持的协议选:
| 协议类型 | Base URL | 适用客户端 |
|---|---|---|
| OpenAI 兼容 | https://taotoken.net/api/v1 | Cline、Cursor、多数 BYOK 工具 |
| Anthropic 兼容 | https://taotoken.net/api | Claude Code、部分 Anthropic SDK 场景 |
Model ID 这块,MCP 客户端里通常要你手填一个模型名。常用的有 claude-sonnet-4-5、claude-opus-4-1、gpt-4o 这类,具体以你账号下可用的为准。填错模型名最常见的报错是 404 model not found,不是 Key 的问题,先排查模型名拼写。
如果你用的是 Claude Code,它读的是环境变量,配置方式和其他 GUI 工具不一样,后面第 3 节会单独给一份 settings 片段。如果你用的是 Cline 或 Windsurf,直接在设置面板里填 Base URL、API Key、Model ID 三件套即可。
这里有个容易踩的坑:有些客户端把 OpenAI 兼容端点的路径写成https://taotoken.net/api/v1/chat/completions,你只需要填到/v1为止,后面的路径客户端会自己拼。多填了会导致 404 或者路径重复。同理 Anthropic 兼容端点填到https://taotoken.net/api即可。
准备好这三样之后,先别急着配 MCP Server,先在客户端里发一条普通对话,确认模型侧是通的。模型侧不通的情况下配 MCP,报错会混在一起,很难定位。这一步验证通过,再进入下一节。
3. 可复制的 MCP 服务端与客户端配置片段
这一节给三份配置,覆盖最常见的三种场景:Cline 的 MCP 配置、Claude Code 的 settings、以及一个最小可用的 MCP Server 示例。路径和字段名都按各工具当前的实际格式写,可以直接复制改。
先看 Cline。Cline 的 MCP 配置存在cline_mcp_settings.json里,Windows 一般在%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\下,macOS 在~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/。文件内容长这样:
{ "mcpServers": { "filesystem": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "/Users/yourname/projects" ], "disabled": false, "autoApprove": [] }, "weather-demo": { "command": "node", "args": ["/Users/yourname/mcp-servers/weather/index.js"], "env": { "WEATHER_API_KEY": "your_key_here" }, "disabled": false, "autoApprove": ["getWeather"] } } }command是启动 Server 的可执行文件,args是参数,env是环境变量。autoApprove里列的工具名表示不需要每次弹窗确认,建议只放只读类工具,写操作类保持手动确认。disabled设为 false 表示启用。
再看 Claude Code。它读的是~/.claude/settings.json,模型侧和 MCP 侧可以写在同一个文件里:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-your-taotoken-key", "ANTHROPIC_MODEL": "claude-sonnet-4-5" }, "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/yourname/projects"] } } }注意ANTHROPIC_BASE_URL填的是不带/v1的地址,Claude Code 会自己拼/v1/messages。填成https://taotoken.net/api/v1会变成/api/v1/v1/messages,直接 404。
最后给一个最小 MCP Server 示例,用 Node 写,暴露一个 getWeather 工具。先初始化:
mkdir -p ~/mcp-servers/weather && cd ~/mcp-servers/weather npm init -y npm install @modelcontextprotocol/sdk然后写index.js:
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; const server = new Server( { name: "weather-demo", version: "1.0.0" }, { capabilities: { tools: {} } } ); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [{ name: "getWeather", description: "获取指定城市的实时天气", inputSchema: { type: "object", properties: { city: { type: "string", description: "城市名" } }, required: ["city"] } }] })); server.setRequestHandler(CallToolRequestSchema, async (req) => { const { city } = req.params.arguments; return { content: [{ type: "text", text: `${city} 当前晴,26 摄氏度` }] }; }); const transport = new StdioServerTransport(); await server.connect(transport);在package.json里加一行"type": "module",然后node index.js能跑起来不报错,就说明 Server 侧没问题。这个 Server 走的是 stdio 传输,客户端通过标准输入输出和它通信,不需要开端口。
三份配置里,模型侧的三件套(Base URL、Key、Model ID)在 Cline 和 Claude Code 里都要填全,缺一个就连不上。Cline 在设置面板里填,Claude Code 在 settings.json 的 env 里填。
4. 验证一次工具调用,确认扩展坞链路真的跑通
配置写完不代表链路通了,必须做一次真实的工具调用验证。这一步的目的是把“模型侧通”“MCP 侧通”“模型能正确选择工具”三件事分开确认。
第一步,先确认 MCP Server 被客户端识别到。在 Cline 里打开 MCP 面板,应该能看到 filesystem 和 weather-demo 两个 Server,状态是绿色的 connected。如果显示红色或者一直转圈,说明 Server 进程没起来,去看客户端的 MCP 日志,通常是 command 路径不对或者 npx 没装。
第二步,确认工具列表被拉取到。点开 weather-demo,应该能看到 getWeather 这个工具,参数是 city。如果工具列表是空的,说明 Server 的 ListTools 处理有问题,回到上一节检查setRequestHandler(ListToolsRequestSchema, ...)那段。
第三步,发一条会触发工具调用的消息。在对话框里输入:“帮我查一下杭州现在的天气”。正常流程是:模型先返回一个 tool_use 块,指定调用 getWeather,参数 city=杭州;客户端把这次调用转发给 weather-demo Server;Server 返回“杭州 当前晴,26 摄氏度”;模型拿到结果后组织成自然语言回复你。
如果一切正常,你会看到回复里包含“杭州”“晴”“26 摄氏度”这些来自 Server 的信息。这就证明整条链路跑通了:模型侧(TaoToken)→ 客户端(Cline)→ MCP Server(weather-demo)→ 返回 → 模型侧。
第四步,验证 filesystem 这个官方 Server。输入:“列出 /Users/yourname/projects 下的文件”。模型会调用 filesystem 的 list_directory 工具,返回真实目录内容。这一步验证的是 Server 能访问本地文件系统,也是 MCP 最常用的场景之一。
验证过程中有两个观察点值得留意。一是工具调用的往返延迟,stdio 传输基本在毫秒级,如果你感觉卡了好几秒,多半是模型侧在排队,不是 MCP 的问题。二是 autoApprove 的效果,getWeather 在 autoApprove 列表里,应该不弹确认框直接执行;filesystem 的写操作没在列表里,会弹确认。这个行为符合预期就说明权限控制生效了。
跑通之后,你可以把 weather-demo 换成任何真实工具:查数据库的、调内部 API 的、读工单系统的。MCP 的价值就在这里,Server 换掉,客户端和模型侧配置一行不用改。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一节按真实遇到的报错来排,每个都给定位思路。
401 Unauthorized。两种可能:一是 TaoToken 的 API Key 填错或过期,去 https://taotoken.net/api-keys 重新生成一个换上;二是 Key 填对了但 Base URL 协议不匹配,比如客户端走 OpenAI 格式却填了 Anthropic 端点。检查方法:看报错里返回的 body,如果提示invalid api key就是 Key 问题,如果提示not found多半是路径问题。
local proxy failed / connection refused。这个报错通常出现在客户端试图连一个本地端口的 MCP Server 时。如果你用的是 stdio 传输的 Server,不应该出现这个错;出现说明配置里写成了 SSE 或 HTTP 传输但 Server 没监听对应端口。检查mcpServers里是不是误加了url字段。stdio 的 Server 只有command和args,没有url。
Error reading choices / choices field missing。这是模型侧返回格式不对,客户端解析失败。常见原因是 Base URL 填成了 Anthropic 端点但客户端按 OpenAI 格式解析,或者反过来。Cline 这类工具默认走 OpenAI 兼容格式,Base URL 应该填https://taotoken.net/api/v1。如果你填了https://taotoken.net/api,返回的是 Anthropic 格式,客户端找不到choices字段就报这个错。
OAuth / authentication failed。有些 MCP Server(尤其是云服务官方提供的)要求 OAuth 授权,第一次连接会弹浏览器让你登录。如果弹不出来或者回调失败,检查客户端版本是否支持 OAuth 流程,以及本地是否有防火墙拦了回调端口。这类 Server 的配置里通常有auth相关字段,按官方文档填。
工具列表为空但 Server 显示 connected。说明进程起来了但 ListTools 没返回。去 Server 日志里看有没有异常,常见的是 SDK 版本不匹配,@modelcontextprotocol/sdk升级到最新再试。
模型不调用工具,直接编答案。这不是报错但很常见。原因是工具的 description 写得太模糊,模型判断不需要调用。把 description 写具体,比如“获取指定城市的实时天气,返回温度和天气状况”,模型选择工具的概率会明显提高。
排查顺序建议固定:先看客户端 MCP 日志,再看 Server 自己的 stdout/stderr,最后看模型侧返回。三层分开看,比混在一起猜快得多。
6. 把 MCP 用起来的几个实际建议
MCP Server 不要一上来就写复杂的。先从官方提供的 filesystem、fetch、sqlite 这几个现成的跑通,确认客户端环境没问题,再写自己的。自己写的时候,一个 Server 只做一类事,工具数量控制在 5 个以内,description 写清楚,模型选择准确率会高很多。
传输方式优先选 stdio。SSE 和 HTTP 适合远程 Server,但会引入网络和鉴权问题,本地开发阶段没必要。stdio 的 Server 随客户端启动,随客户端退出,生命周期清晰。
权限控制别偷懒。autoApprove 只放只读工具,写操作、删除操作、发消息这类一定要手动确认。MCP 的权限模型是客户端控制的,Server 本身不拦,所以确认框是最后一道防线。
模型侧和 MCP 侧分开验证。模型侧用一条普通对话确认,MCP 侧用工具列表确认,最后再合起来测工具调用。这样任何一环出问题都能快速定位,不会出现“不知道是 Key 错了还是 Server 挂了”的情况。
如果你在团队里推广 MCP,建议把常用的 Server 配置做成模板,新人复制改路径就能用。配置里的路径、Key 用环境变量占位,别硬编码。这样一份配置能在多个人的机器上跑,也方便进版本管理。
MCP 生态现在更新很快,官方 Server 列表和 SDK 都在迭代。遇到问题时先看客户端的 MCP 日志和 Server 的 stderr,大部分问题在这两处都有明确提示。把这两处看明白,比搜报错信息快。