ARTICLE DETAIL

资讯详情

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

手动写一个MCP server:用Python+uv从stdio到SSE的TaoToken配置骨架

手动写一个MCP server:用Python+uv从stdio到SSE的TaoToken配置骨架 1. 为什么我要手写一个 MCP serverMCP server 说白了就是一段 Python 程序它把「工具」「资源」「提示词」这三类能力暴露给大模型客户端让模型能真正去调函数、读数据而不是只会在对话框里编。你平时用的 Cherry Studio、Claude Desktop、Cline 这些客户端背后连的就是一个个 MCP server。理解它最好的方式不是看文档而是自己从零写一个跑通 stdio 和 SSE 两种传输模式再把它接到统一的 API 通道上。这篇面向的是已经会一点 Python、想搞清楚 MCP 到底怎么跑起来的人。我会用 uv 管环境用官方mcp[cli]SDK 写一个带加法工具、动态资源、提示词模板的最小 server然后分别用 stdio 和 SSE 两种方式验证连通性。最后给出 TaoToken 的config.toml和settings.json骨架让请求走统一 Key 通道转发。全程本地可复现不需要你去折腾网络环境。我试过把 stdio 和 SSE 混在一个文件里反复切最容易踩的坑是端口没释放和客户端配置路径写错后面排障章节会逐个说。2. TaoToken 前置统一 Key 与 API 通道准备在写 server 之前先把「请求往哪发」这件事定下来。TaoToken 提供统一的 API 通道你只需要一个 Key就能在模型对话、编码、Agent 这些场景里复用同一套接入参数不用每个客户端单独配一遍。你需要做两件事拿到 Key记住两个地址。项目地址用途官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content注册、看文档、进控制台API Basehttps://taotoken.net/api所有请求的统一入口不加 UTMKey 在控制台的 API Keys 页面生成格式一般是一串sk-开头的字符串。生成后先复制到本地一个安全的地方后面config.toml和settings.json都要用。注意Key 只显示一次页面刷新后就看不到了。建议生成后立刻写进本地配置文件别只放在聊天窗口里。如果你后面要长期跑编码类 Agent可以顺带了解 Coding Plan它把常用的编码模型额度打包配合 MCP server 做工具调用会更顺。但这一篇的重点是骨架先把最小链路跑通。3. 用 uv 初始化工程并写最小 MCP server3.1 安装 uv 与 Python 3.13uv 是目前管 Python 环境最省心的工具装完它连虚拟环境都不用你手动建。Windows 下用 PowerShell 一行搞定powershell -ExecutionPolicy ByPass -c irm https://astral.sh/uv/install.ps1 | iex装完确认一下版本和已有的 Pythonuv --version uv python list然后装目标版本我选 3.13uv python install 3.133.2 初始化项目并加依赖新建文件夹并初始化-p指定 Python 版本mkdir mcp_server cd mcp_server uv init . -p 3.13 uv add mcp[cli]执行完你会看到.venv虚拟环境目录和pyproject.toml。pyproject.toml里记录了项目名、Python 版本和依赖.venv是隔离环境两者配合保证换台机器也能复现。3.3 写 server 主体把main.py改成下面这样。这段代码定义了一个加法工具、一个动态问候资源、一个提示词模板from mcp.server.fastmcp import FastMCP mcp FastMCP(Demo) mcp.tool() def add(a: int, b: int) - int: Add two numbers return a b mcp.resource(greeting://{name}) def get_greeting(name: str) - str: Get a personalized greeting return fHello, {name}! mcp.prompt() def greet_user(name: str, style: str friendly) - str: Generate a greeting prompt styles { friendly: Please write a warm, friendly greeting, formal: Please write a formal, professional greeting, casual: Please write a casual, relaxed greeting, } return f{styles.get(style, styles[friendly])} for someone named {name}. if __name__ __main__: mcp.run(transportstdio)三个装饰器的语义要分清mcp.tool()相当于 HTTP 里的 POST模型调它会触发副作用或计算mcp.resource()相当于 GET只读数据不该改状态mcp.prompt()是给模型用的提示词模板客户端可以把它当快捷指令。理解这三者的区别后面设计自己的 server 就不会乱。4. 可复制配置stdio 与 SSE 两种传输4.1 stdio 模式配置stdio 模式下客户端把 server 当子进程拉起来通过标准输入输出通信。Cherry Studio 这类客户端里配置 MCP 服务器时命令和参数这样填{ mcpServers: { demo-stdio: { command: uv, args: [ --directory, D:\\userApplication\\mcp_server, run, mcp, run, main.py ] } } }--directory指向你的工程目录uv run mcp run main.py是启动命令。客户端会自己拉起这个进程你不需要手动开终端。4.2 SSE 模式配置SSE 模式要把 server 单独跑起来客户端通过 URL 远程调用。先把main.py最后一行改掉mcp.run(transportsse)然后手动启动uv run mcp run main.py默认监听http://127.0.0.1:8000SSE 端点是/sse。客户端里配置成 URL 形式{ mcpServers: { demo-sse: { url: http://127.0.0.1:8000/sse } } }4.3 TaoToken 统一通道骨架如果你希望 server 内部调用模型时走 TaoToken 的统一通道用config.toml存接入参数[taotoken] api_base https://taotoken.net/api api_key sk-你的Key default_model 你的模型名 [mcp] transport stdio对应的settings.json给客户端用{ taotoken: { apiBase: https://taotoken.net/api, apiKey: sk-你的Key }, mcp: { transport: stdio, sseUrl: http://127.0.0.1:8000/sse } }提示api_base不要带 UTM 参数保持https://taotoken.net/api干净避免某些客户端拼接路径时出错。5. 验证请求stdio 与 SSE 连通性实测5.1 stdio 验证在 Cherry Studio 里添加 MCP 服务器按 4.1 的 JSON 填好命令和参数保存后客户端会尝试启动进程。启动成功的话工具列表里会出现add资源里会出现greeting://{name}。调用add传a3, b5返回8就说明 stdio 链路通了。这一步的本质是客户端把 JSON-RPC 请求写进子进程的 stdinserver 处理后把结果写回 stdout。5.2 SSE 验证先确认 server 在跑uv run mcp run main.py终端会打印监听地址。然后在客户端里添加 URL 类型的 MCP 服务器填http://127.0.0.1:8000/sse。添加后同样调add返回8即成功。你也可以用 curl 直接探一下 SSE 端点是否活着curl -N http://127.0.0.1:8000/sse-N关闭缓冲能看到服务端持续推送的事件流就说明 SSE 通道正常。5.3 两种模式的区别维度stdioSSE部署位置客户端本机可单独部署通信方式标准输入输出HTTP 长连接距离近进程级远网络级适用场景本地工具、单机远程服务、多客户端共享stdio 适合本地一次性工具SSE 适合把 server 放到一台机器上给多个客户端用。选哪个取决于你的 server 要不要被共享。6. 本篇常见错排查端口被占用SSE 模式启动报Address already in use说明 8000 端口有别的进程。换端口可以在FastMCP初始化时传port参数或者先netstat -ano | findstr 8000找到进程结束掉。客户端拉不起 stdio 进程多半是--directory路径写错或者uv不在系统 PATH 里。把路径换成绝对路径并确认终端里uv --version能正常输出。SSE 连不上检查 server 是否真的在跑以及 URL 是不是/sse结尾。有些客户端要求填完整端点只填http://127.0.0.1:8000会失败。Key 无效或 401确认api_key复制完整没有多余空格。如果走 TaoToken 通道报错去控制台 API Keys 页面核对 Key 状态必要时重新生成。改了 transport 没生效mcp.run(transport...)是启动时读的改完必须重启 server客户端也要重新连接。排障时优先看 server 端终端的输出大部分错误信息会直接打在那里比客户端日志清楚。7. 下一步把骨架接到真实场景骨架跑通后你可以按同样的结构加自己的工具。比如加一个读本地文件的工具或者加一个查数据库的只读资源。工具用mcp.tool()只读数据用mcp.resource()提示词模板用mcp.prompt()三者别混用。接入参数统一走 TaoToken 的 API 通道Key 和 Base 只维护一份换客户端时改settings.json就行。需要生成新 Key 或查看额度进控制台 API Keys 页面接入细节看接入文档想先验证模型对话是否正常用模型对话页面发一条测试消息长期跑编码 Agent 的话Coding Plan 能把额度管得更省心。把add换成你真正需要的函数这个 server 就从 demo 变成你自己的工具了。
返回列表