资讯动态

MCP Server开发实战:用LLM建智能工具生态的完整指南(TaoToken统一Key接入篇)

发布时间:2026/9/27 12:39:18 来源:尧图企业网站定制
1. 为什么我要自己写一个 MCP ServerMCP Server 是 Model Context Protocol 服务端的简称它做的事情说白了就是给大模型装上一双手模型不再只会聊天而是能通过标准协议去调用你写的工具函数比如查数据库、读文件、调内部接口。适合谁适合手里已经有一堆零散脚本、想让 LLM 自动编排这些脚本的开发者也适合想把公司内部系统安全暴露给 AI 助手的团队。我最早接触 MCP 是因为一个很具体的痛点团队里有个查询订单状态的小工具每次都要人工复制订单号到脚本里跑一遍再把结果贴回对话框。后来想干脆让模型自己调但直接给模型开 HTTP 接口又担心权限失控。MCP 的 Host / Client / Server 三层结构正好解决这个问题——Server 只暴露声明过的工具Client 负责协议转换Host 决定什么时候发起调用边界清晰。这篇会从零搭一个能跑的 MCP Server重点放在模型调用环节怎么用 TaoToken 的统一 Key 打通避免你在多个模型供应商之间来回切配置。全程给可复制的 config.toml 和 settings.json 骨架最后附连通性验证和几个我踩过的报错。2. 前置准备TaoToken 统一 Key 与 MCP 运行环境2.1 为什么模型调用层要单独抽出来MCP Server 本身只负责工具执行但工具执行完往往需要模型做二次加工比如把查询结果总结成自然语言。如果每个工具都硬编码一个模型 SDK后面换模型就是灾难。我的做法是把模型调用统一收敛到一个 OpenAI 兼容的入口MCP Server 内部只认 base_url 和 api_key 两个变量。TaoToken 在这里的角色就是那个统一入口它提供 OpenAI 兼容的 API 通道base_url 填https://taotoken.net/apiKey 在控制台生成。这样我的 MCP Server 代码里不需要出现任何具体模型厂商的名字换模型只改一个字符串。2.2 环境与依赖Python 3.10 以上我实测 3.11 最稳。核心依赖三个mcp官方 SDK、fastapi做 HTTP 层、httpx做异步请求。装的时候注意 mcp 的版本0.4 和 0.5 的 API 有差异下面代码基于 0.5。python -m venv venv source venv/bin/activate pip install mcp0.5 fastapi uvicorn httpx pydanticKey 的获取路径登录后进控制台在 API Keys 页面新建一个复制出来存到环境变量别写进代码。export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意Key 只显示一次丢了就重新生成。生产环境建议用密钥管理服务注入不要留在 shell history 里。3. 可复制配置config.toml 与 settings.json 骨架3.1 config.tomlMCP Server 自身配置这个文件放在项目根目录描述 Server 名称、传输方式、以及模型调用参数。传输方式我选 stdio本地开发最省事不用管端口。[server] name order-mcp version 0.1.0 transport stdio [model] provider openai-compatible base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY default_model claude-sonnet-4 timeout 60 max_retries 2 [tools] enabled [get_order_status, summarize_order]api_key_env这个设计很关键配置文件里永远不出现明文 Key只写环境变量名代码运行时去读。3.2 settings.json客户端侧接入配置如果你用 Cline 或 Claude Code 这类支持 MCP 的客户端它们读的是 settings.json。下面这份是 Cline 的骨架Claude Code 的字段名略有不同但结构一致。{ mcpServers: { order-mcp: { command: python, args: [-m, order_mcp.server], env: { TAOTOKEN_API_KEY: ${env:TAOTOKEN_API_KEY}, TAOTOKEN_BASE_URL: https://taotoken.net/api }, disabled: false, autoApprove: [get_order_status] } } }autoApprove里放只读工具写操作类工具不要放进去否则模型可能在你没确认的情况下改数据。3.3 CC Switch 接入配置CC Switch 用来在多个 MCP Server 之间切换它的配置是一个数组每个元素指向一份 settings.json。我通常按项目分一个项目一份。{ profiles: [ { name: order-dev, settingsPath: ./config/settings.dev.json }, { name: order-prod, settingsPath: ./config/settings.prod.json } ], active: order-dev }切换时只改active字段不用动其他文件。这个设计在同时维护测试和生产两套工具时特别省心。4. 写一个能跑的 MCP Server订单查询工具4.1 工具定义与注册MCP 的工具注册靠装饰器参数用 Pydantic 模型声明SDK 会自动生成 JSON Schema 给模型看。下面这个get_order_status是只读工具返回结构化数据。from mcp.server import Server from mcp.server.stdio import stdio_server from pydantic import BaseModel, Field app Server(order-mcp) class OrderQuery(BaseModel): order_id: str Field(description订单号格式 ORD-开头) detail: bool Field(defaultFalse, description是否返回明细) app.tool() async def get_order_status(query: OrderQuery) - dict: 查询订单当前状态返回状态码和更新时间 # 实际项目替换为数据库查询 mock { order_id: query.order_id, status: shipped, updated_at: 2025-01-15T10:30:00Z, } if query.detail: mock[items] [{sku: A100, qty: 2}] return mockField里的 description 不是写给人看的是写给模型看的。模型靠这段文字判断什么时候该调这个工具、参数怎么填。我试过把 description 写得很含糊结果模型经常传错 order_id 格式补上格式说明后就准了。4.2 接入 TaoToken 做结果总结工具返回的是 JSON但用户想听人话。这里加一个summarize_order工具内部调 TaoToken 的 API 把 JSON 转成自然语言。import os import httpx TAOTOKEN_BASE os.environ[TAOTOKEN_BASE_URL] TAOTOKEN_KEY os.environ[TAOTOKEN_API_KEY] async def call_llm(prompt: str, model: str claude-sonnet-4) - str: async with httpx.AsyncClient(timeout60) as client: resp await client.post( f{TAOTOKEN_BASE}/v1/chat/completions, headers{Authorization: fBearer {TAOTOKEN_KEY}}, json{ model: model, messages: [{role: user, content: prompt}], temperature: 0.3, }, ) resp.raise_for_status() return resp.json()[choices][0][message][content] app.tool() async def summarize_order(order_id: str) - str: 把订单 JSON 转成一句人话总结 raw await get_order_status(OrderQuery(order_idorder_id, detailTrue)) prompt f用一句话总结这个订单状态不要加前缀{raw} return await call_llm(prompt)注意 base_url 后面要拼/v1/chat/completions这是 OpenAI 兼容协议的标准路径。TaoToken 的 API 地址是https://taotoken.net/api拼完就是完整的请求地址。4.3 启动入口async def main(): async with stdio_server() as (read, write): await app.run(read, write, app.create_initialization_options()) if __name__ __main__: import asyncio asyncio.run(main())stdio 模式下 Server 通过标准输入输出和 Client 通信所以启动后终端不会有任何输出这是正常的别以为卡死了。5. 验证请求确认工具真的被调起来了5.1 用 MCP Inspector 做连通性验证官方有个 Inspector 工具能直接列出 Server 暴露的工具并手动调用。npx modelcontextprotocol/inspector python -m order_mcp.server打开它给的本地地址左侧应该能看到get_order_status和summarize_order两个工具。点进去填order_id: ORD-123执行右侧返回 JSON 就说明 Server 通了。5.2 验证模型调用链路工具通了不代表模型调用通了。单独测一下 TaoToken 的通道curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4, messages: [{role: user, content: 回复 OK 两个字母}] }返回里有choices[0].message.content且内容是 OK说明 Key 和 base_url 都对。这一步能省掉后面大量排查时间因为 MCP 层报错经常把模型层的错误吞掉。5.3 端到端跑一次在 Cline 里输入「帮我查一下 ORD-123 的状态并总结」正常流程是模型先调get_order_status拿到 JSON再调summarize_order最后把总结返回。你会在工具调用面板看到两次调用记录。如果只看到一次说明模型没理解要串联检查工具 description 是否写清楚了依赖关系。6. 本篇常见报错排查6.1 401 Unauthorized九成是 Key 没读到。先确认echo $TAOTOKEN_API_KEY有值再确认 settings.json 里的${env:...}语法被客户端支持。有些客户端不解析这种占位符得直接写值或者用它的密钥管理功能。另外检查 Authorization 头是不是Bearer加空格少个空格也会 401。6.2 工具列表为空Server 启动了但 Client 看不到工具通常是启动命令的工作目录不对。python -m order_mcp.server要求order_mcp是包目录下得有__init__.py。如果报No module named在 settings.json 的 args 里加-u并确认 cwd 字段指向项目根目录。6.3 模型调用超时默认 timeout 60 秒长文本总结可能不够。在 config.toml 里把 timeout 调到 120同时给 httpx 客户端也设上。另外max_retries设 2 就够设太多遇到持续性错误会拖很久。如果频繁超时先单独用 curl 测模型通道排除是网络还是模型本身慢。6.4 工具参数校验失败模型传的参数类型不对比如把布尔值传成字符串 true。解决办法是在 Pydantic 模型里加model_config {strict: True}让校验更严格同时在 description 里明确写「布尔值不是字符串」。我遇到过模型把 detail 传成 yes加上严格模式后它会自动纠正。6.5 stdio 模式下日志污染stdio 模式下 Server 的 stdout 是协议通道任何 print 都会破坏协议导致 Client 解析失败。所有调试输出必须走 stderrimport sys print(debug info, filesys.stderr)这个坑我踩过现象是 Client 报 JSON 解析错误但 Server 看起来正常运行查了半天才发现是一行 print。7. 把链路跑顺之后工具生态能不能落地关键不在工具写得多花哨而在模型调用这一层稳不稳。把 TaoToken 的统一 Key 接进来之后我的 config.toml 里再也没出现过第二个 base_url换模型只改default_model一个字段。如果你后面要接更多工具建议按功能拆多个 MCP Server用 CC Switch 管理别全塞一个进程里否则一个工具报错会拖垮整条链路。需要生成 Key 的话去控制台新建接入细节看接入文档想先验证模型通道是否通可以直接在模型对话里发一条测试消息。长期做编码类 Agent 的话Coding Plan 的额度模型更适合高频调用场景。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