人人都会AI编程

3.7.2 MCP 协议与外部工具接入

更新时间:2026-06-29

MCP(Model Context Protocol,模型上下文协议)是一种开放协议,用于在 AI 应用与外部工具、数据源之间建立标准化的连接。它让大模型能够安全、可控地调用本地或远程工具,比如查询数据库、操作文件、调用 API 等,而不需要为每个工具单独编写适配代码。

为什么需要 MCP

在没有统一协议时,接入外部工具往往需要:

  • 为每个工具编写自定义集成逻辑;
  • 处理不同的认证方式、数据格式和错误机制;
  • 手动管理上下文和对话中的工具调用状态。

MCP 提供了一种 客户端-服务器 架构,将工具的实现(MCP Server)与 AI 应用的调用逻辑(MCP Client)解耦,就像 USB 协议统一了外设连接一样。

MCP 的核心概念

  • MCP Server:以标准方式暴露一组工具(Tools)、资源(Resources)和提示(Prompts)。一个服务端可以是一个本地进程,也可以是远程服务。
  • MCP Client:通常是 AI 应用(如聊天界面、IDE 插件),通过 MCP 协议发现并调用服务端提供的功能。
  • 工具(Tool):可被模型调用的函数,有明确的输入/输出 schema。
  • 资源(Resource):模型可读取的上下文数据,例如文件内容、数据库记录。
  • 传输层:支持 stdio(标准输入输出)和 HTTP+SSE 两种传输方式。本地工具常用 stdio,远程工具可用 HTTP。

快速上手:搭建一个天气查询 MCP 服务器

下面用一个简单的天气工具示例,演示如何使用 Python 编写 MCP Server,并在客户端调用它。

1. 安装 MCP SDK

pip install mcp

2. 编写 MCP Server(weather_server.py)

from mcp.server import Server, Tool
from mcp.server.stdio import stdio_server
import httpx

# 创建服务器实例
server = Server("weather-server")

# 定义一个工具:查询城市天气
@server.tool()
async def get_weather(city: str) -> str:
    """查询指定城市的天气信息"""
    # 这里用公开 API 模拟(需要替换为真实 API)
    async with httpx.AsyncClient() as client:
        resp = await client.get(f"https://wttr.in/{city}?format=3")
        return resp.text

# 启动 stdio 传输
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

3. 在客户端中接入工具(使用 Claude Desktop 或自定义 Client)

以 Claude Desktop 为例,只需在配置文件中添加:

{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["weather_server.py"]
    }
  }
}

重启 Claude Desktop 后,你就能在对话中直接说「查一下北京的天气」,模型会自动调用 get_weather 工具获取结果并回复。

4. 自定义 MCP Client 示例

如果你想在自己的应用里调用 MCP 工具,可以用以下代码:

from mcp.client import Client
from mcp.client.stdio import stdio_client

async def run():
    async with stdio_client("python weather_server.py") as (read, write):
        async with Client(read, write) as client:
            # 列出可用工具
            tools = await client.list_tools()
            print("可用工具:", [t.name for t in tools])

            # 调用工具
            result = await client.call_tool("get_weather", {"city": "上海"})
            print(result.content[0].text)

import asyncio
asyncio.run(run())

实际开发中的注意事项

  • 安全性:工具调用会直接影响系统,务必验证参数、限制权限,避免注入风险。
  • 错误处理:工具应返回明确的结构化错误信息,方便模型理解并重试。
  • 性能:本地 stdio 传输延迟低,适合单机工具;远程 HTTP 传输适合微服务架构,但需注意网络开销。
  • 工具描述:给工具提供清晰的 docstring 和参数说明,能显著提高模型调用准确率。
  • 调试:可以使用 MCP Inspector(npx @modelcontextprotocol/inspector)可视化查看工具列表和调用结果,加速开发。

小结

MCP 协议将外部工具的接入从“每个工具写一份胶水代码”简化为定义标准接口。你只需实现一个 MCP Server 暴露工具,AI 应用就能自动发现并使用它们。这大大降低了智能体与现实世界交互的门槛,也让工具生态更容易复用和共享。