☰
动手学MCP从0到1:2.1 SDK介绍与第一个MCP Server创建步骤详解(TaoToken统一Key接入)
2026/9/29 6:36:59 网站建设 项目流程

1. 从零跑通第一个 MCP Server:为什么值得动手做一遍

MCP(Model Context Protocol)是 Anthropic 提出的开放协议,用来把「工具能力」标准化地暴露给大模型。你可以把它理解成给 AI 装了一个 USB 接口:以前每接一个工具都要写一套胶水代码,现在只要按 MCP 规范实现一个 Server,任何支持 MCP 的客户端都能直接调用。它适合谁?适合已经会用 Python 写点脚本、想让大模型真正「动手干活」而不是只聊天的开发者。

这一篇聚焦 SDK 入门与第一个 MCP Server 落地。我会先讲清 stdio 和 SSE 两种传输方式的区别,再拆开 JSON-RPC 的消息骨架,然后给出可复制的config.toml/settings.json配置骨架,最后用 TaoToken 统一 Key 接入 AI 工具,完成一次本地调用验证。目标很明确:从零跑通第一个 MCP Server,而不是停留在概念层面。

很多人卡在第一步不是因为不会写代码,而是被「传输方式」「消息格式」「客户端怎么连」这三件事绕晕。我试过把这三块拆开单独验证,跑通之后再拼起来,成功率会高很多。下面按这个思路走。

2. 前置准备:TaoToken 统一 Key 与 SDK 安装

2.1 为什么用 TaoToken 统一 Key

MCP 客户端在调用大模型时需要一个兼容 OpenAI 接口的base_url和api_key。如果你同时用多个模型,每个都去申请 Key、记不同的地址,管理成本很高。TaoToken 提供统一 Key 和统一 API 通道,一个 Key 就能接入多种模型,配置里只改model字段即可切换。

官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= API 地址:https://taotoken.net/api

注意:API 地址不加 UTM 参数,直接写https://taotoken.net/api即可。Key 在控制台的 API Keys 页面创建,建议先建一个专用 Key 给 MCP 项目用,方便后续排查和轮换。

2.2 安装 MCP SDK

官方 SDK 安装命令如下,建议在虚拟环境里做,避免版本互相干扰:

python -m venv mcp_projects source mcp_projects/bin/activate # Windows 用 mcp_projects\Scripts\activate pip install "mcp[cli]" pip install openai

mcp[cli]带上了命令行调试工具,后面可以用mcp dev直接起一个调试面板。openai库不是只能用 GPT,它是一套标准的客户端调用方式,把base_url指向 TaoToken 就能调通。

2.3 stdio 与 SSE 的区别

stdio 是本地标准输入输出,基于进程间通信。客户端把服务端脚本放到子进程里执行,适合本地开发、单机工具。SSE 是 Server-Sent Events,底层走 HTTP,服务端独立运行,客户端通过 URL 连接,适合服务端部署、多客户端共享。

两者都用 JSON-RPC 交互,区别只在传输层。JSON-RPC 的消息骨架长这样:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "plus_tool", "arguments": { "a": 3, "b": 2 } } }

method是方法名,params是参数,id用来匹配请求和响应。MCP 在此基础上定义了initialize、tools/list、tools/call等标准方法。理解这个骨架,后面看任何 MCP 日志都不会懵。

3. 可复制配置:config.toml 与 settings.json 骨架

3.1 服务端脚本 server.py

先写一个最小的加法工具,重点是函数注释要写清楚,大模型靠它判断什么时候调用:

from mcp.server.fastmcp import FastMCP app = FastMCP("start mcp") @app.tool() def plus_tool(a: float, b: float) -> float: """ 计算两个浮点数相加的结果 :param a: 第一个浮点数 :param b: 第二个浮点数 :return: 浮点数 """ return a + b if __name__ == '__main__': app.run(transport="stdio")

@app.tool()装饰器把函数注册成 MCP 工具,transport="stdio"指定用标准输入输出通信。注释里的参数说明会变成工具的description,直接影响大模型的选择准确率,别偷懒。

3.2 config.toml 骨架

如果你用支持 TOML 配置的客户端,可以这样写:

[mcp_servers.plus] command = "python" args = ["/absolute/path/to/server.py"] transport = "stdio" [llm] base_url = "https://taotoken.net/api" api_key = "sk-your-taotoken-key" model = "deepseek-chat"

command和args告诉客户端怎么启动服务端,base_url指向 TaoToken 的 API 通道。路径一定用绝对路径,相对路径在子进程里经常找不到文件。

3.3 settings.json 骨架

用 JSON 配置的客户端对应写法:

{ "mcpServers": { "plus": { "command": "python", "args": ["/absolute/path/to/server.py"], "env": { "TAOTOKEN_API_KEY": "sk-your-taotoken-key" } } }, "llm": { "baseUrl": "https://taotoken.net/api", "apiKey": "sk-your-taotoken-key", "model": "deepseek-chat" } }

