
1. 为什么 MCP 本地开发值得用 uv 重新搭一遍MCPModel Context Protocol这两年在工具调用生态里出现得越来越频繁简单说它是一套让大模型能伸手去调用本地或远程工具的协议。你写一个 MCP Server把查询天气、读数据库、跑脚本这些能力暴露成 Tool再让支持 MCP 的客户端比如 Cline、Cherry Studio、Claude Code 这类连上来模型就能自己决定什么时候调哪个工具。适合谁适合已经会写点 Python、想让自己的大模型应用真正动起来的开发者尤其是做本地开发、不想一上来就折腾服务器的人。但真动手时第一个坑往往不是协议本身而是环境。Python 项目依赖管理这件事pip venv requirements.txt 的组合在小项目里还行一旦你要同时维护多个 MCP Server、每个又依赖不同版本的 mcp SDK环境就会开始互相打架。MCP 官方文档里推荐用 uv 来管理 Python 工程我实测下来确实省心它把虚拟环境创建、依赖解析、锁文件、运行脚本这几件事揉成了一条命令速度也快。这篇就聚焦一件事用 uv 从零搭一个 MCP 本地开发环境写一个能跑的 MCP Server然后把它的模型调用通道统一接到 TaoToken 的 API 上。这样你本地调试工具逻辑时不用在好几个模型厂商的 Key 之间来回切换一个统一 Key 就能覆盖对话和工具调用。下面所有配置都可以直接复制改掉路径就能用。2. 前置准备装好 uv 并初始化 MCP 项目uv 的安装方式按平台分。Windows 64 位一般下载uv-x86_64-pc-windows-msvc.zip解压后会得到uv.exe、uvx.exe等文件把解压目录加进系统环境变量 PATH重开一个命令行窗口执行uv --version能看到版本号就说明装好了。macOS 和 Linux 用户可以直接用官方脚本或包管理器安装这里不展开。接着初始化项目。假设项目名叫mcp_demo指定 Python 3.13uv init mcp_demo --python3.13 cd mcp_demo这条命令会生成pyproject.toml、README.md和一个示例hello.py。然后装 MCP 的 Python SDK官方推荐带 CLI 扩展uv add mcp[cli]执行完目录下会多出一个.venv虚拟环境依赖也自动装好了。这里有个细节uv 默认会把依赖写进pyproject.toml的dependencies同时生成uv.lock锁文件。团队协作时把uv.lock一起提交别人uv sync就能还原出一模一样的环境比 requirements.txt 靠谱。如果你还要在 Server 里发 HTTP 请求比如调模型 API顺手把httpx也加上uv add httpx到这一步环境骨架就有了。接下来是重点把模型调用通道统一到 TaoToken。3. 接入 TaoToken 统一 API 通道的配置TaoToken 在这里扮演的角色是统一入口你本地 MCP Server 需要调模型时不用分别去配各家厂商的 Key 和 Base URL而是统一走一个 API 地址和一个 Key。它的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的接口格式所以大部分现成的 SDK 都能直接改 Base URL 用起来。先在 TaoToken 控制台创建一个 API Key。入口在控制台的 API Keys 页面创建后复制那串sk-开头的密钥别直接写死在代码里用环境变量管理。在项目根目录建一个.env文件TAOTOKEN_API_KEYsk-你的密钥 TAOTOKEN_BASE_URLhttps://taotoken.net/api然后在pyproject.toml里确认依赖齐全。一个可复制的骨架大概长这样[project] name mcp_demo version 0.1.0 description MCP local dev demo with uv and TaoToken readme README.md requires-python 3.13 dependencies [ mcp[cli]1.2.0, httpx0.27.0, python-dotenv1.0.0, ] [tool.uv] dev-dependencies []改完执行uv sync让依赖对齐。这里python-dotenv用来读.envhttpx用来发请求。注意requires-python和你uv init时指定的版本保持一致否则 uv 会提示解析冲突。配置层面还有一件事MCP Server 本身不强制你用什么模型但如果你想让 Server 内部也具备调模型的能力比如做一个让模型总结文本的 Tool就需要在代码里读这两个环境变量。下面写 Server 时会体现。4. 写一个带模型调用的 MCP Server在项目根目录新建server.py。这个 Server 暴露两个 Tool一个查天气演示纯本地逻辑一个调 TaoToken 做文本总结演示统一 API 通道。用 FastMCP 写法代码量很少import os import httpx from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP load_dotenv() mcp FastMCP(mcp_demo) TAOTOKEN_API_KEY os.getenv(TAOTOKEN_API_KEY) TAOTOKEN_BASE_URL os.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api) mcp.tool() def get_weather(location: str) - str: 根据城市中文名返回天气信息 cities { 北京: 101010100, 上海: 101020100, 成都: 101270101, } city_code cities.get(location) if not city_code: return f暂不支持的城市{location} url http://t.weather.sojson.com/api/weather/city/ city_code resp httpx.get(url, timeout10) return str(resp.json()) mcp.tool() def summarize_text(text: str) - str: 调用 TaoToken 统一通道对文本做一句话总结 if not TAOTOKEN_API_KEY: return 缺少 TAOTOKEN_API_KEY请检查 .env payload { model: gpt-4o-mini, messages: [ {role: system, content: 你是一个简洁的总结助手。}, {role: user, content: f用一句话总结{text}}, ], } headers { Authorization: fBearer {TAOTOKEN_API_KEY}, Content-Type: application/json, } resp httpx.post( f{TAOTOKEN_BASE_URL}/v1/chat/completions, jsonpayload, headersheaders, timeout60, ) resp.raise_for_status() data resp.json() return data[choices][0][message][content] if __name__ __main__: mcp.run(transportstdio)几个关键点。第一mcp.tool()装饰器把普通函数注册成 Tool函数签名和 docstring 会被客户端读去做参数提示所以 docstring 别省。第二summarize_text里请求的是{BASE_URL}/v1/chat/completions这是 OpenAI 兼容路径TaoToken 的 Base URL 是https://taotoken.net/api拼起来就是完整地址。第三模型名这里写的是gpt-4o-mini你可以在 TaoToken 的模型列表里换成任意支持的模型通道不用改。写完先别急着接客户端用官方调试器验证一下。5. 启动服务并验证请求链路MCP 自带一个开发调试器在项目目录下执行uv run mcp dev server.py它会启动一个本地 Web 界面并打印一个带 token 的链接浏览器打开后点 Connect状态变绿说明连接成功。切到 Tools 标签点 List Tools应该能看到get_weather和summarize_text两个工具。先测get_weather参数填北京如果超时就把 Configuration 里的 Request Timeout 调大比如 100000 毫秒。再测summarize_text随便粘一段文字比如uv 是一个用 Rust 写的 Python 包管理器速度比 pip 快很多正常会返回一句总结。这一步能跑通说明从 MCP Server 到 TaoToken 的整条链路是通的。调试器验证完再把它接到真实客户端。以 Cherry Studio 为例安装后在设置里配好模型服务然后进 MCP 服务器配置填入{ mcpServers: { mcp_demo: { name: mcp_demo, type: stdio, isActive: true, command: uv, args: [ run, --directory, F:\\你的项目路径\\mcp_demo, server.py ] } } }把--directory换成你自己的绝对路径。保存后客户端会拉起这个 Server回到对话界面选中它问一句北京的天气怎么样模型就会自动调用get_weather并把结果组织成回答。注意客户端用的模型本身要支持工具调用否则它不会去触发 Tool。如果你想用代码方式验证也可以写个最小 Clientimport asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client server_params StdioServerParameters( commanduv, args[run, --directory, F:\\你的项目路径\\mcp_demo, server.py], envNone, ) async def run(): async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() print(Tools:, tools) result await session.call_tool( namesummarize_text, arguments{text: MCP 让模型可以调用本地工具。}, ) print(Result:, result) if __name__ __main__: asyncio.run(run())先在一个窗口uv run server.py把 Server 跑起来再开另一个窗口uv run client.py就能看到工具列表和调用结果。6. 本地开发常见报错排查报错一ModuleNotFoundError: No module named mcp。多半是你没在项目虚拟环境里跑或者忘了uv add mcp[cli]。确认在项目根目录执行uv sync然后用uv run前缀启动别直接python server.py。报错二客户端连不上状态一直灰的。检查 JSON 配置里的--directory路径是不是绝对路径、有没有写错盘符。Windows 下反斜杠要转义成\\。另外确认uv在系统 PATH 里客户端进程能调到它。报错三调summarize_text返回 401。说明TAOTOKEN_API_KEY没读到。检查.env是否在项目根目录、load_dotenv()是否在读取环境变量之前调用。也可以临时print(os.getenv(TAOTOKEN_API_KEY))确认。报错四请求超时。调试器里把 Request Timeout 调大代码里httpx.post的timeout设成 60 秒以上。模型接口本身有延迟别用默认的 5 秒。报错五模型不调用工具。这不是 MCP 的问题是客户端选的模型不支持 function calling或者工具调用开关没打开。换一个支持工具调用的模型再试。7. 下一步怎么走环境搭通之后你可以把summarize_text换成更实用的 Tool比如读本地文件、查 SQLite、调内部接口。模型通道这块不用动继续走 TaoToken 的统一 Key 就行。想验证不同模型对工具调用的支持差异可以直接在模型对话里试如果是要长期跑编码类 Agent、频繁调工具建议了解一下 Coding Plan额度模型更划算。接入过程中遇到 Key 或路径问题去 API Keys 页面重新生成一个再对照接入文档核对 Base URL 拼写基本都能解决。