
1. 从一次多 Agent 项目踩坑说起MCP 与 A2A 到底谁管什么如果你最近在折腾 Agent 项目大概率会遇到这样一个场景调度 Agent 需要把「查一下上季度华东区销售数据再让法务 Agent 审一下合同条款」这种任务拆开分给两个不同垂域的 Agent 去干。这时候问题就来了——销售数据 Agent 怎么读数据库法务 Agent 怎么调合同系统两个 Agent 之间又怎么把中间结果传回来我试过最原始的做法每个 Agent 自己写一套 Function Calling 的 JSON Schema自己对接 API。结果就是「查天气」这个能力在调度 Agent 里写一遍在垂域 Agent 里又写一遍参数格式还不太一样。项目跑到第三个 Agent 的时候适配层代码已经比业务逻辑还多了。这就是 MCP 和 A2A 这两套协议要解决的核心痛点。MCPModel Context Protocol管的是「Agent 怎么调用外部工具和数据源」你可以把它理解成大模型的 USB-C 接口标准——任何符合 MCP 的工具 Server都能被任何符合 MCP 的 Client 即插即用。A2AAgent-to-Agent Protocol管的是「Agent 之间怎么发现彼此、委托任务、同步状态」它更像是企业间的 B2B 协作流程。一句话区分MCP 是 Agent 的「手和脚」负责跟工具、数据库、文件系统打交道A2A 是 Agent 之间的「语言和流程」负责调度 Agent 把任务分给垂域 Agent再把结果收回来。两者不是竞争关系而是上下层互补——A2A 负责横向的任务分发MCP 负责纵向的工具对接。这篇文章要交付的东西很具体一套可复制的 endpoint 配置、auth.json 片段、连通性验证命令以及真实项目里踩过的报错排查步骤。适合正在搭多 Agent 系统、或者想让单个 Agent 先具备标准化工具调用能力的开发者。读完你至少能跑通一个「调度 Agent 通过 A2A 委托任务垂域 Agent 通过 MCP 调工具」的最小闭环。在开始配置之前先明确一个前提无论 MCP 还是 A2A底层都要调用大模型来做意图理解和决策。如果每个 Agent 都去单独申请一套 Key、维护一套计费工程上会很乱。所以下面我会用 TaoToken 的统一 API 通道来承载这些模型调用让 MCP Server 和 A2A Agent 共用同一个 Base URL 和 Key。2. TaoToken 统一接入前置一个 Key 打通 MCP Server 与 A2A Agent在真实项目里MCP Server 和 A2A Agent 对模型调用的需求是不一样的。MCP Server 里的工具调用往往需要模型做参数组装和结果总结A2A 的调度 Agent 需要模型做任务分解和路由决策垂域 Agent 需要模型在浓缩后的 Context 里做领域推理。如果每个环节都配一套独立的模型凭证密钥管理、额度监控、故障排查都会变成噩梦。TaoToken 在这里扮演的角色是「统一模型调用通道」。它提供兼容 OpenAI 规范的 API 接口你只需要一个 Base URL 和一个 API Key就能让 MCP Client、A2A Agent、以及各种 IDE 插件共用同一套凭证。这对多 Agent 项目特别重要——当调度 Agent 和垂域 Agent 都指向同一个 endpoint 时你排查问题时只需要看一个日志入口。先拿到凭证。访问控制台创建 API Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建完成后你会得到形如sk-xxxxxxxx的 Key。接下来所有配置都围绕两个核心值展开配置项值说明Base URLhttps://taotoken.net/api兼容 OpenAI 规范不加 UTMAPI Keysk-你的密钥控制台创建注意保密Model IDclaude-sonnet-4-5或gpt-4o等按项目需求选这里要强调一个容易踩的坑Base URL 是https://taotoken.net/api不要在后面多加/v1或者/chat/completions具体路径由 SDK 自己拼接。很多 401 和 404 报错都是因为 Base URL 写多了后缀。对于长期跑编码类 Agent 的场景可以考虑 Coding Plan它更适合高频、长时间的 Agent 调用https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite如果你只是想先验证模型能不能通用模型对话页面直接测最快https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite接入文档在这里遇到路径问题优先查它https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite现在你有了统一的 Base URL 和 Key接下来进入具体配置环节。我会分两条线走先配 MCP Server 的模型调用再配 A2A Agent 的模型调用最后让它们通过同一套凭证协同工作。3. 可复制配置MCP Server 与 A2A Agent 的 endpoint 与 auth.json 片段这一节是全文最核心的部分所有片段都可以直接复制到你的项目里。我会按「MCP Server 侧」和「A2A Agent 侧」分别给出配置并说明每个字段的作用。3.1 MCP Server 的模型调用配置MCP Server 本身是工具提供方但它内部的工具实现比如「总结数据库查询结果」往往需要调用大模型。以 Python SDK 为例你可以在 Server 初始化时注入统一的模型客户端# mcp_server_config.py import os from openai import OpenAI # 统一使用 TaoToken 通道 client OpenAI( base_urlhttps://taotoken.net/api, api_keyos.environ.get(TAOTOKEN_API_KEY, sk-你的密钥) ) MODEL_ID claude-sonnet-4-5 def summarize_result(raw_text: str) - str: resp client.chat.completions.create( modelMODEL_ID, messages[ {role: system, content: 你是数据总结助手输出简洁结论。}, {role: user, content: raw_text} ], temperature0.2 ) return resp.choices[0].message.content如果你用的是 Claude Code 这类工具它的配置走的是settings.json。在项目根目录创建.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的密钥, ANTHROPIC_MODEL: claude-sonnet-4-5 } }注意这里的三件套必须齐全Base URL、Key、Model ID。少任何一个都会导致连接失败。Claude Code 的接入文档在https://taotoken.net/claude-code?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-codeutm_campaignrewrite3.2 A2A Agent 的 auth.json 配置A2A 协议里Agent 之间通过 Agent Card 发现彼此能力。但 Agent 内部调用模型时同样需要凭证。以 Codex 风格的auth.json为例{ base_url: https://taotoken.net/api, api_key: sk-你的密钥, model: claude-sonnet-4-5, provider: openai-compatible }把这个文件放在 Agent 项目的配置目录下比如~/.config/a2a-agent/auth.json。然后在 Agent 启动代码里读取import json from pathlib import Path def load_auth(): auth_path Path.home() / .config / a2a-agent / auth.json with open(auth_path, r, encodingutf-8) as f: return json.load(f) auth load_auth() # 传给模型客户端 client OpenAI(base_urlauth[base_url], api_keyauth[api_key])3.3 MCP Client 注册 Server 的配置MCP Client比如 Claude Desktop 或 Cursor需要知道有哪些 Server 可用。以claude_desktop_config.json为例{ mcpServers: { weather: { command: python, args: [/absolute/path/to/weather_server.py], env: { TAOTOKEN_API_KEY: sk-你的密钥 } }, remote-data: { url: https://your-api.com/mcp/sse, headers: { X-API-Key: sk-你的密钥 } } } }这里有两个细节本地 stdio Server 通过env传 Key远程 SSE Server 通过headers传 Key。两种方式都指向同一个 TaoToken 凭证。3.4 A2A Agent Card 配置A2A 的核心是 Agent Card它描述了一个 Agent 的能力和 endpoint。一个最小化的 Agent Card 长这样{ name: finance-audit-agent, description: 财务审计垂域 Agent负责账表核对与合规检查, url: https://your-domain.com/a2a/finance, version: 1.0.0, capabilities: { streaming: true, pushNotifications: false }, skills: [ { id: audit-ledger, name: 账表审计, description: 读取账表数据并执行合规规则检查 } ], authentication: { schemes: [bearer] } }调度 Agent 通过读取这个 Card 来发现财务 Agent 的能力然后通过url发起 A2A 任务委托。而财务 Agent 内部调用模型时用的还是上面auth.json里的统一凭证。配置到这里MCP 和 A2A 两条线的凭证就统一了。接下来验证连通性。4. 验证请求从 tools/list 到 A2A 任务委托的成功结果配置写完不代表能跑通。这一节给出具体的验证命令和预期输出你可以照着一步步确认。4.1 验证模型通道是否通先用最简单的 curl 确认 TaoToken 通道可用curl -X POST https://taotoken.net/api/chat/completions \ -H Authorization: Bearer sk-你的密钥 \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 回复 OK 两个字母}], max_tokens: 10 }预期返回类似{ id: chatcmpl-xxx, choices: [ { message: { role: assistant, content: OK } } ] }如果这一步就报 401说明 Key 有问题报 404说明 Base URL 写错了。先解决这个再往下走。4.2 验证 MCP Server 的 tools/listMCP 协议基于 JSON-RPC 2.0。你可以手动发一条tools/list请求来验证 Server 是否正常暴露工具。对于 stdio Server用管道输入echo {jsonrpc:2.0,id:1,method:tools/list,params:{}} | python weather_server.py预期输出{ jsonrpc: 2.0, id: 1, result: { tools: [ { name: get_weather, description: 获取指定城市的当前天气, inputSchema: { type: object, properties: { city: {type: string} }, required: [city] } } ] } }看到tools数组里有你的工具说明 Server 的list_toolshandler 正常。4.3 验证 tools/call 调用继续发一条调用请求echo {jsonrpc:2.0,id:2,method:tools/call,params:{name:get_weather,arguments:{city:Beijing}}} | python weather_server.py预期返回{ jsonrpc: 2.0, id: 2, result: { content: [ {type: text, text: 北京今天晴25°C} ] } }如果这里返回的是isError: true说明你的 handler 内部逻辑抛异常了去看 Server 的 stderr 输出。4.4 验证 A2A 任务委托A2A 的任务委托通常通过 HTTP POST 到 Agent Card 里的url。一个最小验证请求curl -X POST https://your-domain.com/a2a/finance \ -H Authorization: Bearer sk-你的密钥 \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: task-001, method: tasks/send, params: { task: { type: audit-ledger, input: {period: 2026-Q1, region: east-china} } } }预期返回一个 task 对象包含id、status和可能的artifacts{ jsonrpc: 2.0, id: task-001, result: { id: task-abc, status: {state: completed}, artifacts: [ {type: text, text: 华东区 Q1 账表核对完成发现 2 处异常。} ] } }到这里MCP 的工具调用和 A2A 的任务委托都验证通过了。接下来是排错环节——真实项目里最容易卡住的地方。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节按报错信息来组织每条都给出原因和修复方法。这些是我在实际项目里真实遇到过的。5.1 401 Unauthorized最常见。原因通常有三个第一Key 没传对。检查Authorizationheader 是不是Bearer sk-xxx格式注意Bearer和 Key 之间有一个空格。MCP 的 SSE 配置里如果用的是X-API-Key那 header 名要和 Server 端校验逻辑一致。第二Key 被环境变量覆盖了。比如你在settings.json里写了 Key但系统环境变量里有一个旧的ANTHROPIC_AUTH_TOKEN优先级更高。用echo $ANTHROPIC_AUTH_TOKEN确认一下。第三Base URL 和 Key 不匹配。比如 Key 是 TaoToken 的但 Base URL 指向了别的服务。确认base_url是https://taotoken.net/api。5.2 local proxy failed这个报错通常出现在 Claude Code 或 Cursor 这类工具里意思是本地代理层连接失败。原因往往是第一ANTHROPIC_BASE_URL写成了https://taotoken.net/api/v1多了一层路径。改成https://taotoken.net/api。第二本地网络有额外的代理设置干扰。检查HTTP_PROXY/HTTPS_PROXY环境变量如果有临时 unset 掉再试。第三工具版本太旧不支持自定义 Base URL。升级到最新版。5.3 reading choices 报错这个报错一般长这样Error reading choices: ...或cannot read property choices of undefined。说明模型返回的 JSON 结构不符合预期。原因通常是模型 ID 写错了。比如你写了claude-sonnet-4但实际可用的 ID 是claude-sonnet-4-5。去接入文档确认当前支持的 Model ID 列表https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite另一个可能是请求体里messages格式不对比如 role 写成了assistant但 content 是数组。确保格式符合 OpenAI 规范。5.4 OAuth 相关报错如果你用的是 Claude Code 的 OAuth 登录流程可能会遇到OAuth token expired或invalid_grant。这时候不要反复重试直接改用 API Key 方式{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的密钥, ANTHROPIC_MODEL: claude-sonnet-4-5 } }API Key 方式比 OAuth 更稳定适合长期运行的 Agent 项目。Claude Code 的完整接入步骤在https://taotoken.net/claude-code?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-codeutm_campaignrewrite5.5 MCP Server 启动后 Client 看不到工具配置写对了但 Client 里就是没有工具列表。检查顺序第一Server 进程是否真的启动了。手动跑python weather_server.py看有没有报错。第二tools/list是否返回了非空数组。用 4.2 节的命令验证。第三Client 配置里的路径是不是绝对路径。相对路径在 Client 启动时的工作目录可能不对。第四改完配置后 Client 有没有重启。Claude Desktop 需要完全退出再打开不是关窗口。5.6 A2A 任务委托超时调度 Agent 发任务给垂域 Agent一直 pending。检查第一Agent Card 里的url是否可达。用 curl 直接打一下。第二垂域 Agent 的模型调用是否卡住了。看它的日志确认auth.json里的 Key 有效。第三任务是否太大导致模型推理超时。把任务拆小或者调大超时时间。排错的核心思路是先确认模型通道通4.1再确认 MCP 工具通4.2/4.3最后确认 A2A 委托通4.4。逐层排查不要跳步。6. 把统一通道用起来从单 Agent 到多 Agent 的演进路径配置和排错都跑通之后最后聊聊工程上的演进节奏。很多团队一上来就想搭完整的 A2A 多 Agent 架构结果卡在基础设施上。更务实的路径是分三步走。第一步先让单个 Agent 具备标准化的 MCP 工具调用能力。用第 3 节的配置把 MCP Server 跑起来用第 4 节的方法验证tools/list和tools/call。这一步的目标是「一个 Agent 能稳定调工具」不涉及 Agent 间通信。第二步把领域知识外置化。不要急着微调模型而是用文档 RAG MCP 资源来承载领域知识。比如财务 Agent 的审计规则写成SKILL.md通过 MCP 的resources/list暴露给 Agent。这样新增垂域能力时只需要加文档和 Server不用动调度逻辑。第三步当单一 Agent 的 Context 和职责过于复杂时再引入 A2A。这时候你已经有了多个能独立工作的 Agent只需要用 A2A 的 Agent Card 让它们互相发现用tasks/send做任务委托。调度 Agent 的职责变轻了只负责路由和结果汇总。整个过程中TaoToken 的统一 Key 和 API 通道是贯穿始终的基础设施。无论你有 1 个 Agent 还是 10 个 Agent无论它们用 MCP 调工具还是用 A2A 互相通信模型调用的 Base URL 和凭证都是同一套。这带来的好处在排错时特别明显——所有 Agent 的模型调用日志都指向同一个入口出问题时不用在多个凭证之间来回切换。如果你还在单 Agent 阶段建议先把 MCP 这条线跑通用模型对话页面快速验证通道https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite如果你已经在跑多 Agent 项目需要更稳定的高频调用额度看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite所有接入细节和最新 Model ID 列表以接入文档为准https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite最后给一个实操建议在项目里建一个config/目录把auth.json、settings.json、claude_desktop_config.json都放进去用环境变量注入 Key不要硬编码。这样换环境时只改环境变量配置文件不用动。多 Agent 项目的配置管理越早规范越省事。