拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

【手撕MCP代码】从零实现天气预报查询与心情朋友圈文案生成器

【手撕MCP代码】从零实现天气预报查询与心情朋友圈文案生成器

1. 从零手撕 MCP 天气预报服务:为什么值得自己写一遍

MCP(Model Context Protocol)这两年被聊得很多,但真正动手写过一个能跑通的 MCP Server 的人其实不多。大多数人停留在“装个客户端、导入别人写好的配置”这一步,一旦工具返回的数据不对、模型不调用工具、或者调用链断在中间,就完全不知道从哪查起。这篇就带你从零手撕一个 MCP 天气预报查询服务,并且把“天气数据 → 朋友圈文案”这条链路完整串起来,最后用真实城市名验证返回结果。

先说清楚这个 MCP 天气预报查询与朋友圈文案生成器到底是什么、能做什么、适合谁。它是一个基于 MCP 协议的最小可运行服务端,对外暴露两个工具:一个负责根据城市名查实时天气,一个负责把天气信息喂给大模型生成朋友圈文案。适合三类人:一是刚接触 MCP、想搞懂 Server 端到底怎么写的人;二是想把外部 API 接进 AI 客户端、做点实用小工具的人;三是想理解“工具调用链”在真实场景里怎么跑通的人。

我试过直接抄网上的示例代码,结果卡在依赖版本和 transport 配置上整整一个下午,所以这篇会把踩过的坑和排查方法都写清楚。整个链路是这样的:你在 AI 客户端里输入“查一下西安天气并配个朋友圈文案”,客户端通过 MCP 协议调用你写的 Server,Server 先调天气工具拿到数据,再把数据传给文案工具,最后把结果返回给客户端展示。听起来简单,但每一步都有细节。

MCP 的架构里,MCP 主机是发起请求的 AI 应用,MCP 客户端是主机创建的与 Server 一对一的连接,MCP Server 就是我们今天要写的东西。Server 提供三类能力:资源(Resources,类似可读取的文件或数据库)、工具(Tools,可被 LLM 调用的函数)、提示(Prompts,预编写的模板)。我们这个项目主要用 Tools,因为天气查询和文案生成都是“被调用执行”的动作。

为什么不用现成的天气插件?因为自己写一遍你才能真正理解工具注册、参数校验、返回值序列化这些环节。而且朋友圈文案这种个性化需求,现成插件基本满足不了,必须自己接大模型。下面进入实操,从环境准备开始。

2. TaoToken 前置准备:API Key 与模型接入配置

在写代码之前,先把模型调用这一环准备好。我们这个 MCP Server 里的文案生成工具需要调用大模型,所以你得有一个可用的 API Key 和对应的 Base URL。这里用 TaoToken 来做模型接入,它的接口兼容 OpenAI 格式,配置起来比较直接。

先到官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册账号,然后进控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,在 API Keys 页面点新建,复制生成的 Key 保存好,后面代码里要用。API 的基础地址是 https://taotoken.net/api ,注意这个地址不带任何查询参数,直接作为 base_url 使用。

模型选择上,文案生成这种任务用 DeepSeek 系列或者通用对话模型都行,你在模型对话页面可以先试一下效果,地址是 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。如果你后面打算长期做编码类或 Agent 类项目,可以了解下 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,不过我们这个天气文案项目用按量调用就够了。

天气数据这边,你需要一个天气 API。聚合数据、和风天气之类的都行,注册后在个人中心拿到 AppKey。本文示例用聚合数据的简单天气接口,接口地址是 http://apis.juhe.cn/simpleWeather/query ,请求参数是 key 和 city。你拿到自己的 AppKey 后替换代码里的占位符即可。

环境方面,Python 需要 3.11 及以上,因为 MCP 的 Python SDK 对异步和类型注解有要求。依赖装这几个:mcp、litellm、requests。litellm 用来统一调用大模型接口,requests 用来请求天气 API。装依赖的命令如下:

