MCP 工具使用教程
MCP (Model Context Protocol) 让 AI 能够使用外部工具,极大扩展了 Agent 的能力。本教程详细讲解如何使用和配置 MCP 工具。
MCP 是什么?
MCP 是 Anthropic 提出的标准化协议,让 AI 模型能够安全地调用外部工具和服务。
User: "查询 React 19 的新特性"
↓
Agent 识别需要使用工具
↓
调用 MCP Tool: Context7
↓
Context7 查询最新文档
↓
返回结果给 Agent
↓
Agent 整理并回复用户核心概念
Tool(工具):
- 定义:具有特定功能的外部服务
- 能力:搜索、数据查询、API 调用、文档检索等
- 标准:遵循 MCP 协议规范
Tool Call(工具调用):
- Agent 决定何时调用工具
- 构造工具调用参数
- 处理工具返回结果
Tool Server(工具服务器):
- 提供 MCP 工具的服务端
- 处理工具调用请求
- 返回执行结果
预置工具
Sira AI 内置了常用的 MCP 工具,开箱即用。
Context7 - 技术文档查询
功能
查询最新的技术文档和 API 参考。
支持的库:
- React, Vue, Angular, Svelte
- Next.js, Nuxt, SvelteKit
- Node.js, Python, Go
- MongoDB, PostgreSQL, Redis
- Docker, Kubernetes
- 数千个主流开源项目
使用场景
yaml
✅ 适用:
- 查询最新技术文档
- 获取 API 使用示例
- 了解框架最佳实践
- 对比不同版本差异
❌ 不适用:
- 实时新闻
- 社交媒体内容
- 未收录的小众库启用 Context7
步骤 1:查看工具状态
- 进入 MCP Tools
- 找到 Context7
- 查看状态:已启用/未启用
步骤 2:启用工具(如未启用)
- 点击 Context7 卡片
- 查看配置信息:yaml
名称: context7 类型: MCP Tool Transport: streamable_http URL: https://mcp.context7.com/mcp - 点击 启用
步骤 3:为 Agent 配置工具
- 进入 Agent System → Agents
- 编辑 Agent
- 在 MCP 工具 部分勾选 Context7
- 保存
使用示例
示例 1:查询 API 文档
User: "如何使用 Next.js 14 的 Server Actions?"
Agent 思考:
这是技术问题,需要查询最新文档
Agent 调用 Context7:
library: "nextjs"
topic: "server actions"
Context7 返回:
《Next.js 14 Server Actions 使用指南》
- 定义 Server Action
- 使用 'use server' 指令
- 表单提交示例...
Agent 回复:
根据 Next.js 14 最新文档,Server Actions 的使用方法如下:
[基于 Context7 返回的内容整理回复]示例 2:代码示例查询
User: "给我一个 React useState 的示例"
Agent 调用 Context7:
library: "react"
topic: "useState hook"
Context7 返回:
```jsx
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}Agent 回复: 这是一个 React useState 的示例: [返回代码并解释]
### WebSearch - 网页搜索
#### 功能
搜索互联网内容,获取实时信息。
**搜索范围**:
- 新闻资讯
- 技术博客
- 产品官网
- 社区讨论
- 学术论文
#### 使用场景
```yaml
✅ 适用:
- 实时新闻和热点
- 产品价格和评测
- 公司信息查询
- 活动和会议信息
❌ 不适用:
- 需要认证的私有内容
- 深度网页(Paywall)
- 实时股票价格(用专门API)启用和使用
同 Context7,启用后为 Agent 配置即可。
使用示例
User: "苹果最新发布会有哪些产品?"
Agent 调用 WebSearch:
query: "苹果 2024 最新发布会 产品"
WebSearch 返回:
[搜索结果]
1. iPhone 16 Pro 发布 - Apple官网
2. 苹果秋季发布会:iPhone 16、Apple Watch... - 科技媒体
...
Agent 回复:
根据最新资讯,苹果在2024年发布会上发布了:
1. iPhone 16 系列...
2. Apple Watch Series 10...
...Weather - 天气查询
功能
查询全球城市的天气信息。
支持查询:
- 当前天气
- 未来7天预报
- 温度、湿度、风力
- 空气质量
使用示例
User: "北京今天天气怎么样?"
Agent 调用 Weather:
city: "北京"
date: "today"
Weather 返回:
{
"temperature": 25,
"condition": "晴",
"humidity": 40,
"wind": "东北风3级"
}
Agent 回复:
北京今天晴天,温度25°C,湿度40%,东北风3级。适合户外活动。为 Agent 配置工具
配置步骤
步骤 1:选择合适的工具
根据 Agent 的职责选择工具:
yaml
技术助手:
工具: [Context7, WebSearch]
理由: 需要查询技术文档和最新资讯
天气助手:
工具: [Weather]
理由: 只需要天气查询
通用助手:
工具: [Context7, WebSearch, Weather]
理由: 需要全面的信息查询能力
客服助手:
工具: [] # 无工具
理由: 基于知识库回答,不需要外部工具步骤 2:在 Agent 中配置
- 进入 Agent System → Agents
- 点击要配置的 Agent 的 编辑 按钮
- 找到 MCP 工具 部分
- 勾选需要的工具:
- [ ] Context7
- [ ] WebSearch
- [ ] Weather
- 点击 保存
步骤 3:优化提示词
在系统提示词中说明工具的使用规则:
你是技术文档助手,专注于回答技术问题。
【可用工具】
- Context7:查询最新技术文档和 API 参考
- WebSearch:搜索互联网内容和最新资讯
【工具使用规则】
1. 技术问题优先使用 Context7
2. 新闻资讯使用 WebSearch
3. 如果 Context7 找不到结果,可以尝试 WebSearch
4. 不要在没有必要时调用工具
【示例】
用户: "React 19 有什么新特性?"
操作: 使用 Context7 查询 React 19 文档
用户: "React 19 什么时候发布的?"
操作: 使用 WebSearch 查询发布时间
用户: "你好"
操作: 直接回复,无需调用工具工具调用流程
yaml
1. Agent 收到用户消息
2. Agent 判断是否需要使用工具
↓ 是
3. Agent 选择合适的工具
4. Agent 构造工具调用参数
5. 系统调用 MCP Tool
6. Tool 返回结果
7. Agent 基于结果生成回复
↓ 否
8. Agent 直接基于知识回复测试工具调用
方法 1:直接对话测试
创建 Application → 测试对话:
yaml
测试用例 1:
输入: "查询 Next.js 15 的新特性"
期望: Agent 调用 Context7
验证: 查看回复是否包含最新文档内容
测试用例 2:
输入: "今天天气如何?"
期望: Agent 调用 Weather
验证: 回复包含温度、天气状况
测试用例 3:
输入: "你好"
期望: Agent 不调用工具
验证: 直接回复问候方法 2:查看日志
bash
# 查看工具调用日志
docker logs backend | grep "tool_call"
# 示例日志
[INFO] Agent决定调用工具: context7
[INFO] 工具参数: {"library": "nextjs", "topic": "server actions"}
[INFO] 工具返回: 成功,3000 tokens
[INFO] Agent生成回复: 完成自定义 MCP 工具
创建自定义工具
场景:企业内部数据库查询工具
需求:
- Agent 需要查询企业内部销售数据
- 提供 SQL 查询能力
- 返回格式化数据
步骤 1:准备 MCP Server
使用 FastMCP 创建工具服务器:
python
# mcp_server/sales_query_server.py
from fastmcp import FastMCP
import mysql.connector
mcp = FastMCP("Sales Query Server")
@mcp.tool()
async def query_sales(
date_range: str,
product_id: str = None
) -> str:
"""查询销售数据
Args:
date_range: 日期范围,格式:YYYY-MM-DD to YYYY-MM-DD
product_id: 产品ID(可选),查询特定产品
Returns:
销售数据的 JSON 字符串
"""
# 连接数据库
conn = mysql.connector.connect(
host="localhost",
user="readonly_user",
password="xxx",
database="sales_db"
)
cursor = conn.cursor(dictionary=True)
# 解析日期范围
start_date, end_date = date_range.split(" to ")
# 构造SQL
if product_id:
sql = """
SELECT product_id, SUM(amount) as total_sales, COUNT(*) as order_count
FROM orders
WHERE date BETWEEN %s AND %s AND product_id = %s
GROUP BY product_id
"""
cursor.execute(sql, (start_date, end_date, product_id))
else:
sql = """
SELECT product_id, SUM(amount) as total_sales, COUNT(*) as order_count
FROM orders
WHERE date BETWEEN %s AND %s
GROUP BY product_id
ORDER BY total_sales DESC
LIMIT 10
"""
cursor.execute(sql, (start_date, end_date))
results = cursor.fetchall()
cursor.close()
conn.close()
return json.dumps(results, ensure_ascii=False)
if __name__ == "__main__":
mcp.run()步骤 2:部署 MCP Server
bash
# 安装依赖
pip install fastmcp mysql-connector-python
# 运行服务器
python mcp_server/sales_query_server.py服务器运行在:http://localhost:8000/mcp
步骤 3:在 Sira AI 中注册工具
- 进入 MCP Tools
- 点击 创建 MCP Tool
- 填写配置:
yaml
名称: sales_query
显示名称: 销售数据查询
描述: 查询企业内部销售数据
工具类型: MCP
Source 配置:
Transport: streamable_http
URL: http://localhost:8000/mcp- 点击 测试连接 → 成功
- 点击 保存
步骤 4:为 Agent 配置工具
yaml
Agent: sales_analyst
系统提示词: |
你是销售数据分析专家。
【可用工具】
- sales_query: 查询销售数据
【使用示例】
用户: "查询本月销售数据"
操作: 调用 sales_query,date_range="2024-01-01 to 2024-01-31"
MCP 工具: [sales_query]步骤 5:测试
User: "查询1月份销售前10的产品"
Agent 调用 sales_query:
date_range: "2024-01-01 to 2024-01-31"
Tool 返回:
[
{"product_id": "P001", "total_sales": 500000, "order_count": 120},
{"product_id": "P002", "total_sales": 450000, "order_count": 95},
...
]
Agent 回复:
1月份销售TOP10产品如下:
1. 产品P001:销售额50万,订单120笔
2. 产品P002:销售额45万,订单95笔
...高级功能
工具组合使用
场景:技术研究助手
Agent 可以组合使用多个工具:
User: "对比 Next.js 和 Nuxt.js 的性能"
Step 1: Agent 调用 Context7 查询 Next.js 文档
→ 获取 Next.js 的性能特性
Step 2: Agent 调用 Context7 查询 Nuxt.js 文档
→ 获取 Nuxt.js 的性能特性
Step 3: Agent 调用 WebSearch 搜索性能对比文章
→ 获取社区的实际对比数据
Step 4: Agent 综合所有信息
→ 生成详细的对比分析工具链(Tool Chaining)
工具的输出可以作为下一个工具的输入:
User: "查询北京的天气,然后推荐适合的户外活动"
Step 1: 调用 Weather 工具
输入: city="北京"
输出: {"temperature": 25, "condition": "晴"}
Step 2: 基于天气推荐活动
思考: 天气好,温度适宜
输出: 推荐爬山、骑行、野餐等户外活动条件工具调用
根据情况决定是否调用工具:
python
# Agent 的决策逻辑
用户问题: "React 是什么?"
→ 基础知识,无需调用工具,直接回答
用户问题: "React 19 有什么新特性?"
→ 需要最新信息,调用 Context7
用户问题: "React 19 什么时候发布的?"
→ 需要时间信息,调用 WebSearch工具调用重试
工具调用失败时的处理:
yaml
策略:
1. 自动重试(最多3次)
2. 换用其他工具(Context7失败 → WebSearch)
3. 降级回复(基于已有知识)
示例:
User: "查询 Next.js 15 新特性"
尝试 1: 调用 Context7 → 超时
尝试 2: 调用 Context7 → 失败
尝试 3: 调用 WebSearch → 成功
或者: 所有尝试失败 → 降级回复
"抱歉,目前无法查询最新信息,根据我所知的 Next.js 14 版本..."工具开发最佳实践
1. 工具设计原则
单一职责
yaml
✅ 好的设计:
Tool 1: query_weather (只查天气)
Tool 2: query_air_quality (只查空气质量)
❌ 不好的设计:
Tool: query_everything (天气+空气+紫外线+...)清晰的参数
python
# ✅ 好的参数设计
@mcp.tool()
async def query_sales(
start_date: str, # 明确的开始日期
end_date: str, # 明确的结束日期
product_id: str = None # 可选参数有默认值
) -> str:
"""查询销售数据
Args:
start_date: 开始日期,格式 YYYY-MM-DD
end_date: 结束日期,格式 YYYY-MM-DD
product_id: 产品ID(可选)
"""
pass
# ❌ 不好的参数设计
@mcp.tool()
async def query_sales(
params: dict # 模糊的参数
) -> str:
pass有意义的返回值
python
# ✅ 结构化的返回
return json.dumps({
"success": True,
"data": [...],
"count": 10,
"total": 1000
})
# ❌ 纯文本返回
return "找到10条记录,共1000条..."2. 错误处理
python
@mcp.tool()
async def query_database(sql: str) -> str:
try:
# 数据库查询
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
return json.dumps({
"success": True,
"data": results
})
except mysql.connector.Error as e:
# 数据库错误
return json.dumps({
"success": False,
"error": "数据库查询失败",
"details": str(e)
})
except Exception as e:
# 其他错误
return json.dumps({
"success": False,
"error": "未知错误",
"details": str(e)
})
finally:
# 清理资源
if cursor:
cursor.close()
if conn:
conn.close()3. 安全考虑
SQL 注入防护
python
# ✅ 使用参数化查询
cursor.execute(
"SELECT * FROM users WHERE id = %s",
(user_id,)
)
# ❌ 字符串拼接(易被注入)
cursor.execute(
f"SELECT * FROM users WHERE id = {user_id}"
)权限控制
python
@mcp.tool()
async def delete_data(table: str, id: int) -> str:
# 1. 验证权限
if not has_delete_permission(current_user):
return json.dumps({
"success": False,
"error": "权限不足"
})
# 2. 白名单检查
allowed_tables = ["temp_data", "cache_data"]
if table not in allowed_tables:
return json.dumps({
"success": False,
"error": "不允许删除该表"
})
# 3. 执行删除
...敏感信息保护
python
@mcp.tool()
async def query_user(user_id: str) -> str:
# 查询用户信息
user = db.query_user(user_id)
# ✅ 过滤敏感信息
safe_user = {
"id": user["id"],
"name": user["name"],
"email": mask_email(user["email"]), # 脱敏
# 不返回密码、手机号等敏感信息
}
return json.dumps(safe_user)4. 性能优化
缓存
python
from functools import lru_cache
@lru_cache(maxsize=100)
@mcp.tool()
async def query_static_data(category: str) -> str:
"""查询静态数据(带缓存)"""
# 静态数据变化不频繁,可以缓存
...超时控制
python
import asyncio
@mcp.tool()
async def query_external_api(url: str) -> str:
try:
# 设置10秒超时
async with asyncio.timeout(10):
response = await fetch(url)
return response.text
except asyncio.TimeoutError:
return json.dumps({
"success": False,
"error": "请求超时"
})连接池
python
from aiomysql import create_pool
# 全局连接池
db_pool = await create_pool(
host='localhost',
user='root',
password='xxx',
db='mydb',
minsize=5,
maxsize=20
)
@mcp.tool()
async def query_database(sql: str) -> str:
# 从连接池获取连接
async with db_pool.acquire() as conn:
async with conn.cursor() as cursor:
await cursor.execute(sql)
results = await cursor.fetchall()
return json.dumps(results)故障排查
工具无法调用
问题 1:工具未启用
症状:
- Agent 不调用工具
- 日志显示"工具不可用"
排查:
yaml
1. 检查 MCP Tools 页面,工具是否启用
2. 检查 Agent 配置,是否勾选了该工具
3. 重启 Agent System 服务问题 2:MCP Server 不可达
症状:
- 工具调用失败
- 日志显示"连接超时"或"连接拒绝"
排查:
bash
# 测试 MCP Server
curl http://localhost:8000/mcp
# 检查 MCP Server 进程
ps aux | grep mcp
# 查看 MCP Server 日志
tail -f mcp_server.log问题 3:参数错误
症状:
- 工具返回参数错误
- Agent 无法生成正确的参数
排查:
yaml
1. 检查工具的参数定义是否清晰
2. 在提示词中提供参数示例
3. 查看日志,确认 Agent 传递的参数工具返回异常
问题 1:超时
原因:
- 数据库查询慢
- 外部API响应慢
- 网络问题
解决:
python
# 增加超时时间
@mcp.tool()
async def slow_query(...):
async with asyncio.timeout(30): # 30秒超时
...问题 2:数据格式错误
原因:
- 返回的不是有效JSON
- 数据结构不一致
解决:
python
# 统一返回格式
def format_response(success: bool, data=None, error=None):
return json.dumps({
"success": success,
"data": data,
"error": error
}, ensure_ascii=False)
@mcp.tool()
async def my_tool(...) -> str:
try:
result = ...
return format_response(True, result)
except Exception as e:
return format_response(False, error=str(e))下一步
掌握 MCP 工具使用后,继续学习:
- 完整使用场景 - 端到端实战案例
- 自定义 MCP 工具开发 - 深入工具开发
- 日志查看 - 排查与审计
💡 提示:
- 合理选择工具,避免配置过多
- 工具调用有成本,优化 Agent 提示词减少不必要的调用
- 自定义工具时注意安全和性能
- 定期监控工具调用情况和失败率
