引言你是否曾经让 Claude 帮你查天气、分析文件或者调用内部 API却不得不在对话里粘贴整段 JSON甚至手动解释返回结果随着大语言模型的能力越来越强我们不再满足于文本对话更希望 AI 能像真实的工作助手一样直接使用我们指定的工具对外交互。过去这种集成往往需要搭建复杂的中间服务如今有了Model Context ProtocolMCP一切都变得简单而优雅。本文将带你从零开始理解 MCP 的核心理念并通过一个完整的天气查询工具实战为 Claude 客户端如 Claude Desktop构建专属的工具服务器。你会看到仅仅几十行 Python 代码就能让 Claude 在回答中实时拉取外部数据甚至执行你定义好的任何操作。读完此文你将能够理解 MCP 的设计思想与核心概念使用 Python 快速构建一个 MCP Server注册自定义工具并配置 Claude Desktop 使用掌握调试、安全与常见避坑要点让我们直接开始吧。核心概念MCP 是什么MCPModel Context Protocol是由 Anthropic 推出的一种开放协议它标准化了 AI 模型与外部工具、数据源之间的交互方式。你可以把它想象成 AI 世界的“USB‑C 接口”——只要遵循 MCP 规范任何客户端Claude Desktop、IDE 插件、自研应用都能无缝连接任何服务器发现并使用其提供的工具Tools、资源Resources和提示Prompts。MCP 架构一览MCP 采用客户端‑服务器Client‑Server架构通信基于 JSON‑RPC 2.0底层传输可以是标准输入输出stdio或 HTTPSSE。一次典型的交互流程如下Server 启动并暴露自己的能力例如一个get_weather工具。Client如 Claude Desktop与 Server 建立连接进行能力协商。用户在对话中提出请求Claude 判断需要使用某个工具。Client 向 Server 发送tools/call请求携带工具名和参数。Server 执行逻辑调用 API、查询数据库、运行脚本等并将结果返回。Claude 将结果自然整合到回答中呈现给用户。整个过程对用户透明仿佛 Claude 天生就拥有这些能力。三个核心元素工具Tools模型可以调用的函数。每个工具包含名称、描述、输入参数的 JSON Schema。资源Resources模型可以直接读取的数据如文件内容、数据库记录。提示Prompts预定义的交互模板帮助用户快速发起特定类型的请求。本文我们聚焦在最常用、最灵活的自定义工具上构建一个 MCP Server为 Claude 提供实时天气查询能力。实战构建一个天气查询 MCP 工具我们将创建一个 Python MCP Server注册get_weather工具它会调用免费的 wttr.in API 获取指定城市的当前天气并返回格式化后的文本。随后我们配置 Claude Desktop 连接此 Server在对话中直接询问天气。环境准备本示例基于 Python 3.10 和官方 MCP Python SDK。首先安装依赖pip install mcp[cli] httpxmcp[cli]包含 MCP Server/Client 的基础库及命令行调试工具。httpx异步 HTTP 客户端用于请求天气 API。编写 MCP Server 代码新建文件weather_server.py内容如下import json import httpx from mcp.server import Server, NotificationOptions from mcp.server.models import InitializationCapabilities from mcp.server.stdio import stdio_server from mcp.types import Tool, TextContent # 创建 MCP Server 实例 server Server(weather-server) # 定义工具的具体实现 async def handle_get_weather(city: str) - str: 实际调用 wttr.in API获取指定城市的天气信息。 返回简洁的文本描述便于 Claude 理解。 # wttr.in 提供多种格式这里使用 JSON 格式避免解析 HTML url fhttps://wttr.in/{city}?formatj1 async with httpx.AsyncClient() as client: resp await client.get(url) resp.raise_for_status() data resp.json() # 提取当前天气数据 current data[current_condition][0] weather_desc current[weatherDesc][0][value] temp_c current[temp_C] humidity current[humidity] feels_like current[FeelsLikeC] return ( f{city} 当前天气{weather_desc}\n f气温{temp_c}°C体感 {feels_like}°C\n f湿度{humidity}% ) # 注册工具定义名称、描述、参数 schema server.list_tools() async def list_tools() - list[Tool]: return [ Tool( nameget_weather, description查询指定城市的实时天气信息包括天气状况、气温、湿度等。, inputSchema{ type: object, properties: { city: { type: string, description: 城市名称例如 Beijing, London, Tokyo } }, required: [city] } ) ] # 处理工具调用请求 server.call_tool() async def call_tool(name: str, arguments: dict) - list[TextContent]: if name get_weather: city arguments.get(city, ) if not city: raise ValueError(city 参数不能为空) result_text await handle_get_weather(city) return [TextContent(typetext, textresult_text)] else: raise ValueError(f未知工具: {name}) # 主函数启动 stdio 传输的 Server async def main(): async with stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationCapabilities( sampling{}, # 不需要采样能力 experimental{}, ), notification_optionsNotificationOptions(), ) if __name__ __main__: import asyncio asyncio.run(main())这段代码清晰地体现了 MCP Server 的三个关键部分工具清单 (list_tools)向客户端声明服务器提供了哪些工具以及每个工具的参数格式JSON Schema。Claude 会根据这里的描述在对话中准确理解工具的用途和调用方式。工具执行 (call_tool)当客户端请求调用某个工具时该函数被触发负责解析参数、执行实际业务逻辑此处为 HTTP 请求并返回TextContent类型的结果。传输层我们使用stdio即标准输入输出这是 MCP 本地使用最方便的方式无需开放网络端口。本地测试工具在正式接入 Claude 前我们可以用mcp dev命令快速测试工具是否正常工作mcp dev weather_server.py这会启动一个交互式测试环境你可以模拟客户端调用 tools/call get_weather {city:Beijing}如果一切正常你会看到类似输出Beijing 当前天气Sunny 气温22°C体感 21°C 湿度35%配置 Claude Desktop 使用自定义工具假设你已安装 Claude Desktop。我们需要编辑其配置文件告诉它启动我们刚刚编写的 MCP Server。找到配置文件- macOS:~/Library/Application Support/Claude/claude_desktop_config.json- Windows:%APPDATA%\Claude\claude_desktop_config.json如果文件不存在可以手动创建。添加 MCP Server 配置{ mcpServers: { weather-server: { command: python, args: [/absolute/path/to/weather_server.py], env: {} } } }请将路径替换为你的weather_server.py的绝对路径。如果你使用的是虚拟环境记得将command设为虚拟环境中的 python 解释器路径。重启 Claude Desktop完全退出后重新打开Claude 会自动连接配置的 MCP Server。验证连接点击输入框旁的工具图标你应该能看到weather-server及其下的get_weather工具说明集成成功。在对话中使用天气工具现在你可以直接向 Claude 提问北京今天天气怎么样Claude 会判断需要调用get_weather工具自动发送城市名“Beijing”获取结果后组织回答北京当前天气晴气温 22°C体感 21°C湿度 35%。今天天气不错适合户外活动哦整个过程完全在对话中完成你再也不需要手动查询天气并粘贴结果了。增强实战集成更多工具了解了基础流程后你可以轻松扩展服务器添加更多工具。例如我们再加一个简单的“日期计算”工具帮助 Claude 回答“100天后是几号”这类问题。只需在list_tools和call_tool中添加新条目# 在 list_tools 中追加 Tool( nameadd_days_to_today, description计算从今天起若干天后的日期返回 YYYY-MM-DD 格式。, inputSchema{ type: object, properties: { days: {type: integer, description: 增加的天数} }, required: [days] } ) # 在 call_tool 中添加处理分支 from datetime import date, timedelta elif name add_days_to_today: days int(arguments[days]) future date.today() timedelta(daysdays) result_text future.isoformat() return [TextContent(typetext, textresult_text)]更新服务配置重启 Claude Desktop 后它就能同时使用天气和日期计算工具组合完成任务。常见问题与注意事项1. 安全性谁可以调用我的工具MCP 工具运行在本地使用 stdio 传输时只有本机进程可以访问相对安全。但如果 Server 通过 HTTP 暴露务必加上鉴权目前社区方案使用 OAuth 或 API Key。切勿在工具中直接执行未经校验的用户输入避免命令注入。对于敏感操作如数据库写入建议在工具内部做二次确认或限制。2. 调试工具无响应确认weather_server.py能独立运行没有 import 错误。使用mcp dev weather_server.py单独测试查看错误堆栈。检查配置文件路径、python 命令是否正确。在终端中手动执行命令确认可以启动。Claude Desktop 的日志位于~/Library/Logs/Claude/macOS可作为排查线索。3. 工具返回的内容 Claude 不识别MCP 工具应返回清晰的文本描述或者符合TextContent的结构。如果返回的是复杂 JSONClaude 也可能处理但最好在工具描述中说明返回格式。另外避免过长的文本必要时截断或分页。4. 异步与性能本示例使用了httpx.AsyncClient和异步 Server这是推荐的模式。如果你的工具涉及 I/O 密集操作务必使用异步库防止阻塞整个 Server。对于 CPU 密集型任务可考虑放入线程池执行。5. 工具过多时的命名冲突不同 MCP Server 可以注册同名工具吗可以但用户在 Claude Desktop 中会看到两个来源的工具选择时容易混淆。建议为功能明确的 Server 起一个独立的名称工具名保持简洁且语义唯一。总结通过本文你不仅理解了 MCP 的设计理念还亲手打造了一个实时天气查询工具并成功将其接入 Claude Desktop。整个流程无需复杂的前端、鉴权只需几十行 Python 代码就让大模型与真实世界的数据流动了起来。MCP 的出现极大地降低了 AI 集成的门槛未来我们可以预见会有越来越多的工具服务器涌现形成繁荣的生态。无论你是想连接企业内部 API、自动化日常任务还是搭建个人知识库MCP Claude 的组合都提供了一个强大且灵活的解决方案。现在就动手把你重复性的提问变成工具让 Claude 成为你真正的智能助手吧扩展阅读与资源- MCP 官方文档- MCP Python SDK- wttr.in 天气 API 文档