1. 三种协议到底在解决什么问题
MCP、Function Calling、A2A 这三个词经常被混着用,但它们在真实 AI 工具里负责的环节完全不同。你可以先把它们想成一条流水线上的三个工位:Function Calling 是模型决定"要不要动手、动哪只手";MCP 是把手伸出去时,工具怎么被标准化地发现和调用;A2A 则是当一件事一只手干不完,多个 Agent 之间怎么派活和汇报。
我见过太多人把 MCP 当成"模型直连工具",结果配置完发现模型根本没反应。原因很简单:MCP 本身不和 LLM 直接交互,它是一套给上下文工程服务的协议,真正让模型"知道有工具可用"的是写进 prompt 里的工具描述,也就是 Function Calling 的触发条件。而 A2A 更靠后,它管的是 Agent 与 Agent 之间的任务发现、分配和状态回传。
这篇会以 TaoToken 的统一 Key 和 API 通道作为接入点,在 Cline 和 CC Switch 里分别把三条链路配出来,对比请求结构,并给出可复制的settings.json与config.toml骨架。适合已经在用 Cline、Claude Code 这类工具,但被三种协议绕晕的开发者。读完你能明确:什么场景该用哪条链路,配置写在哪,报错怎么查。
2. TaoToken 前置:统一 Key 与接入点
TaoToken 在这里的角色是"统一入口"。三条链路最终都要发 HTTP 请求,如果每条链路各配一套 Key 和 Base URL,排障时会分不清是协议问题还是鉴权问题。用同一个 Key 走同一个 API 通道,变量就少了一个。
你需要先拿到 Key。登录后进入控制台,在 API Keys 页面创建一个新 Key,复制保存。注意 Key 只在创建时完整显示一次,关掉页面就看不到了。
- 控制台入口:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
- API Keys 页面:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
API 基础地址统一用https://taotoken.net/api,这个地址不加 UTM 参数,直接写进配置文件即可。三条链路都指向它,区别只在请求体结构和工具描述的组织方式。
注意:Key 不要写进会提交到 Git 的文件里。Cline 的配置建议放在用户级目录,CC Switch 的配置放在本地配置目录,避免误提交。
3. 可复制配置:Cline 与 CC Switch 骨架
3.1 Cline 的 settings.json 骨架
Cline 是 VS Code 插件,它的模型配置和 MCP Server 配置是分开的。模型侧走 Function Calling,MCP 侧走工具注册。下面这份settings.json放在 Cline 的用户配置目录,把模型指向 TaoToken 通道。
{ "cline.apiProvider": "openai", "cline.openAiBaseUrl": "https://taotoken.net/api", "cline.openAiApiKey": "sk-你的TaoTokenKey", "cline.openAiModelId": "claude-sonnet-4-20250514", "cline.mcpServers": { "weather": { "command": "uv", "args": ["run", "mcp_weather_server.py"], "env": { "UV_INDEX_URL": "https://repo.huaweicloud.com/repository/pypi/simple/" } } } }这里cline.openAiBaseUrl指向 TaoToken,模型侧就会以 OpenAI 兼容格式发起 Function Calling 请求。cline.mcpServers里的weather是 MCP Server 的注册项,Cline 启动时会拉起这个进程,通过 stdio 做 JSON-RPC 握手。
3.2 CC Switch 的 config.toml 骨架
CC Switch 用来在多个 Claude Code 配置间切换。它的config.toml里可以声明多个 profile,每个 profile 指向不同的 Base URL 和 Key。把 TaoToken 作为一个 profile 写进去。
[[profiles]] name = "taotoken" base_url = "https://taotoken.net/api" api_key = "sk-你的TaoTokenKey" model = "claude-sonnet-4-20250514" [[profiles.mcp_servers]] name = "weather" command = "uv" args = ["run", "mcp_weather_server.py"]CC Switch 切换 profile 后,Claude Code 的请求就会走 TaoToken 通道。MCP Server 的声明方式和 Cline 类似,都是命令加参数的形式,区别在于 CC Switch 用 TOML 数组表来表达。
3.3 三条链路的请求结构对比
配置写完后,真正要理解的是请求长什么样。下面这张表把三条链路的核心字段列出来。
| 链路 | 触发方 | 核心字段 | 请求目标 |
|---|---|---|---|
| Function Calling | 模型 | tools、tool_choice | TaoToken 的 chat completions |
| MCP | Agent 运行时 | method、params、jsonrpc | 本地 MCP Server 进程 |
| A2A | Agent 客户端 | tasks/send、agent.json | 远端 A2A Server |
Function Calling 的请求体里,tools数组描述可用工具,模型返回tool_calls字段表示它想调哪个。MCP 的请求是 JSON-RPC,method为tools/call时带上工具名和参数。A2A 则是先拉/.well-known/agent.json拿到 Agent Card,再发tasks/send。
4. 验证请求与成功结果
4.1 验证 Function Calling 链路
先用 curl 直接打 TaoToken 的 chat completions,确认模型能返回tool_calls。这一步不经过 Cline,排除插件层干扰。
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的TaoTokenKey" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "杭州明天天气如何"}], "tools": [{ "type": "function", "function": { "name": "get_forecast", "description": "获取天气信息", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"] } } }] }'成功时返回体里会出现finish_reason: "tool_calls",并且message.tool_calls数组里有get_forecast和参数{"city": "杭州"}。如果返回的是普通文本,说明模型没识别到工具,检查tools字段格式和模型是否支持。
4.2 验证 MCP 链路
MCP 的验证看日志。在 Cline 里配置好 MCP Server 后,工具列表里get_forecast显示为绿色,说明握手成功。此时在任务窗口输入"杭州明天天气如何",Cline 会先发tools/list拿工具清单,再发tools/call。
日志里能看到三段:初始化阶段交换initialize和initialized,工具注册阶段发tools/list,调用阶段发tools/call。如果tools/list返回空数组,说明 MCP Server 没正确注册工具,检查@mcp.tool装饰器是否写对。
4.3 验证 A2A 链路
A2A 的验证分两步。先拉 Agent Card:
curl http://localhost:8000/.well-known/agent.json返回体里应有name、skills、endpoint字段。再发任务:
curl -X POST http://localhost:8000/tasks/send \ -H "Content-Type: application/json" \ -d '{"task": {"id": "t1", "message": {"role": "user", "parts": [{"type": "text", "text": "查杭州天气"}]}}}'成功时返回status: "submitted"或"working",后续通过 SSE 或 webhook 拿最终结果。如果返回 404,检查 Agent Card 路径是否在/.well-known/下。
5. 本篇常见错排查
5.1 MCP Server 启动失败
最常见的是uv run找不到命令。检查UV_INDEX_URL是否设置,以及uv是否在 PATH 里。另一个坑是 MCP Server 的mcp.run(transport='stdio')写成了其他 transport,Cline 只认 stdio。
5.2 Function Calling 不触发
模型返回纯文本而不是tool_calls,通常是tools字段的 JSON 结构不对。parameters必须是合法的 JSON Schema,required数组不能漏。另外确认模型本身支持 Function Calling,部分小模型不支持。
5.3 A2A 任务卡在 submitted
任务状态一直是submitted,说明 A2A Server 没推进任务。检查 Server 端是否实现了tasks/send的处理逻辑,以及 SSE 通道是否正常推送。如果用了 webhook,确认回调地址可达。
5.4 TaoToken 鉴权失败
返回 401 时,先确认 Key 有没有多余空格,再确认Authorization头格式是Bearer sk-xxx。如果 Key 刚创建,等几秒再试,避免缓存问题。
5.5 Cline 工具列表为空
MCP Server 进程起来了但工具列表为空,检查@mcp.tool装饰器的参数名和函数签名是否匹配。Cline 通过tools/list拿工具,如果 Server 返回空数组,Cline 就不会显示任何工具。
6. 三条链路的边界与接入选择
把三条链路跑通后,边界就清楚了。Function Calling 是模型侧的能力,决定"调不调";MCP 是工具侧的协议,决定"怎么调";A2A 是 Agent 间的协议,决定"谁来调"。三者不是替代关系,而是互补。
如果你在写单 Agent 工具调用,重点配 Function Calling 加 MCP。如果你在做多 Agent 协作,再引入 A2A。TaoToken 在这里的价值是让三条链路共用一套 Key 和 Base URL,排障时只需关注协议层,不用在鉴权上反复折腾。
需要长期跑编码任务或 Agent 的,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
想直接验证模型对话效果的,用模型对话入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite
接入和排障过程中遇到问题,先翻接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
我自己的习惯是:每加一条链路,先用 curl 打一遍原始请求,确认协议层通了,再往 Cline 或 CC Switch 里塞配置。这样出问题时能快速定位是协议层还是工具层。