# MCP 协议入门:构建可被 LLM 调用的工具
前言
随着大语言模型(LLM)在各行业的广泛应用,如何让 AI 助手安全、高效地调用外部工具和数据源成为关键挑战。**Model Context Protocol(MCP)** 是由 Anthropic 提出的开放标准协议,旨在为 LLM 与外部世界之间建立统一的通信桥梁。本文将带你深入了解 MCP 的核心架构,并手把手教你构建一个可被 LLM 调用的 MCP 服务器。
---
什么是 MCP?
MCP(Model Context Protocol)是一种开放协议,它定义了 LLM 与外部工具、数据源之间的标准通信方式。在 MCP 出现之前,每种 AI 应用都需要为不同的工具编写定制化的集成代码,导致:
MCP 的出现解决了这些问题,通过统一的协议标准,开发者只需实现一次工具接口,即可让任何兼容 MCP 的 LLM 调用。
MCP 的核心价值
| 特性 | 说明 |
|------|------|
| **标准化** | 统一的工具定义与调用规范 |
| **可扩展** | 支持任意数量的工具和数据源 |
| **安全隔离** | 工具运行在独立进程中,权限可控 |
| **跨平台** | 支持多种编程语言和运行环境 |
---
MCP 架构概览
MCP 采用**客户端-服务器架构**,主要包含以下组件:
核心组件
┌─────────────────────────────────────────────────────┐
│ LLM 模型 │
└─────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ MCP Host │
│ (如 Claude Desktop、AI 应用等) │
└─────────────────────┬───────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ MCP │ │ MCP │ │ MCP │
│ Server │ │ Server │ │ Server │
│ (工具A) │ │ (工具B) │ │ (工具C) │
└────────┘ └────────┘ └────────┘
1. **MCP Host**:运行 LLM 的主机环境(如 Claude Desktop)
2. **MCP Client**:嵌入在 Host 中的客户端,负责与服务器通信
3. **MCP Server**:独立的服务器进程,实现具体工具功能
通信协议
MCP 基于 **JSON-RPC 2.0** 协议进行通信,支持两种传输方式:
---
快速开始:创建 MCP 服务器
下面以 Python 为例,实现一个简单的 MCP 服务器。
环境准备
# 安装 MCP SDK
pip install mcp
# 或使用 uv(推荐)
uv pip install mcp
基础服务器实现
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
from pydantic import AnyUrl
# 创建服务器实例
server = Server("my-first-mcp-server")
@server.list_tools()
async def list_tools() -> list[Tool]:
"""声明服务器提供的所有工具"""
return [
Tool(
name="get_weather",
description="获取指定城市的天气信息",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称(中文或英文)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"default": "celsius",
"description": "温度单位"
}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
"""处理工具调用请求"""
if name == "get_weather":
city = arguments.get("city")
unit = arguments.get("unit", "celsius")
# 这里替换为真实的天气 API 调用
weather_data = {
"北京": {"temp": 22, "condition": "晴朗"},
"上海": {"temp": 25, "condition": "多云"},
}
if city in weather_data:
data = weather_data[city]
temp = data["temp"]
if unit == "fahrenheit":
temp = temp * 9/5 + 32
return [TextContent(
type="text",
text=f"{city}当前天气:{data['condition']},温度 {temp}°{'F' if unit == 'fahrenheit' else 'C'}"
)]
else:
return [TextContent(
type="text",
text=f"未找到城市 {city} 的天气数据"
)]
raise ValueError(f"未知工具: {name}")
async def main():
"""启动服务器"""
async with stdio_server() as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ ==