
1. 为什么你的 Python Agent 总是接不上外部工具如果你写过 Python Agent大概率经历过这个场景模型能聊天、能推理但一到“帮我查一下库存”“读一下这个配置文件”“调一下内部工单接口”就卡住了。你不得不为每个工具手写一套函数描述、参数 Schema、调用分发逻辑接三个工具还行接十个就开始失控。MCPModel Context Protocol模型上下文协议就是来解决这个问题的。它是一套让 AI 应用以标准协议连接外部工具、资源和提示模板的开放协议底层基于 JSON-RPC 2.0支持本地 STDIO 和远程 Streamable HTTP 两种传输模式。适合谁适合正在做 Agent、Copilot、企业知识库问答、自动化脚本平台的 Python 开发者尤其是那些手里已经有一堆 FastAPI 服务、数据处理脚本、内部 RPC 接口想让 AI 低成本接入的人。我试过把一个库存查询脚本从“手写 Function Calling”改成“MCP Server Client”的结构最直观的感受是工具发现、参数协商、调用返回这三件事被协议层统一了客户端不再需要硬编码每个工具的细节。下面从架构分层讲到 Python 落地每一步都给可复制的配置和验证动作。MCP 的核心价值不是“模型会不会调函数”而是“AI 系统怎么以标准化、可组合、可治理的方式连接外部世界”。它把 HostAI 应用、Client协议客户端、Server能力提供方三个角色拆开让工具能力的暴露和消费解耦。你可以把已有的 Python 服务包装成 MCP Server也可以让你的 Python Agent 作为 MCP Client 去消费别人的工具两边都走同一套协议。2. TaoToken 统一 Key 接入 MCP 的前置准备在动手写 MCP Server 之前先解决一个现实问题你的 Python 应用最终要调用大模型来完成推理和工具选择而模型 API 的 Key 管理、通道切换、额度控制往往比 MCP 本身还烦。TaoToken 在这里的角色是提供一个统一的 API 通道让你用一套 Key 接入多种模型MCP 客户端在需要模型采样时直接走这个通道。你需要准备三样东西Base URL、API Key、Model ID。Base URL 填https://taotoken.net/apiAPI Key 在控制台的 API Keys 页面创建Model ID 根据你实际使用的模型填写。这三件套在后面的 MCP Client 配置和模型调用里都会用到。如果你用的是 Claude Code 这类编码工具配置方式是在 settings 里指定 Base URL 和 Key如果用的是 Cline 或类似的 MCP 客户端需要在 MCP 配置里同时写清楚 Server 启动命令和模型通道信息。Codex 的 auth.json 也是同样的逻辑Base URL、Key、Model ID 三件套缺一不可。对于 MCP 场景TaoToken 的接入点主要在两个地方一是 MCP Client 在 Sampling 阶段需要调用模型时走 TaoToken 的 API二是你的 Python Agent 本身如果要做推理也统一走这个通道。这样你不需要在 MCP Server 里再嵌一套模型调用逻辑Server 只管暴露工具模型调用交给 Client 侧的 Host 处理。实际操作上你可以在环境变量里统一管理export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-your-key-here export TAOTOKEN_MODEL_IDyour-model-id然后在 Python 代码里读取这些变量。这样做的好处是 MCP Server 和 Client 可以共用同一套配置切换模型或 Key 时只改环境变量不用动代码。如果你还没有 Key可以去控制台创建一个接入文档里有详细的参数说明。3. 可复制的 Python MCP Server 与 Client 配置这一节直接给可运行的代码。先装依赖pip install mcp3.1 最小 MCP ServerFastMCP Streamable HTTPfrom mcp.server.fastmcp import FastMCP mcp FastMCP(inventory-service, json_responseTrue) mcp.tool() def get_available_stock(sku_code: str) - dict: 查询指定 SKU 的可售库存 available 128 return { skuCode: sku_code, availableStock: available, status: IN_STOCK if available 0 else OUT_OF_STOCK, } mcp.resource(inventory://policy) def inventory_policy() - str: 返回库存规则说明 return 库存低于 20 时触发补货提醒。 mcp.prompt() def stock_analysis_prompt(sku_code: str) - str: return f请分析 SKU {sku_code} 的库存状态并给出补货建议。 if __name__ __main__: mcp.run(transportstreamable-http)这段代码把三类能力都暴露了mcp.tool()是可执行动作mcp.resource()是可读上下文mcp.prompt()是可复用提示模板。启动后默认监听本地端口你可以通过http://localhost:8000/mcp访问。3.2 MCP Client 连接远程 Serverimport asyncio from mcp import ClientSession from mcp.client.streamable_http import streamable_http_client async def main(): async with streamable_http_client(http://localhost:8000/mcp) as ( read_stream, write_stream, _, ): async with ClientSession(read_stream, write_stream) as session: await session.initialize() tools await session.list_tools() print([tool.name for tool in tools.tools]) result await session.call_tool( get_available_stock, arguments{sku_code: SKU-1001}, ) print(result) asyncio.run(main())3.3 挂载到已有 FastAPI / Starlette 应用如果你已经有 ASGI 应用不需要单独再开一个服务import contextlib from starlette.applications import Starlette from starlette.routing import Mount from mcp.server.fastmcp import FastMCP mcp FastMCP(my-app, json_responseTrue) mcp.tool() def hello() - str: return Hello from MCP! contextlib.asynccontextmanager async def lifespan(app: Starlette): async with mcp.session_manager.run(): yield app Starlette( routes[ Mount(/mcp, appmcp.streamable_http_app()), ], lifespanlifespan, )3.4 MCP 客户端配置片段JSON如果你用的是支持 MCP 的编辑器或客户端配置文件通常长这样{ mcpServers: { inventory-service: { command: python, args: [inventory_mcp_server.py], env: { TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_API_KEY: sk-your-key-here, TAOTOKEN_MODEL_ID: your-model-id } } } }注意这里 Base URL、Key、Model ID 三件套都写全了。如果你的客户端是 Cline 或 Claude Code配置字段名可能略有不同但核心信息一致。4. 验证请求与成功结果配置写完后按这个顺序验证。第一步启动 MCP Serverpython inventory_mcp_server.py看到服务监听日志后第二步用 Client 脚本连接并列出工具python mcp_client.py预期输出类似[get_available_stock] metaNone content[TextContent(typetext, text{skuCode: SKU-1001, availableStock: 128, status: IN_STOCK})] isErrorFalse第三步验证模型通道。在你的 Python Agent 里调用 TaoToken 的 API确认 Base URL 和 Key 生效import os from openai import OpenAI client OpenAI( base_urlos.environ[TAOTOKEN_BASE_URL], api_keyos.environ[TAOTOKEN_API_KEY], ) resp client.chat.completions.create( modelos.environ[TAOTOKEN_MODEL_ID], messages[{role: user, content: 你好}], ) print(resp.choices[0].message.content)如果这一步返回正常文本说明模型通道通了。第四步把 MCP Client 和模型调用串起来Client 先list_tools()拿到工具列表把工具描述注入到模型请求里模型返回工具调用意图后Client 再call_tool()执行。整个链路跑通后你会看到模型能正确选择get_available_stock并传入sku_code参数。实测下来最容易出问题的环节是工具描述和参数 Schema 的清晰度。如果模型总是选错工具或传错参数先检查mcp.tool()的 docstring 和参数类型标注是否足够明确。5. 本篇常见错误排查报错一401 Unauthorized如果你在调用 TaoToken API 时看到 401先检查 API Key 是否正确、是否过期、是否在环境变量里被覆盖。常见原因是.env文件里 Key 带了引号或空格。另外确认 Base URL 是https://taotoken.net/api不要多加路径。报错二local proxy failed / connection refusedMCP Client 连接http://localhost:8000/mcp时报连接拒绝说明 Server 没启动或端口不对。先确认 Server 进程在跑再确认端口没有被占用。如果你在容器里跑注意 localhost 的指向问题。报错三reading choices 相关错误模型返回结构解析失败时常见于choices字段为空或格式不符。检查 Model ID 是否填写正确以及请求体是否符合 OpenAI 兼容格式。如果你用的是非标准模型确认它支持 chat completions 接口。报错四OAuth / 认证流程卡住远程 Streamable HTTP 模式下如果 Server 要求 OAuth而你的 Client 没有配置认证会卡在初始化阶段。本地开发建议先用 STDIO 模式跑通再切到 HTTP 模式补认证。报错五工具列表为空list_tools()返回空列表通常是 Server 端装饰器没生效或启动的模块不对。确认mcp.tool()装饰的函数在mcp.run()之前已经定义且没有语法错误导致模块加载失败。报错六Codex auth.json 配置不生效如果你用 Codex 类工具auth.json 里需要同时写 Base URL、Key、Model ID。只写 Key 不写 Base URL 会导致请求打到默认端点出现认证失败。检查 JSON 格式是否合法字段名是否匹配。6. 从最小闭环到平台化的落地路径把 MCP 接进 Python 项目建议按四个阶段推进。第一阶段做最小闭环选一个查询型工具用 FastMCP 暴露本地用 STDIO 或 Streamable HTTP 跑通list_tools和call_tool。这个阶段的目标是确认协议链路通不追求功能多。第二阶段做 AI 友好的结果结构收敛返回字段给每个参数写清楚描述为常见错误提供结构化错误信息。观察模型是否能稳定选对工具、传对参数。这一步决定了后续扩展的顺畅程度。第三阶段做治理能力加认证、审计日志、限流、超时、敏感工具二次确认。远程 HTTP 模式下特别要注意 Origin 校验和 localhost 绑定不要把服务暴露在0.0.0.0上。第四阶段做平台化统一 MCP 网关、工具目录、多业务域 Server 治理、可观测性。这时候你手里的 MCP Server 已经不是几个脚本而是一套 AI 能力平台。如果你现在已经在用 Python 和 FastAPI完全可以从一个最小查询工具开始把现有业务系统先包装成一个小型 MCP Server。模型通道统一走 TaoToken 的 APIKey 和 Base URL 在环境变量里管理MCP Server 只管暴露能力Client 只管消费能力。这样你的 Python 技术栈就能以最低改造成本接入 AI 生态。需要创建 Key 或查看接入参数的话API Keys 页面和接入文档里有完整说明。如果你更关注长期编码和 Agent 场景可以了解一下 Coding Plan 的通道配置方式。模型对话调试可以直接在模型对话页面验证通道是否正常。