ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

【保姆级】MCP 协议实战:从 0 到 1 构建你的第一个 MCP Server,附完整代码与 TaoToken 接入

【保姆级】MCP 协议实战:从 0 到 1 构建你的第一个 MCP Server,附完整代码与 TaoToken 接入 1. 为什么我要自己写一个 MCP ServerMCPModel Context Protocol模型上下文协议是 Anthropic 开源的一套标准用来让大模型以统一方式调用外部工具和数据源。它能做什么简单说你写一次 ServerClaude Desktop、Cursor、Continue 这些支持 MCP 的客户端都能直接调用不用为每家模型单独适配 Function Calling 格式。适合谁适合手里有内部 API、数据库、脚本想让 AI 直接调用的 Python 开发者以及想把 Claude Desktop 变成自己工具台的用户。我第一次动手写 MCP Server 时踩了不少坑官方文档偏协议规范缺少阶梯式教程JSON-RPC 和 stdio 通信对没接触过的人一头雾水市面上的现成 Server 又满足不了业务定制。折腾了两个下午才跑通第一个 Hello World。这篇文章就把这条路重新铺一遍从项目结构、依赖清单、启动命令到把 Claude Desktop 的 MCP 配置改到 TaoToken 统一 Key/API 通道最后用一次工具调用验证连通性。MCP 的核心价值在于解耦。以前让模型调工具要么用 OpenAI 的 Function Calling、Anthropic 的 Tool Use各写一套要么被 LangChain 这类框架绑死。MCP 把「工具怎么被发现、怎么被描述、怎么被调用」抽成协议层Server 只写一次任何支持 MCP 的 Client 都能用。它基于 JSON-RPC 2.0传输层支持 stdio本地子进程和 HTTPSSE远程服务三大原语是 Tool、Resource、Prompt。本文聚焦最常用的 Tool带你从零构建一个能查天气、能做四则运算的 Server。2. TaoToken 前置准备统一 Key 与 API 通道在写代码之前先把模型调用通道理顺。Claude Desktop 默认走 Anthropic 官方接口但如果你同时用多个模型、多个工具Key 管理会很乱。TaoToken 提供统一的 API 通道一个 Key 就能覆盖多种模型调用MCP Server 里如果需要调用模型能力比如做二次推理、生成摘要也可以走这个通道。你需要先拿到两样东西Base URL 和 API Key。Base URL 是https://taotoken.net/apiAPI Key 在控制台的 API Keys 页面创建。创建时建议按用途命名比如mcp-demo方便后续排查。拿到 Key 后不要硬编码进代码用环境变量管理。# Linux / macOS export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api # Windows PowerShell $env:TAOTOKEN_API_KEYsk-你的key $env:TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用的是 Claude Code 或 Codex 这类编码工具配置方式略有不同。Claude Code 的 settings 文件里需要写全三件套Base URL、Key、Model ID。Codex 的auth.json也是类似结构。下面是一个 Claude Code 的 settings 片段示例路径按你的实际安装位置调整{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的key, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }注意 Model ID 要和你实际使用的模型对应不同客户端对模型名的写法可能不同以控制台文档为准。配置完成后可以用一个最简单的 curl 验证通道是否通curl -X POST https://taotoken.net/api/v1/messages \ -H Content-Type: application/json \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: ping}] }如果返回里有正常的content字段说明通道没问题。这一步很关键因为后面 MCP Server 如果涉及模型调用走的就是这个通道。如果这里就报 401先检查 Key 是否复制完整、有没有多余空格。3. 可复制配置从零搭建 MCP Server 项目现在进入正题。我们构建一个包含两个 Tool 的 Serverget_weather查天气和calculator四则运算。项目结构如下mcp-demo-server/ ├── server.py # MCP Server 主程序 ├── tools/ │ ├── __init__.py │ ├── weather.py # 天气查询工具 │ └── calculator.py # 计算器工具 ├── requirements.txt └── claude_desktop_config.json # Claude Desktop 配置示例先写依赖清单requirements.txtmcp1.0.0 httpx0.27.0安装依赖pip install -r requirements.txt主程序server.py负责创建 Server 实例、注册 Tool 列表、处理调用请求、启动 stdio 传输 MCP Demo Server —— 天气查询 计算器 使用官方 MCP Python SDK 构建 import asyncio import json from mcp.server import Server, NotificationOptions from mcp.server.models import InitializationCapabilities from mcp.server.stdio import stdio_server from tools.weather import get_weather_data from tools.calculator import calculate # 1. 创建 MCP Server 实例 server Server(mcp-demo-server) # 2. 注册 Tool 列表 server.list_tools() async def handle_list_tools() - list: 返回当前 Server 支持的所有 Tool 列表 return [ { name: get_weather, description: 获取指定城市的当前天气信息包括温度、湿度、天气状况和风力, inputSchema: { type: object, properties: { city: { type: string, description: 城市名称支持中文如北京或英文如Beijing } }, required: [city] } }, { name: calculator, description: 执行基本的四则运算加减乘除支持整数和浮点数, inputSchema: { type: object, properties: { operation: { type: string, enum: [add, subtract, multiply, divide], description: 运算类型add-加法, subtract-减法, multiply-乘法, divide-除法 }, a: {type: number, description: 第一个操作数}, b: {type: number, description: 第二个操作数} }, required: [operation, a, b] } } ] # 3. 注册 Tool 调用处理器 server.call_tool() async def handle_call_tool(name: str, arguments: dict) - list: 处理来自 Client 的 Tool 调用请求 if name get_weather: city arguments.get(city, 北京) weather_data await get_weather_data(city) return [{ type: text, text: json.dumps(weather_data, ensure_asciiFalse, indent2) }] elif name calculator: operation arguments[operation] a arguments[a] b arguments[b] result await calculate(operation, a, b) return [{ type: text, text: f计算结果{a} {operation} {b} {result} }] else: raise ValueError(f未知的 Tool: {name}) # 4. 启动 Server async def main(): 通过 stdio 传输启动 MCP Server async with stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationCapabilities( sampling{}, experimental{}, ), notification_optionsNotificationOptions( tools_changedTrue ) ) if __name__ __main__: asyncio.run(main())天气工具tools/weather.py调用免费天气 API并做好异常降级 天气查询工具 —— 调用免费天气 API 获取实时天气数据 import httpx WEATHER_API_URL https://wttr.in/{}?formatj1 async def get_weather_data(city: str Beijing) - dict: 获取指定城市的天气信息 try: async with httpx.AsyncClient(timeout10.0) as client: response await client.get(WEATHER_API_URL.format(city)) if response.status_code ! 200: return _get_mock_weather(city) data response.json() current data[current_condition][0] weather { city: city, temperature_c: int(current[temp_C]), humidity: int(current[humidity]), condition: current[lang_zh][0][value] if current.get(lang_zh) else current[weatherDesc][0][value], wind_speed_kmh: int(current[windspeedKmph]), feels_like_c: int(current[FeelsLikeC]), observation_time: current[observation_time] } return weather except Exception as e: return { **_get_mock_weather(city), note: f模拟数据API 请求失败{str(e)} } def _get_mock_weather(city: str) - dict: 返回模拟天气数据用于 API 不可用时的降级处理 return { city: city, temperature_c: 25, humidity: 60, condition: 晴, wind_speed_kmh: 15, feels_like_c: 26, observation_time: 12:00 PM }计算器工具tools/calculator.py 计算器工具 —— 提供安全的四则运算能力 async def calculate(operation: str, a: float, b: float) - float: 执行基本四则运算 if operation not in (add, subtract, multiply, divide): raise ValueError(f不支持的运算类型{operation}) if operation add: return a b elif operation subtract: return a - b elif operation multiply: return a * b elif operation divide: if b 0: raise ValueError(除数不能为零请检查第二个参数。) return a / btools/__init__.py留空即可。接下来配置 Claude Desktop。配置文件路径Windows 在%APPDATA%\Claude\claude_desktop_config.jsonmacOS 在~/Library/Application Support/Claude/claude_desktop_config.json。内容如下{ mcpServers: { mcp-demo-server: { command: python, args: [C:\\path\\to\\mcp-demo-server\\server.py], description: 天气查询和计算器服务 } } }如果你希望 MCP Server 内部调用模型时走 TaoToken 通道可以在配置里加环境变量{ mcpServers: { mcp-demo-server: { command: python, args: [C:\\path\\to\\mcp-demo-server\\server.py], env: { TAOTOKEN_API_KEY: sk-你的key, TAOTOKEN_BASE_URL: https://taotoken.net/api } } } }保存后完全退出 Claude Desktop 再重启输入框下方会出现工具图标代表 MCP Tool 已就绪。4. 验证请求与成功结果重启 Claude Desktop 后做三组测试。第一组测天气你北京今天天气怎么样 Claude自动调用 get_weather北京今天晴温度 25°C湿度 60%风力 15km/h。第二组测计算器你帮我算一下 156.5 乘以 38.2 等于多少 Claude自动调用 calculator156.5 × 38.2 5978.3。第三组测组合调用你北京和上海哪个城市今天更热 Claude分别调用 get_weather 两次对比后回答北京 25°C上海 28°C上海今天更热。如果工具图标没出现先用mcp dev命令单独测试 Server它会给出比直接连 Claude Desktop 更详细的错误信息pip install mcp mcp dev server.py这个命令会启动一个开发模式你能看到 JSON-RPC 消息的收发过程。实测下来大部分问题在这一步就能定位。比如 Server 启动后 Claude Desktop 连不上通常是 stdout 被print()污染了——stdio 传输下stdout 只能走协议消息日志必须走 stderr 或文件。把print(Server started)改成logging.info(Server started)就能解决。验证成功后你可以尝试修改 Tool 逻辑比如把天气 API 换成自己的数据源或者加一个新 Tool 做数据库查询。MCP 的扩展性就在这里Server 端改一次所有支持 MCP 的 Client 都能用上新能力。5. 本篇常见错误排查开发 MCP Server 时下面这些报错我基本都遇到过对照排查能省不少时间。401 Unauthorized如果 MCP Server 内部调用模型走 TaoToken 通道时报 401先检查TAOTOKEN_API_KEY环境变量是否传入。Claude Desktop 的配置里env字段要写全Key 不要有多余空格。用 curl 单独测一次通道确认 Key 本身有效。local proxy failed / connection refused这类错误通常出现在 Server 启动阶段。检查command和args路径是否正确Windows 下路径要用双反斜杠或正斜杠。如果 Python 不在系统 PATH 里command要写 Python 的绝对路径。reading choices 报错如果 Server 返回的消息格式不符合 JSON-RPC 2.0 规范Client 解析时会报类似reading choices的错误。检查handle_call_tool的返回值必须是[{type: text, text: ...}]这种结构不能直接返回裸字典。OAuth 相关报错部分客户端在连接远程 MCP Server 时会走 OAuth 流程。如果你用的是 stdio 本地 Server一般不会遇到如果遇到检查 Client 的认证配置确认没有误配远程地址。Tool 不出现先确认 Claude Desktop 完全退出再重启不是关窗口。然后检查 JSON 配置文件格式多一个逗号都会导致解析失败。用mcp dev server.py确认 Server 本身能正常列出 Tool。Tool 调用参数错误模型是根据inputSchema生成调用参数的。如果required数组漏了关键字段模型可能不传参。每个 Tool 的必填参数都要写进required。description也要写清楚模型靠它理解 Tool 用途描述越明确调用越准。异步阻塞导致 Server 无响应在 async 上下文里调用同步阻塞函数比如requests.get会卡住整个 Server。用httpx.AsyncClient替代requests所有耗时操作都走异步。一个实用技巧Tool 的description字段极其重要。模型是根据描述来决定是否调用、怎么调用的。描述里写清「做什么、什么场景用、参数含义」调用成功率能明显提升。我试过把描述从「查天气」改成「获取指定城市的当前天气信息包括温度、湿度、天气状况和风力」模型调用准确率肉眼可见地变好。6. 继续深入从 Demo 到生产可用跑通 Demo 只是起点。接下来你可以做几件事把天气 API 换成自己的业务数据源比如订单查询、用户信息加一个 Resource 原语把数据库表结构暴露给模型作为上下文或者用 HTTPSSE 传输把 Server 部署到远程让团队共用。如果你在配置 Claude Code 或 Codex 时遇到认证问题记得三件套要写全Base URL 用https://taotoken.net/apiKey 从控制台 API Keys 页面获取Model ID 按实际使用的模型填写。需要长期跑编码任务或 Agent 场景可以了解 Coding Plan只是想验证模型连通性用模型对话页面发一条消息即可。接入文档里有各客户端的完整配置示例排障时对照检查效率更高。MCP 正在成为 LLM 应用开发的基础设施。现在动手写第一个 Server比等到生态完全成熟再入场能更早理解协议层的设计取舍。遇到问题别急着换方案先用mcp dev把 JSON-RPC 消息打出来看大部分坑都在消息格式和传输层上。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表