首页 / 资讯中心 / 文章详情

MCP Server实战搭建:用FastMCP与uv打造天气查询服务,接入TaoToken统一Key通道

MCP Server实战搭建:用FastMCP与uv打造天气查询服务,接入TaoToken统一Key通道 ★ FEATURED ARTICLE
1. 从零搭建天气查询 MCP Server为什么模型自己查不到天气你可能遇到过这种情况问 AI 客户端「我这边现在天气怎么样」它一本正经地回你一段听起来很合理、但完全对不上的天气描述。原因不复杂——大模型本身的知识来自训练数据它没有实时联网能力也没有你所在位置的实时气象数据。它不是在骗你它只是在「凭记忆猜」。MCP Server 就是解决这类问题的标准做法。MCPModel Context Protocol把「模型」和「外部工具/数据源」解耦模型负责理解意图和决定调用哪个工具MCP Server 负责真正去执行查询并把结构化结果返回。天气查询是理解 MCP 最合适的入门场景因为它足够简单——输入城市名输出天气数据没有复杂的鉴权链路和状态管理。这篇要做的是一个能被 AI 客户端直接调用的天气查询 MCP Server。技术栈是 Python uv FastMCPuv 负责依赖和虚拟环境管理FastMCP 负责把普通 Python 函数注册成 MCP 工具。整个过程分四块环境准备、server.py 编写、本地 stdio 联调、把模型通道统一到 TaoToken。适合谁看写过一点 Python、想让自己的 AI 客户端具备实时工具调用能力、但还没完整跑通过一个 MCP Server 的人。我试过用最朴素的方式pip 手写 JSON-RPC搭第一个 MCP Server光协议握手就调了半天。FastMCP 把这些都封装掉了你只需要关心「这个工具叫什么、参数是什么、返回什么」。下面按可复制的顺序来。2. 用 uv 管理 Python 环境与 FastMCP 依赖2.1 为什么这个项目用 uv 而不是 pip传统pip install能用但在这个场景下有两个痛点一是 MCP Server 通常要跑在客户端拉起的子进程里环境必须干净可复现二是 FastMCP、httpx 这些包有版本约束手动管理容易冲突。uv 用pyproject.toml描述依赖安装速度快虚拟环境隔离彻底uv run还能直接「带环境执行脚本」省掉手动 activate 的步骤。安装 uv 有两种方式。已经有 pip 的话pip install uvWindows 上没装 pip可以用官方脚本powershell -ExecutionPolicy ByPass -c irm https://astral.sh/uv/install.ps1 | iex装完验证一下uv --version能打印版本号就说明可用。接下来初始化项目。我习惯给每个 MCP Server 单独一个目录mkdir weather-mcp cd weather-mcp uv inituv init会生成pyproject.toml和main.py。然后加依赖uv add mcp httpx这里mcp是官方 Python SDKFastMCP 就在里面httpx用来发异步 HTTP 请求比 requests 更适合 async 场景。执行完你会看到pyproject.toml里多了dependencies段类似[project] name weather-mcp version 0.1.0 requires-python 3.10 dependencies [ mcp1.2.0, httpx0.27.0, ]注意Python 版本建议 3.10 以上FastMCP 的类型注解和 async 语法在低版本上会有兼容问题。uv python pin 3.11可以锁定解释器版本。2.2 天气数据源与 API Key 准备天气数据我用 OpenWeatherMap 的免费接口注册后在控制台拿一个 API Key 即可。它的当前天气端点返回 JSON字段清晰适合做 MCP 工具的输出。把 Key 放进环境变量不要硬编码进代码# Linux / macOS export OPENWEATHER_API_KEY你的key # Windows PowerShell $env:OPENWEATHER_API_KEY你的key到这一步环境侧的东西就齐了uv 管依赖环境变量管密钥接下来写 server.py。3. 可复制的 server.py 与 FastMCP 工具注册配置3.1 完整 server.py新建server.py内容如下。我把它拆成「数据获取」和「工具注册」两层方便你替换成别的数据源import os import json import httpx from typing import Any from mcp.server.fastmcp import FastMCP # 创建 MCP Server 实例名字会显示在客户端工具列表里 mcp FastMCP(WeatherServer) OPENWEATHER_API https://api.openweathermap.org/data/2.5/weather OPENWEATHER_API_KEY os.environ.get(OPENWEATHER_API_KEY, ) USER_AGENT weather-mcp/1.0 async def get_weather(city: str) - dict[str, Any]: 从 OpenWeatherMap 获取指定城市的原始天气数据。 params { q: city, appid: OPENWEATHER_API_KEY, units: metric, lang: zh_cn, } headers {User-Agent: USER_AGENT} async with httpx.AsyncClient(timeout10) as client: resp await client.get(OPENWEATHER_API, paramsparams, headersheaders) resp.raise_for_status() return resp.json() def format_weather(data: dict[str, Any]) - str: 把原始 JSON 整理成模型容易读的文本。 if not data or main not in data: return 未获取到有效天气数据请检查城市名或 API Key。 city data.get(name, 未知城市) main data[main] weather data.get(weather, [{}])[0] return ( f城市{city}\n f天气{weather.get(description, 未知)}\n f温度{main.get(temp)}°C体感 {main.get(feels_like)}°C\n f湿度{main.get(humidity)}%\n f气压{main.get(pressure)} hPa ) mcp.tool() async def weather_tool(city: str) - str: 查询指定城市的实时天气。 Args: city: 城市名称例如 Beijing 或 Shanghai。 data await get_weather(city) return format_weather(data) if __name__ __main__: mcp.run(transportstdio)几个关键点值得单独说。mcp.tool()装饰器把weather_tool注册成 MCP 工具函数名就是工具名docstring 会被模型当作工具描述读取——所以 docstring 要写清楚「这个工具干什么、参数是什么」模型靠它决定要不要调用。transportstdio表示走标准输入输出通信这是本地 MCP Server 最常用的方式客户端拉起进程后通过 stdin/stdout 交换 JSON-RPC 消息。3.2 客户端接入配置JSON 片段MCP 客户端Cherry Studio、Cline、Claude Desktop 等接入本地 stdio Server配置结构基本一致。以通用 JSON 为例{ mcpServers: { weather: { command: uv, args: [ --directory, D:/MCP/weather-mcp, run, server.py ], env: { OPENWEATHER_API_KEY: 你的key } } } }--directory不能省它告诉 uv 去哪个目录找pyproject.tomlrun会自动使用项目虚拟环境执行server.py不需要你手动 activate。env段把 API Key 注入子进程这样代码里os.environ.get就能读到。如果你用的是 Claude Code 这类支持 MCP 的编码工具配置思路一样只是配置文件位置不同。把 Base URL、Key、Model ID 三件套理清楚后面接 TaoToken 时会用到。4. 本地 stdio 联调与真实天气查询验证4.1 先用命令行确认 Server 能起来在接入客户端之前先在终端里跑一遍确认没有语法错误和依赖缺失cd weather-mcp uv run server.py如果没有任何输出、进程挂在那里等待输入说明 Server 正常启动了——stdio 模式下它就是在等客户端发消息。按 CtrlC 退出。如果报ModuleNotFoundError说明依赖没装全回到uv add那步。4.2 用 MCP Inspector 做可视化调试官方提供了 Inspector 工具可以直观看到工具列表和调用结果npx modelcontextprotocol/inspector uv --directory D:/MCP/weather-mcp run server.py浏览器打开它提示的地址左侧能看到weather_tool点进去输入城市名执行右侧会返回格式化后的天气文本。这一步能跑通说明 Server 本身没问题剩下的就是客户端配置。4.3 在客户端里发起一次真实查询把 3.2 的 JSON 配置填进你的客户端保存并启动 MCP 服务。状态变绿后在对话里问帮我查一下上海现在的天气适合穿什么衣服模型会先调用weather_tool拿到实时数据再基于数据给出穿搭建议。你会看到工具调用卡片里显示city: Shanghai返回温度、湿度、天气描述。这就是 MCP 的价值——模型不再「猜」而是拿到真实数据再回答。4.4 把模型通道统一到 TaoTokenMCP Server 负责工具调用但模型本身还是要走一个 API 通道。如果你同时用多个客户端、多个模型Key 管理会很乱。TaoToken 提供统一 Key 通道把模型调用收敛到一个入口。以 OpenAI 兼容配置为例{ base_url: https://taotoken.net/api, api_key: 你的TaoToken Key, model: claude-sonnet-4-5 }在客户端的模型设置里填入 Base URL 和 KeyModel ID 按你实际要用的填。这样 MCP 工具走本地 stdio模型推理走 TaoToken两边职责清晰。需要拿 Key 的话去控制台创建接入细节看官方文档。5. 常见报错排查401、local proxy failed 与 reading choices5.1 401 Unauthorized最常见。两种可能一是 OpenWeatherMap 的 Key 没生效新注册的 Key 有时要等十几分钟二是 TaoToken 的 Key 填错或没填。排查顺序先在终端echo $OPENWEATHER_API_KEY确认环境变量有值再确认客户端env段有没有把 Key 传进去。如果代码里读的是os.environ.get而客户端配置里没写env那 Server 拿到的就是空字符串请求自然 401。5.2 local proxy failed / spawn uv ENOENT这个报错通常出现在客户端启动 MCP Server 时。ENOENT意思是找不到uv这个可执行文件。原因是客户端拉起的子进程没有继承你终端的 PATH。解决办法把command从uv改成 uv 的绝对路径比如 Windows 上是C:/Users/你的用户名/.local/bin/uv.exemacOS 上是/Users/你的用户名/.local/bin/uv。改完重启客户端。5.3 reading choices 报错这个报错一般不是 MCP Server 的问题而是模型 API 返回结构不符合预期。常见原因是 Base URL 配错——比如把https://taotoken.net/api写成了带/v1或其他路径导致请求打到了错误端点返回的不是标准 OpenAI 格式。检查你的 Base URL 是否和文档一致Model ID 是否是通道支持的模型。如果用的是 Claude Code 这类工具还要确认它读的是哪个配置文件settings.json或auth.json别改错了地方。5.4 OAuth 相关报错部分客户端在接入远程 MCP 或某些模型通道时会走 OAuth 流程。如果你看到OAuth token expired或invalid_grant先确认是不是把本地 stdio Server 配成了远程模式。本地 Server 不需要 OAuth走 stdio 就行。如果是模型通道的 OAuth重新走一遍授权流程即可。5.5 工具调用返回空数据Server 起来了、模型也调用了工具但返回「未获取到有效天气数据」。检查城市名——OpenWeatherMap 对中文城市名支持不稳定建议用拼音或英文比如Shanghai而不是上海。另外确认units参数是metric否则温度会是开尔文。6. 把天气 MCP 接入你的日常工作流跑通之后这个 Server 可以继续扩展。比如加一个forecast_tool查未来几天天气或者加air_quality_tool查空气质量FastMCP 注册新工具就是多写一个带mcp.tool()的函数。工具多了之后docstring 的清晰度直接决定模型选得对不对这点比代码本身更重要。模型通道这边如果你要长期跑编码类 Agent 或者多个 MCP 工具协同用 Coding Plan 会比按量计费更省心只是偶尔验证模型效果用模型对话页面就够了。Key 在 API Keys 页面管理接入细节看文档。把工具和模型通道分开配置后面换模型、加工具都不会互相影响。最后留一个实用习惯每次改完 server.py先在终端uv run server.py确认能启动再去客户端里测。客户端报错信息往往被包装过终端里的原始报错才是最有用的。
阅读完成 · 觉得有帮助?
咨询建站