把 Key 放到env里比硬编码在代码里安全,也方便不同环境切换。配置骨架先照抄,跑通之后再按需改。

4. 客户端调用与本地验证

4.1 客户端完整代码

下面这段代码用 stdio 启动服务端,通过 TaoToken 统一 Key 调用大模型,完成一次工具调用闭环:

import asyncio import json from contextlib import AsyncExitStack from openai import OpenAI from mcp import ClientSession from mcp.client.stdio import StdioServerParameters, stdio_client class MCPClient: def __init__(self, server_path: str): self.server_path = server_path self.llm = OpenAI( api_key="sk-your-taotoken-key", base_url="https://taotoken.net/api", ) self.exit_stack = AsyncExitStack() async def run(self, query: str): server_parameters = StdioServerParameters( command="python", args=[self.server_path], ) read_stream, write_stream = await self.exit_stack.enter_async_context( stdio_client(server=server_parameters) ) session = await self.exit_stack.enter_async_context( ClientSession(read_stream=read_stream, write_stream=write_stream) ) await session.initialize() response = await session.list_tools() tools = [] for tool in response.tools: tools.append({ "type": "function", "function": { "name": tool.name, "description": tool.description, "input_schema": tool.inputSchema, }, }) messages = [{"role": "user", "content": query}] llm_response = self.llm.chat.completions.create( messages=messages, model="deepseek-chat", tools=tools, ) choice = llm_response.choices[0] if choice.finish_reason == "tool_calls": messages.append(choice.message.model_dump()) for tool_call in choice.message.tool_calls: function_name = tool_call.function.name function_arguments = json.loads(tool_call.function.arguments) result = await session.call_tool( name=function_name, arguments=function_arguments ) content = result.content[0].text messages.append({ "role": "tool", "content": content, "tool_call_id": tool_call.id, }) final = self.llm.chat.completions.create( model="deepseek-chat", messages=messages ) print("AI:", final.choices[0].message.content) else: print("模型没有选择工具") async def aclose(self): await self.exit_stack.aclose() async def main(): client = MCPClient(server_path="./server.py") try: await client.run("请帮我计算 3 加 2 等于多少?") finally: await client.aclose() if __name__ == "__main__": asyncio.run(main())

流程分八步:建连接参数、开读写流、建 session、初始化、列工具、封装 Function Calling 格式、让模型选工具、把结果回传模型生成最终回复。大模型不会自己执行工具,它只负责「选」,执行靠session.call_tool。

4.2 成功结果长什么样

运行后你会看到两段输出。第一段是工具执行结果5.0,第二段是模型基于结果生成的最终回复,类似「3 加 2 等于 5」。如果只看到第一段没有第二段,说明messages里role: tool那条没拼对,检查tool_call_id是否和tool_call.id一致。

4.3 换成 SSE 只需改两处

服务端把app.run(transport="stdio")改成app.run(transport="sse"),客户端把stdio_client(server=server_parameters)换成sse_client("http://127.0.0.1:8000/sse")。先启动服务端,再跑客户端。SSE 的好处是服务端独立运行,改代码不用重启客户端,调试体验更好。

5. 本篇常见错误排查

5.1 报错:找不到 server.py

子进程的工作目录和你的终端不一样,args里必须用绝对路径。Windows 上路径带空格要加引号,或者用正斜杠。

5.2 报错:401 Unauthorized

Key 没填对,或者base_url写成了带/v1的旧格式。TaoToken 的 API 地址就是https://taotoken.net/api,不要自己加后缀。Key 前后有空格也会 401,复制时注意。

5.3 模型不调用工具

两个原因:一是函数注释太模糊,模型不知道什么时候用;二是tools列表没传进去。检查list_tools()返回的description是否完整,参数类型是否明确。

5.4 报错:finish_reason 不是 tool_calls

说明模型选择了直接回答而不是调工具。可以换一个更明确的提问,比如「用 plus_tool 计算 3 加 2」,或者在 system 提示里说明必须用工具。

5.5 资源泄漏警告

用AsyncExitStack管理stdio_client和ClientSession,在finally里调aclose()。直接async with嵌套在异常时容易漏掉清理,堆栈方式更稳。

6. 下一步:把 MCP 接进你的日常工具链

跑通第一个 Server 之后,你可以把plus_tool换成任何真实能力:查数据库、调内部 API、读本地文件。客户端这边,如果要做长期编码或 Agent 场景,建议用 Coding Plan 管理多模型调用额度,避免每次手动换 Key。

  • 需要创建和管理 Key:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 想先在线验证模型对话效果:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 长期编码 / Agent 场景:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 接入文档与参数说明:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

一个实用技巧:调试 MCP 时先把list_tools()的返回打印出来,确认工具注册成功,再往下走模型调用。很多「模型不调工具」的问题,其实是工具根本没注册上。把这一步当成固定检查点,能省掉大量排查时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询