ARTICLE DETAIL

资讯详情

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

从零打造你的第一个MCP Server:用TaoToken统一Key跑通模型上下文协议

从零打造你的第一个MCP Server:用TaoToken统一Key跑通模型上下文协议 1. 为什么你的第一个 MCP Server 值得认真写MCP Server 这个词最近出现频率很高但很多人第一次接触时容易把它想复杂。说白了模型上下文协议Model Context Protocol简称 MCP就是给大模型装了一套标准插座以前你想让模型查天气、读文件、调数据库得为每个工具单独写一套接口模型换个平台就得重写一遍现在只要按 MCP 的格式把工具注册好任何支持 MCP 的客户端都能直接调用。MCP Server 就是这套插座背后的服务端负责暴露工具、接收请求、返回结果。这篇文章面向第一次接触 MCP 的开发者目标很明确从零写出一个最小可运行的 MCP Server本地启动注册一个工具然后用一次完整调用链路验证它真的通了。同时我会把模型请求统一走 TaoToken 的 Key 通道这样你后面换模型、加工具时不用到处改配置。适合谁看会一点 Python、装过 pip、能看懂 JSON 的人就够了不需要你之前碰过 MCP。我试过把整个流程拆成六步先讲清楚问题和场景再准备 TaoToken 的统一 Key然后给出可复制的 server 配置接着用 curl 和日志双重验证再列一遍新手最容易踩的报错最后把入口整理给你。跟着做半小时内你能看到自己的 MCP Server 返回第一条真实响应。2. TaoToken 统一 Key 准备与 MCP 环境依赖清单在写代码之前先把两件事准备好一个是模型调用的统一入口一个是本地依赖。很多人卡在第一步不是因为不会写 MCP而是 Key 散落在各个平台调试时根本分不清请求到底走了哪条通道。用 TaoToken 的好处是 Base URL 和 Key 固定模型 ID 按需切换MCP Server 里只认这一套配置。先拿 Key。打开 https://taotoken.net/api-keys 登录后创建一个 API Key复制下来存到环境变量里别硬编码进代码。我习惯这样写export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意 Base URL 是https://taotoken.net/api不带任何多余路径。模型 ID 你可以先在 https://taotoken.net/models 看一眼当前可用的列表选一个你熟悉的比如gpt-4o-mini或claude-3-5-sonnet这类通用对话模型MCP 工具调用对模型的要求主要是支持 function calling。依赖清单很轻Python 3.10 以上即可pip install mcp[cli] httpxmcp[cli]是官方 SDK自带命令行调试工具httpx用来在工具内部发 HTTP 请求。如果你打算用 Node.js 写换成npm install modelcontextprotocol/sdk也行但本文以 Python 为主线因为它的 SDK 对新手最友好报错信息也直白。目录结构建议这样my_mcp_server/ ├── server.py ├── tools/ │ └── weather_tool.json └── .env.env里放 Keytools/weather_tool.json放工具描述符server.py是主逻辑。这样拆的好处是工具描述和实现分离后面加第二个、第三个工具时不用动主文件。有一点要提醒MCP Server 本身不负责模型推理它只负责暴露工具。模型调用工具的那一步是由 MCP Client比如 Claude Desktop、Cline、或者你自己写的客户端发起的。所以你的 Server 里不需要写任何大模型相关的代码只需要把工具注册好、把请求转发到 TaoToken 的统一通道即可。这个边界搞清楚后面调试会省很多事。3. 可复制的 MCP Server 配置与工具注册代码现在进入核心部分。先写工具描述符tools/weather_tool.json{ name: get_weather, description: 查询指定城市的当前天气, parameters: { type: object, properties: { city: { type: string, description: 城市名称例如 北京 } }, required: [city] } }这个文件的作用是告诉客户端「我有哪些工具、每个工具要什么参数」。MCP 的标准化就体现在这里不管你的工具背后是查数据库还是调第三方 API描述格式都一样。接着写server.py。官方 SDK 的写法比早期版本简洁很多用FastMCP装饰器注册工具import os import httpx from mcp.server.fastmcp import FastMCP mcp FastMCP(weather-server) TAOTOKEN_BASE_URL os.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api) TAOTOKEN_API_KEY os.getenv(TAOTOKEN_API_KEY) mcp.tool() async def get_weather(city: str) - dict: 查询指定城市的当前天气 # 这里用统一通道做一次模型侧确认实际项目可替换为真实天气 API async with httpx.AsyncClient(timeout30) as client: resp await client.post( f{TAOTOKEN_BASE_URL}/v1/chat/completions, headers{ Authorization: fBearer {TAOTOKEN_API_KEY}, Content-Type: application/json, }, json{ model: gpt-4o-mini, messages: [ {role: user, content: f用一句话描述{city}今天的天气不要解释} ], }, ) resp.raise_for_status() data resp.json() summary data[choices][0][message][content] return {city: city, summary: summary, source: taotoken} if __name__ __main__: mcp.run(transportstdio)几个关键点。第一mcp.tool()装饰器会自动读取函数的类型注解和 docstring生成工具描述所以你不需要手动再写一遍 JSON——上面那个weather_tool.json是给不支持自动发现的客户端用的备份。第二transportstdio表示用标准输入输出通信这是本地开发最省事的方式客户端启动这个进程后直接通过管道对话。第三模型调用走的是{TAOTOKEN_BASE_URL}/v1/chat/completions这是 OpenAI 兼容格式TaoToken 的通道直接支持。如果你更习惯用配置文件而不是环境变量可以写一个settings.toml[taotoken] base_url https://taotoken.net/api api_key sk-你的key default_model gpt-4o-mini [mcp] transport stdio name weather-server然后在server.py里用tomllib读进来。这样团队协作时配置一目了然也不会因为某个人忘了 export 环境变量而报 401。启动命令python server.py如果一切正常进程会安静地挂在那里等待输入不会有花哨的输出。这是 stdio 模式的正常表现别以为它卡死了。想确认它活着用官方自带的调试器mcp dev server.py这会打开一个本地调试界面能看到已注册的工具列表和调用日志。第一次跑通时看到get_weather出现在工具列表里基本就成功一半了。4. 用 curl 与日志双重验证 MCP 调用链路Server 起来了怎么确认它真的能工作我习惯用双重验证一次 curl 直接打模型通道确认 Key 和 Base URL 没问题一次通过 MCP 客户端调用工具确认整条链路通。先验证 TaoToken 通道本身curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 回复两个字通了}] }正常返回类似{ choices: [ { message: { role: assistant, content: 通了 } } ] }如果这一步就报 401说明 Key 有问题报连接错误说明 Base URL 写错了。先把这一步跑通再往下走。接着验证 MCP 工具调用。用mcp dev server.py打开调试界面在工具列表里点get_weather参数填{city: 北京}执行。你会看到返回{ city: 北京, summary: 北京今天晴气温约 25 摄氏度适合外出。, source: taotoken }同时在终端日志里能看到类似这样的记录INFO Received request: tools/call get_weather INFO POST https://taotoken.net/api/v1/chat/completions 200 INFO Response sent: 1 result这两条日志很关键第一条证明 MCP 协议层收到了调用请求第二条证明请求确实走了 TaoToken 的统一通道并成功返回。如果只有第一条没有第二条说明工具内部逻辑出错如果两条都没有说明客户端根本没连上 Server。想更贴近真实场景可以写一个最小 MCP Client 来调import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): params StdioServerParameters(commandpython, args[server.py]) async with stdio_client(params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() print(可用工具:, [t.name for t in tools.tools]) result await session.call_tool(get_weather, {city: 上海}) print(调用结果:, result.content) asyncio.run(main())跑通后输出里会同时出现工具列表和天气结果。到这一步你的第一个 MCP Server 就算真正跑通了本地启动、工具注册、完整调用链路三件事都验证过了。5. 新手必踩的 MCP 报错与排查对照表这一节是我踩过的坑合集。MCP 刚上手时报错信息往往不直观下面按真实报错对照排查。401 Unauthorized。最常见九成是 Key 没读到。检查echo $TAOTOKEN_API_KEY有没有输出或者.env有没有被正确加载。注意 stdio 模式下 Server 是子进程父进程的环境变量不一定继承稳妥做法是在server.py开头显式load_dotenv()。local proxy failed / connection refused。这个报错通常出现在客户端连不上 Server 时。stdio 模式下检查command和args路径对不对比如python是不是虚拟环境里的那个。如果你用的是 SSE 或 WebSocket 传输检查端口有没有被占用lsof -i :8000看一眼。reading choices 报错 / KeyError: choices。说明请求发出去了但返回结构不对。大概率是 Base URL 写成了https://taotoken.net/api/v1又在代码里拼了一次/v1变成/v1/v1/chat/completions。统一用https://taotoken.net/api作为 Base URL路径里只写一次/v1。OAuth 相关报错。如果你用的是 Claude Code 或某些需要 OAuth 的客户端报 OAuth 失败时先确认客户端版本再检查是不是把 API Key 和 OAuth 混用了。MCP Server 本身不处理 OAuth它只认请求里的工具调用。工具列表为空。list_tools返回空数组通常是装饰器没生效。检查mcp.tool()有没有漏写括号或者函数是不是 async。另外 docstring 不能为空SDK 靠它生成描述。调用超时。工具内部请求 TaoToken 时没设 timeout默认可能很长。显式加timeout30并在客户端侧也设一个合理的超时。对照表报错最可能原因处理401Key 未加载检查环境变量或 .envlocal proxy failed进程路径/端口错核对 command 与端口reading choicesBase URL 重复拼接统一用 /apiOAuth 失败客户端认证方式混用区分 Key 与 OAuth工具列表空装饰器或 docstring 问题补括号、补描述排查时记住一个原则先确认通道curl 打 TaoToken再确认协议mcp dev 看工具最后确认业务工具内部逻辑。分层定位比盲目改代码快得多。6. 把 MCP Server 接入你的日常开发流跑通最小示例只是起点。真正让 MCP Server 有价值是把它接进你每天用的工具里。如果你用 Cline 或 Claude Code 这类支持 MCP 的编辑器配置方式基本一致核心三件套是 Base URL、Key、Model ID{ mcpServers: { weather: { command: python, args: [/绝对路径/my_mcp_server/server.py], env: { TAOTOKEN_API_KEY: sk-你的key, TAOTOKEN_BASE_URL: https://taotoken.net/api } } } }这段配置放到客户端的 MCP 设置里重启后就能在对话中直接让模型调用get_weather。注意args用绝对路径相对路径在不同工作目录下会失效。如果你打算长期做编码类 Agent把多个工具注册到同一个 Server 里统一走 TaoToken 通道模型切换时只改一个 Model ID 就行。需要看当前可用模型和额度去 https://taotoken.net/models 要管理多个 Key 或做团队隔离去 https://taotoken.net/console 。接入文档在 https://taotoken.net/doc 里面有各语言 SDK 的完整示例。调试阶段遇到通道问题优先回 https://taotoken.net/api-keys 确认 Key 状态想快速验证某个模型能不能正常对话用 https://taotoken.net/chat 直接试一句比在代码里反复改快得多。长期跑编码任务的话Coding Plan 在 https://taotoken.net/coding-plan 有更省心的额度方案。最后给一个实用建议把工具描述写清楚。模型能不能选对工具八成取决于 description 写得够不够具体。get_weather写成「查询指定城市的当前天气」就比「获取天气」强很多。工具多了以后描述质量直接决定调用准确率。你的第一个 MCP Server 不用追求功能多把一个工具打磨到模型每次都能正确调用比堆十个半成品有用。
返回列表