MCP 简介
什么是 MCP
MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 公司开发的一种开放协议,用于标准化 AI 模型与外部数据源、工具之间的通信方式。
MCP 的核心目标是让 AI 助手能够:
-
访问外部数据和资源
-
执行各种工具和操作
-
使用预定义的提示词模板
MCP 架构
MCP 采用客户端-服务器架构:
-
MCP 客户端:AI 应用(如 Claude Desktop、Kiro IDE)
-
MCP 服务器:提供工具、资源、提示词的服务
-
通信协议:基于 JSON-RPC 2.0,支持 stdio 和 HTTP 传输
环境搭建
创建 Conda 环境
# 创建专用环境
conda create -n mcp-server python=3.11
# 激活环境
conda activate mcp-server
# 安装 MCP SDK
pip install mcp
项目结构
推荐的项目目录结构:
mcp-project/
src/
my_mcp_server/
__init__.py
server.py # MCP 服务主文件
pyproject.toml # 项目配置
README.md
pyproject.toml 配置
[project]
name = "my-mcp-server"
version = "0.1.0"
dependencies = ["mcp"]
[project.scripts]
my-mcp-server = "my_mcp_server.server:main"
MCP 核心概念
MCP 提供三种核心能力:
Tool(工具)
Tool 让 AI 可以执行操作,类似于函数调用。
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("我的服务")
@mcp.tool()
def add(a: int, b: int) -> int:
"""
计算两个数字的和
Args:
a: 第一个数字
b: 第二个数字
Returns:
两数之和
"""
return a + b
@mcp.tool()
def greet(name: str) -> str:
"""向用户打招呼"""
return f"你好,{name}!"
关键点:
-
使用
@mcp.tool()装饰器 -
必须有完整的 docstring(AI 依赖它理解工具用途)
-
参数需要类型注解
Resource(资源)
Resource 让 AI 可以读取数据,通过 URI 访问。
# 静态资源
@mcp.resource("config://app-settings")
def get_app_settings() -> str:
"""获取应用配置"""
return "应用名称: 我的服务\n版本: 0.1.0"
# 动态资源(带参数)
@mcp.resource("file:///{path}")
def read_file(path: str) -> str:
"""读取指定文件"""
with open(path, 'r', encoding='utf-8') as f:
return f.read()
URI 格式:
-
静态:
config://app-settings -
动态模板:
file:///{path}
Prompt(提示词模板)
Prompt 提供预定义的提示词,帮助 AI 执行特定任务。
@mcp.prompt()
def code_review(code: str) -> str:
"""代码审查提示词"""
return f"""请审查以下代码:
{code}
请从以下方面审查:
1. 代码逻辑是否正确
2. 是否有潜在的 bug
3. 代码风格和可读性
4. 性能优化建议
"""
实战:数据库查询工具
初始化数据库
# init_db.py
import sqlite3
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
city TEXT
)
''')
# 插入测试数据
cursor.execute("INSERT INTO users (name, age, city) VALUES (?, ?, ?)",
("张三", 25, "北京"))
cursor.execute("INSERT INTO users (name, age, city) VALUES (?, ?, ?)",
("李四", 30, "上海"))
conn.commit()
conn.close()
数据库查询工具
import sqlite3
# 注意:使用绝对路径
DB_PATH = r'D:\桌面\mcp\test.db'
@mcp.tool()
def query_users() -> str:
"""查询所有用户"""
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()
conn.close()
output = "ID | 姓名 | 年龄 | 城市\n"
for row in results:
output += f"{row[0]} | {row[1]} | {row[2]} | {row[3]}\n"
return output
@mcp.tool()
def add_user(name: str, age: int, city: str) -> str:
"""添加新用户"""
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute(
"INSERT INTO users (name, age, city) VALUES (?, ?, ?)",
(name, age, city)
)
conn.commit()
conn.close()
return f"添加用户 {name} 成功"
重要提示:数据库路径必须使用绝对路径,因为 MCP 服务的工作目录可能与项目目录不同。
测试与调试
使用 MCP Inspector
MCP Inspector 是官方提供的测试工具:
# 安装
npm install -g @anthropic/mcp-inspector
# 启动测试
npx @anthropic/mcp-inspector uv run my-mcp-server
在 Inspector 中可以:
-
查看所有注册的 Tools、Resources、Prompts
-
手动调用工具并查看返回结果
-
调试参数传递和错误信息
集成到 Kiro IDE
在 .kiro/settings/mcp.json 中配置:
{
"mcpServers": {
"my-learning-server": {
"command": "uv",
"args": [
"--directory",
"D:\\桌面\\mcp",
"run",
"my-mcp-server"
]
}
}
}
最佳实践
工具设计原则
-
单一职责:每个工具只做一件事
-
清晰命名:工具名称要能表达其功能
-
完整文档:docstring 要详细,包含使用场景和参数说明
-
错误处理:妥善处理异常,返回有意义的错误信息
-
类型注解:所有参数和返回值都要有类型注解
常见问题
| 问题 | 解决方案 |
|---|---|
| 数据库找不到 | 使用绝对路径 |
| 工具不显示 | 检查 docstring 是否完整 |
| 参数传递错误 | 检查类型注解是否正确 |
| 服务无法启动 | 检查 pyproject.toml 配置 |
常见问题及解决方案
Sampling(采样)
什么是 Sampling
Sampling 是 MCP 的高级特性,允许 MCP 服务反向调用 AI 生成内容。
-
普通模式:AI (\rightarrow) 调用 (\rightarrow) MCP 服务 (\rightarrow) 返回结果
-
Sampling:MCP 服务 (\rightarrow) 请求 AI 生成 (\rightarrow) AI 返回内容 (\rightarrow) 服务继续处理
使用场景
-
工具执行过程中需要 AI 帮忙分析/总结
-
自动生成代码注释、文档
-
多步骤任务中让 AI 做中间决策
-
数据处理后让 AI 生成报告
核心 API
from mcp.server.fastmcp import FastMCP, Context
mcp = FastMCP("我的服务")
@mcp.tool()
async def analyze_data(data: str, ctx: Context) -> str:
"""需要 AI 帮助分析的工具"""
# 调用 AI 生成内容
result = await ctx.sample(
messages=[
{
"role": "user",
"content": f"请分析这个数据:{data}"
}
],
system_prompt="你是数据分析专家",
max_tokens=500
)
return f"AI 分析结果:{result}"
关键点:
-
必须是
async函数 -
需要
ctx: Context参数 -
使用
await ctx.sample()调用 AI -
需要客户端支持 Sampling 功能
外部 API 集成
为什么集成外部 API
让 AI 能够:
-
获取实时数据(天气、新闻、股票)
-
调用第三方服务(翻译、搜索)
-
操作外部系统(GitHub、Notion)
使用 httpx 调用 API
import httpx
@mcp.tool()
async def get_weather(city: str) -> str:
"""
查询城市天气
Args:
city: 城市名称
"""
try:
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(
f"https://wttr.in/{city}",
params={"format": "j1"}
)
data = response.json()
current = data["current_condition"][0]
return f"""
城市:{city}
温度:{current['temp_C']}°C
天气:{current['weatherDesc'][0]['value']}
湿度:{current['humidity']}%
"""
except httpx.TimeoutException:
return "查询超时"
except Exception as e:
return f"查询出错:{str(e)}"
封装现有后端 API
如果已有后端服务,可以直接封装成 MCP 工具:
BASE_URL = "http://localhost:8000"
@mcp.tool()
async def api_get_users() -> str:
"""获取所有用户"""
async with httpx.AsyncClient() as client:
response = await client.get(f"{BASE_URL}/api/users")
return str(response.json())
@mcp.tool()
async def api_create_user(name: str, age: int) -> str:
"""创建用户"""
async with httpx.AsyncClient() as client:
response = await client.post(
f"{BASE_URL}/api/users",
json={"name": name, "age": age}
)
return str(response.json())
批量注册 API 工具
当有多个相似的 API 需要封装时,可以使用工厂函数批量注册:
import httpx
BASE_URL = "http://localhost:8000"
# API 配置表
API_ENDPOINTS = [
{"name": "get_users", "method": "GET", "path": "/api/users", "desc": "获取所有用户"},
{"name": "get_orders", "method": "GET", "path": "/api/orders", "desc": "获取所有订单"},
{"name": "get_products", "method": "GET", "path": "/api/products", "desc": "获取所有产品"},
]
def create_api_tool(endpoint):
"""工厂函数:为每个 API 创建工具"""
async def tool_func() -> str:
async with httpx.AsyncClient() as client:
if endpoint["method"] == "GET":
response = await client.get(f"{BASE_URL}{endpoint['path']}")
return str(response.json())
tool_func.__name__ = endpoint["name"]
tool_func.__doc__ = endpoint["desc"]
return tool_func
# 批量注册 MCP 工具
for ep in API_ENDPOINTS:
mcp.add_tool(create_api_tool(ep))
优点:
-
减少重复代码
-
统一管理 API 配置
-
方便批量添加/修改接口
HTTP 传输模式
两种传输模式
MCP 支持两种通信方式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
| stdio | 标准输入输出 | 本地运行,Kiro/Claude Desktop |
| HTTP (SSE) | 网络请求 | 远程服务、多客户端 |
stdio 模式
客户端启动 MCP 服务作为子进程,通过标准输入输出通信,只能本地使用。
if __name__ == "__main__":
mcp.run() # 默认 stdio 模式
HTTP 模式
MCP 服务作为独立 HTTP 服务器运行,支持远程访问和多客户端连接。
if __name__ == "__main__":
# HTTP 模式
mcp.run(transport="sse", host="0.0.0.0", port=8080)
客户端连接 HTTP MCP
{
"mcpServers": {
"my-http-server": {
"url": "http://localhost:8080/sse"
}
}
}
多 MCP 服务协作
什么是多服务协作
一个 AI 客户端可以同时连接多个 MCP 服务,每个服务负责不同领域:
AI 客户端
|
+-- 数据库服务(query_users, add_user)
+-- 文件服务(read_file, write_file)
+-- API 服务(get_weather, translate)
配置多个服务
{
"mcpServers": {
"database-server": {
"command": "uv",
"args": ["--directory", "D:\\db-mcp", "run", "db-server"]
},
"file-server": {
"command": "uv",
"args": ["--directory", "D:\\file-mcp", "run", "file-server"]
}
}
}
拆分建议
| 服务类型 | 包含工具 |
|---|---|
| 数据库服务 | 增删改查、SQL 执行 |
| 文件服务 | 读写文件、格式转换 |
| API 服务 | 调用外部 API |
| 文档服务 | 生成 Word、PPT、PDF |
| 浏览器服务 | 网页操作、截图 |
封装 Python 函数为 MCP 工具
直接封装
已有的 Python 函数可以直接加装饰器封装:
# 原函数
def calculate_similarity(text1: str, text2: str) -> float:
common = set(text1) & set(text2)
return len(common) / max(len(set(text1)), len(set(text2)))
# 封装成 MCP 工具
@mcp.tool()
def calculate_similarity(text1: str, text2: str) -> str:
"""
计算两段文本的相似度
Args:
text1: 第一段文本
text2: 第二段文本
"""
common = set(text1) & set(text2)
score = len(common) / max(len(set(text1)), len(set(text2)))
return f"相似度:{score:.2%}"
包装已有函数
不修改原函数,写包装函数:
# 原算法函数(不动)
def my_algorithm(data: list) -> dict:
return {"sum": sum(data), "avg": sum(data)/len(data)}
# 包装成 MCP 工具
@mcp.tool()
def run_algorithm(numbers: str) -> str:
"""
运行算法分析
Args:
numbers: 逗号分隔的数字,如 "1,2,3,4,5"
"""
data = [float(x.strip()) for x in numbers.split(",")]
result = my_algorithm(data)
return f"总和:{result['sum']}\n平均值:{result['avg']:.2f}"
关键点:
-
MCP 工具参数必须是基本类型(str, int, float, bool)
-
返回值建议是 str(方便 AI 理解)
-
docstring 必须写清楚
附录:HTTP 方法速查
| 方法 | 作用 | 对应操作 | 有请求体 |
|---|---|---|---|
| GET | 获取数据 | Read(查询) | 无 |
| POST | 创建数据 | Create(新增) | 有 |
| PUT | 更新数据 | Update(修改) | 有 |
| DELETE | 删除数据 | Delete(删除) | 通常无 |
HTTP 方法对照表
记忆口诀:GET 查,POST 增,PUT 改,DELETE 删
后续学习方向
-
将 Claude Skills 转换为 MCP 工具
-
开发更复杂的 MCP 服务(如文件处理、图像处理)
-
探索 MCP 在实际项目中的应用
-
学习 MCP 服务的发布和部署
-
研究 MCP 与其他 AI 框架的集成