pip install mcp==1.23.1 litellm==1.79.0 requests==2.32.3

版本号建议锁一下,MCP SDK 迭代比较快,不同版本 API 有差异。装完之后可以pip show mcp确认一下版本。到这里前置准备就完成了,接下来进入代码环节。

3. 可复制配置:MCP Server 完整代码与工具注册

这一节是核心,我会把完整的 MCP Server 代码给出来,并且逐段解释。先看整体结构:用 FastMCP 初始化一个名为 weather 的 Server,然后注册两个工具函数,最后用 stdio 传输方式启动。

先写 Server 初始化和启动部分:

from mcp.server.fastmcp import FastMCP mcp = FastMCP("weather") def main(): mcp.run(transport="stdio") if __name__ == "__main__": main()

FastMCP("weather")里的 weather 是 Server 名称,客户端配置里会用到。transport="stdio"表示通过标准输入输出通信,这是本地 MCP Server 最常用的方式,客户端启动子进程后通过 stdin/stdout 交换 JSON-RPC 消息。

接下来注册天气查询工具。用@mcp.tool()装饰器标记,函数签名和 docstring 会被 MCP 协议提取成工具描述,模型根据这个描述决定要不要调用:

import requests @mcp.tool() async def get_weather(city: str) -> dict: """获取城市的天气信息""" apiUrl = 'http://apis.juhe.cn/simpleWeather/query' apiKey = '你的天气APIKey' requestParams = { 'key': apiKey, 'city': city, } response = requests.get(apiUrl, params=requestParams) if response.status_code == 200: responseResult = response.json() return responseResult else: return {'error': '请求异常'}

注意 docstring 一定要写清楚,这是模型判断工具用途的依据。参数类型标注city: str和返回类型dict也要写,MCP 会据此生成 JSON Schema。

然后是文案生成工具,这里用 litellm 调用大模型:

import litellm @mcp.tool() async def get_wechat_article(weather: str) -> str: """根据天气信息生成朋友圈文案""" prompt = f""" 你是一个专业的社交媒体文案writer,擅长根据天气信息创作符合情景的朋友圈文案。 请根据以下天气信息创作一个文案:{weather} """ response = litellm.completion( model="openai/deepseek-ai/DeepSeek-V3", api_key="你的TaoToken APIKey", api_base="https://taotoken.net/api", messages=[{"role": "user", "content": prompt}] ) return response.choices[0].message.content

这里model字段的格式是openai/模型名,api_base填 TaoToken 的 API 地址。如果你用的模型名不同,替换掉deepseek-ai/DeepSeek-V3即可。把两个工具拼起来就是完整代码,保存为weather_article_mcp.py。

客户端配置方面,以 Cherry Studio 为例,导入下面这段 JSON,注意把路径改成你自己的文件路径:

{ "mcpServers": { "weather": { "command": "uv", "args": [ "--directory", "D:\\code\\python\\python-study\\mcp", "run", "weather_article_mcp.py" ] } } }

如果你不用 uv,把 command 改成python,args 改成["D:\\code\\python\\python-study\\mcp\\weather_article_mcp.py"]也行。配置里的三件套要对应上:Base URL 是https://taotoken.net/api,Key 是你创建的 API Key,Model ID 是deepseek-ai/DeepSeek-V3这类具体模型名。导入成功后应该能看到两个工具:get_weather 和 get_wechat_article。

4. 验证请求:用真实城市跑通天气到文案的完整链路

配置导入后,在客户端对话框里输入“查询西安天气,并配上朋友圈文案”,观察工具调用情况。正常情况下你会看到客户端先调用 get_weather,参数是{"city": "西安"},返回一个包含天气信息的 JSON,然后把这个结果作为参数传给 get_wechat_article,最后返回一段文案。

如果天气接口返回正常,你会看到类似这样的结构:

