ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

开发MCP Server的Agent:用TaoToken统一Key把任意API自动转成stdio模式MCP Server

开发MCP Server的Agent:用TaoToken统一Key把任意API自动转成stdio模式MCP Server 1. 为什么要把 HTTP API 塞进 stdio 模式的 MCP Server你可能已经遇到过这种局面手里有一堆内部 HTTP API文档写得七零八落但 Claude、Cline 这类客户端只认 MCP 协议。想让模型直接调你的接口就得把每个 API 包一层 MCP Server。而 stdio 模式是本地开发最省事的一种——客户端启动一个子进程通过标准输入输出收发 JSON-RPC不需要开端口、不需要处理跨域进程活着连接就在。问题在于手工写一个 MCP Server 不难难的是「任意 API 自动转」。一个 API 对应一个 tool 函数参数映射、请求方法分支、异常兜底、返回体裁剪这些如果每个接口都手写一遍十个接口就是十份重复代码。更麻烦的是 Key 管理每个 Server 各自读环境变量配置散落在不同文件里换一次 Key 要改一圈。我试过用 Agent 来做这件事把 API 定义喂给一个带 system prompt 的 Agent让它输出 stdio 模式的 MCP Server 代码和对应的 config.toml / settings.json 骨架再用 TaoToken 的统一 Key 注入到所有 Server 的 env 里。这样新增一个 API只需要补一段定义Agent 产出代码配置里换一个 Key 引用就行。下面把整条链路拆开讲包括 Agent 配置、API 到 stdio 的映射模板、以及用 Cline 加载验证的具体动作。2. TaoToken 前置统一 Key 与接入信息在动手写 Agent 之前先把 Key 这一层理清楚。TaoToken 在这里扮演的角色是「统一入口」你不需要为每个 MCP Server 单独申请一套凭证而是拿一个 Key通过它的 API 端点去访问背后的模型能力。对于 Agent 生成代码、以及后续 Server 内部需要调用模型做参数补全的场景这个 Key 就是唯一需要注入的东西。你需要准备两样东西一个可用的 API Key在控制台的 API Keys 页面创建地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档用来确认请求格式和模型名地址是 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteAPI 的基础地址是 https://taotoken.net/api 注意这个地址不带任何查询参数直接作为 base_url 使用。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 需要看套餐或控制台时从那里进。注意Key 只放在环境变量或本地配置里不要写进 Agent 生成的代码模板中。生成的 Server 代码应该读os.environ.get(TAOTOKEN_API_KEY)而不是硬编码字符串。如果你打算长期跑编码类 Agent比如让 Cline 持续生成和修改 MCP Server可以看一下 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 它更适合高频调用的场景。单纯验证模型连通性的话用模型对话页面就够了https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite3. 可复制配置Agent 骨架与 API 转 stdio 映射模板3.1 Agent 的 system prompt 骨架Agent 的核心是一段 system prompt它决定了输出代码的结构。下面这份可以直接复制我把它拆成了「角色」「输入约定」「输出约定」三块避免模型自由发挥导致代码跑不起来。你是一名资深 Python 开发工程师熟悉 MCP 协议与 FastMCP SDK擅长 stdio 模式 MCP Server 开发。 输入一段 API 定义包含 uri、method、headers、params、返回体结构。 输出两部分先输出完整的 Python MCP Server 代码再输出对应的客户端配置 JSON。 硬性要求 1. 一个 API 对应一个 mcp.tool() 函数函数名用动词加名词全小写下划线。 2. 请求方法只处理 GET 和 POSTGET 用 paramsPOST 用 json。 3. 所有网络请求包在 try/except 里异常返回字符串而不是抛出。 4. 返回体如果超过 4000 字符截断并追加 ...[truncated]。 5. 启动必须是 mcp.run(transportstdio)。 6. 代码中读取 TAOTOKEN_API_KEY 环境变量不硬编码。 7. 配置 JSON 里 env 段注入 TAOTOKEN_API_KEY 的占位引用。这段 prompt 的关键在于第 6、7 条它把 Key 的注入点固定下来后面无论生成多少个 Server配置结构都是一致的。3.2 API 转 stdio 的映射模板Agent 拿到 API 定义后按下面的模板做映射。你可以把这个模板也塞进 prompt 里作为 few-shot模型输出的稳定性会明显提升。import os import requests from mcp.server.fastmcp import FastMCP MCP_SERVER_NAME mcp-{api_group}-server mcp FastMCP(MCP_SERVER_NAME) BASE_URL os.environ.get(API_BASE_URL, http://example.com) API_KEY os.environ.get(TAOTOKEN_API_KEY, ) mcp.tool() async def {tool_name}(param: dict) - str: {api_description} try: uri f{BASE_URL}{api_path} headers {Content-Type: application/json} if API_KEY: headers[Authorization] fBearer {API_KEY} if {method} GET: resp requests.get(uri, paramsparam, headersheaders, timeout30) else: resp requests.post(uri, jsonparam, headersheaders, timeout30) text resp.text if len(text) 4000: text text[:4000] ...[truncated] return text except Exception as e: return ftool error: {e} if __name__ __main__: mcp.run(transportstdio)这个模板里{api_group}、{tool_name}、{api_path}、{method}、{api_description}是 Agent 需要替换的槽位。注意BASE_URL和TAOTOKEN_API_KEY都从环境变量读这样同一份代码可以在不同环境跑不用改文件。3.3 config.toml 与 settings.json 骨架不同客户端读的配置文件不一样。Cline 走的是 MCP settings JSONClaude Desktop 走的是 config.toml 或 claude_desktop_config.json。下面两份骨架都保留env段把 Key 的注入位置统一。config.toml[mcp_servers.mcp_order_server] command uv args [run, --project, /path/to/project, python, /path/to/mcp_order_server.py] env { TAOTOKEN_API_KEY ${TAOTOKEN_API_KEY}, API_BASE_URL http://example.com, PYTHONUNBUFFERED 1 }settings.json{ mcpServers: { mcp_order_server: { command: uv, args: [ run, --project, /path/to/project, python, /path/to/mcp_order_server.py ], env: { TAOTOKEN_API_KEY: ${TAOTOKEN_API_KEY}, API_BASE_URL: http://example.com, PYTHONUNBUFFERED: 1 } } } }${TAOTOKEN_API_KEY}这种写法是否被解析取决于客户端。Cline 支持在 settings 里引用系统环境变量Claude Desktop 则更倾向于直接写值。稳妥做法是本地开发时把 Key 写进系统环境变量配置里用引用如果客户端不解析就退一步在 env 里写实际值但别把这份配置提交到仓库。4. 验证请求用 Cline 加载并确认工具调用成功配置写完之后必须验证 Server 真的能被拉起、tool 真的能被调用。下面用 Cline 走一遍。第一步确认环境变量已经导出。在终端里执行export TAOTOKEN_API_KEY你的Key echo $TAOTOKEN_API_KEY第二步把上面的 settings.json 内容合并进 Cline 的 MCP 配置文件。Cline 的 MCP 配置入口在设置里的 MCP Servers 面板可以直接编辑 JSON。保存后 Cline 会尝试启动这个 Server。第三步观察启动日志。如果 Server 正常拉起Cline 的 MCP 面板里会显示绿色状态并列出这个 Server 暴露的 tool 名称。如果显示红色点开日志看 stderr通常是路径不对或者依赖没装。第四步实际调用一次。在 Cline 的对话里输入类似「调用 mcp_order_server 的 get_order_status参数 order_id 传 12345」观察它是否发起 tool call 并返回结果。成功的话你会看到返回的 JSON 文本被贴回对话。第五步单独验证 Server 进程。绕过客户端直接手动跑一次确认 stdio 通信没问题echo {jsonrpc:2.0,id:1,method:tools/list,params:{}} | uv run --project /path/to/project python /path/to/mcp_order_server.py正常会返回一个包含 tool 列表的 JSON。这一步能过说明 Server 本身没问题剩下的就是客户端配置的事。5. 本篇常见错排查5.1 Server 启动即退出日志里没有 tool 列表最常见的原因是mcp.run(transportstdio)被写成了mcp.run()或者 transport 拼错。stdio 模式下Server 必须显式声明 transport否则默认行为可能不是标准输入输出。检查生成代码的最后一行。另一个原因是uv run的--project路径指向了一个没有 pyproject.toml 的目录。uv 会报错退出但错误信息在 stderr 里客户端面板不一定展示全。手动跑一次命令就能看到。5.2 tool 调用返回 tool error: ...先看错误内容。如果是连接超时检查API_BASE_URL是否可达以及目标 API 是否需要走内网。如果是 401检查TAOTOKEN_API_KEY有没有正确注入到 env。可以在 tool 函数里临时加一行print(os.environ.get(TAOTOKEN_API_KEY, MISSING))但注意 stdio 模式下 stdout 被 JSON-RPC 占用print 会污染协议调试完要删掉或者改用 stderr。5.3 参数传不进去tool 收到的 param 是空 dict这通常是客户端调用时参数结构不对。MCP 的 tool 参数是按 JSON Schema 传的如果你的函数签名是param: dict客户端需要传{param: {...}}而不是直接传{...}。更稳的做法是把参数拆成具名参数比如order_id: str这样 Schema 更明确模型也不容易传错。5.4 多个 Server 共用 Key 时互相覆盖如果你在 settings.json 里给每个 Server 都写了TAOTOKEN_API_KEY的实际值改 Key 时要改多处。正确做法是配置里统一用${TAOTOKEN_API_KEY}实际值只维护在系统环境变量里。如果客户端不支持引用就写一个启动脚本在脚本里 export 后再拉起客户端。5.5 返回体太大导致对话被截断有些 API 返回几万字符的 JSON直接塞回对话会撑爆上下文。模板里的 4000 字符截断只是兜底更好的做法是在 tool 函数里做字段裁剪只返回模型真正需要的字段。这一步可以让 Agent 根据 API 的返回结构自动生成裁剪逻辑在 prompt 里加一条「返回体只保留 data 字段下的关键字段」。6. 把 Key 和配置固定下来后续只补 API 定义整条链路跑通之后新增一个 API 的成本就降到了「补一段定义、让 Agent 生成、把配置块粘进 settings.json」三步。Key 始终是同一个通过环境变量注入不用碰生成的代码。如果你要验证模型本身是否连通用模型对话页面发一条消息即可https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite需要新建或轮换 Key 时去 API Keys 页面操作https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入格式有疑问就翻文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite长期跑编码 Agent 的话Coding Plan 比按次调用更划算https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite最后留一个实用技巧把 Agent 生成的每个 Server 代码和对应配置块按 API 分组存进一个目录目录里放一个 README 记录这个 Server 暴露了哪些 tool、参数是什么。下次模型调用失败时先翻这个 README 对参数比翻代码快得多。
返回列表