{ "reason": "查询成功", "result": { "city": "西安", "realtime": { "temperature": "18", "info": "晴", "humidity": "45%" }, "future": [...] }, "error_code": 0 }

文案工具拿到这个 JSON 后,会生成一段适合发朋友圈的文字,比如“西安今天晴,18度,湿度刚好,适合出门走走”之类的。你可以在客户端的调用链视图里看到完整的调用过程:用户输入 → 模型决策 → 调用 get_weather → 返回结果 → 模型决策 → 调用 get_wechat_article → 返回文案。

验证的时候建议换几个城市试,比如北京、上海、成都,看看返回的天气数据是否随城市变化。如果文案生成这一步返回空或者报错,先检查 API Key 和 Base URL 是否正确。你也可以单独测试天气接口,用 curl 直接请求:

curl "http://apis.juhe.cn/simpleWeather/query?key=你的Key&city=西安"

这样能快速定位是天气接口的问题还是 MCP 链路的问题。实测下来,只要天气接口返回正常、模型接口能通,整条链路跑通大概只需要几分钟。

5. 常见报错排查:401、local proxy failed、reading choices 怎么解

这一节把几个高频报错列出来,对照着查。

401 Unauthorized 一般出现在模型调用这一步,说明 API Key 不对或者没传。检查 litellm.completion 里的 api_key 是否填了正确的 TaoToken Key,注意不要有多余空格。如果 Key 是对的还报 401,确认 api_base 是不是https://taotoken.net/api,少写或多写路径都会导致鉴权失败。

local proxy failed 通常和网络环境或客户端配置有关。先确认你的 MCP Server 进程能正常启动,在命令行直接python weather_article_mcp.py看有没有报错。如果进程启动正常但客户端连不上,检查配置里的路径是否正确,Windows 路径要用双反斜杠或正斜杠。另外确认 command 指向的可执行文件在系统 PATH 里。

reading choices 报错一般出现在解析模型返回结果时,说明 response 结构不符合预期。可能是模型名写错了,或者接口返回了错误信息而不是正常的 choices 数组。打印一下完整 response 看看:

print(response)

如果返回的是错误对象,里面会有 message 字段说明原因。常见的是模型名不存在或没有权限,换成模型对话页面里确认可用的模型名再试。

OAuth 相关报错一般出现在需要授权的客户端场景,本地 stdio 模式的 MCP Server 通常不涉及。如果你用的是远程 MCP Server,需要检查 token 是否过期。另外工具调用返回空结果时,先确认天气 API 的 AppKey 有没有过期,聚合数据的免费接口有调用次数限制。

还有一个容易忽略的点:MCP SDK 版本和客户端版本不匹配。如果你用的客户端比较老,可能不支持某些 transport 或工具特性,升级客户端到最新版通常能解决。排查顺序建议是:先单独测天气接口,再单独测模型接口,最后测 MCP 链路,逐段排除。

6. 继续扩展:把 MCP 天气服务接进你的日常工作流

跑通这个最小示例后,你可以按同样的模式扩展更多工具。比如加一个 get_air_quality 查空气质量,或者加一个 get_weather_forecast 查未来几天天气,然后在文案生成工具里把多个数据源组合起来,生成更丰富的内容。MCP 的好处就在这,工具注册是独立的,加一个新函数就是一个新能力。

如果你想把这类服务用在长期编码或 Agent 项目里,可以了解下 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它更适合高频调用的场景。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有更详细的参数说明和示例。API Keys 管理页面是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,需要新建或轮换 Key 的时候去这里。

最后给个实用技巧:把天气 API 的 AppKey 和模型 API Key 放到环境变量里,不要硬编码在代码中,这样分享代码时不会泄露。用os.environ.get("WEATHER_API_KEY")读取,本地调试时在启动脚本里 export 一下就行。另外工具函数的 docstring 尽量写具体,模型判断是否调用工具全靠它,写得太模糊会导致该调用的时候不调用。

返回列表