【个人主页:玄同765】
大语言模型(LLM)开发工程师 |中国传媒大学·数字媒体技术(智能交互与游戏设计)
**深耕领域:**大语言模型开发 / RAG知识库 / AI Agent落地 / 模型微调
**技术栈:**Python / LangChain/RAG(Dify+Redis+Milvus)| SQL/NumPy | FastAPI+Docker ️
**工程能力:**专注模型工程化部署、知识库构建与优化,擅长全流程解决方案
专栏传送门: LLM大模型开发 项目实战指南、Python 从真零基础到纯文本 LLM 全栈实战、从零学 SQL + 大模型应用落地、大模型开发小白专属:从 0 入门 Linux&Shell
「让AI交互更智能,让技术落地更高效」
欢迎技术探讨/项目合作! 关注我,解锁大模型与智能交互的无限可能!
在 AI 智能体时代,工具调用能力 是衡量智能体 "智商" 的核心标准 ------ 一个只会聊天的智能体价值有限,但能读取文档、操作数据库、调用 API 的智能体,才能真正成为开发者的 "全能助手"。而MCP(Model Context Protocol) 就是让智能体与外部工具顺畅沟通的 "通用语言"。
如果你之前用过mcp-docx-reader这类工具,肯定好奇它是怎么实现的。本文将从MCP 核心概念 、Python 开发实战 、智能体集成三个维度,带你亲手开发一个 MCP 工具,让你的 AI 智能体拥有读取 PDF 文档的 "超能力"。
一、先搞懂:什么是 MCP?
1. MCP 的本质:智能体与工具的 "通信协议"
MCP 是一套标准化的 AI 智能体 - 工具交互协议,它定义了智能体如何调用工具、工具如何返回结果的规范。简单来说:
- 智能体是 "用户",它通过 MCP 发送调用请求;
- MCP 工具是 "服务端",它接收请求、执行逻辑、返回结果;
- 协议本身是 "通信规则",确保不同厂商的智能体和工具能无缝对接。
2. MCP 的核心优势
相比直接写 API 接口,MCP 的优势在于:
- 跨平台兼容:支持 Trae IDE、LangChain Agent、LLaMAIndex 等主流智能体平台;
- 标准化格式:无需为每个智能体平台单独适配,一次开发多平台可用;
- 内置元数据:工具可返回参数描述、示例,智能体能自动理解工具功能;
- 错误处理规范:统一的错误格式,智能体能优雅处理异常。
3. MCP 的核心协议结构
MCP 基于 HTTP/JSON 通信,核心分为请求格式 和响应格式:
请求格式(智能体→工具)
{
"tool_name": "pdf_reader", // 要调用的工具名称
"parameters": { // 工具所需参数
"file_path": "./document.pdf",
"page_range": [1, 10]
}
}
响应格式(工具→智能体)
{
"result": { // 执行成功时返回的结果
"text": "文档第1-10页的内容...",
"page_count": 10
},
"error": null // 执行失败时返回错误信息
}
二、环境准备:Python 开发 MCP 的必备依赖
开发 MCP 工具需要以下环境和依赖:
- Python 版本:≥3.10(支持异步语法和新特性);
- Web 框架:FastAPI(异步优先,自动生成 OpenAPI 文档,适合写 MCP 接口);
- 数据校验:Pydantic(定义请求响应模型,自动校验参数);
- PDF 解析:PyPDF2 或 pdfplumber(用于实现 PDF 读取功能);
- 运行服务器:Uvicorn(FastAPI 的官方 ASGI 服务器)。
安装命令:
pip install fastapi pydantic uvicorn pdfplumber
三、实战 1:写第一个 MCP 服务器 ------ 计算器工具
先从最简单的计算器工具入手,熟悉 MCP 的开发流程:
1. 项目结构
mcp-calculator/
├── main.py # 主程序,包含MCP服务器和工具逻辑
└── requirements.txt # 依赖清单
2. 编写 MCP 服务器代码
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import Optional, Dict, Any
# 1. 初始化FastAPI应用
app = FastAPI(title="MCP计算器工具", version="1.0.0")
# 2. 定义MCP请求模型(智能体发送的请求格式)
class MCPRequest(BaseModel):
tool_name: str = Field(..., description="要调用的工具名称")
parameters: Dict[str, Any] = Field(..., description="工具所需参数")
# 3. 定义MCP响应模型(工具返回的结果格式)
class MCPResponse(BaseModel):
result: Optional[Dict[str, Any]] = Field(None, description="执行成功的结果")
error: Optional[str] = Field(None, description="执行失败的错误信息")
# 4. 实现计算器工具逻辑
def calculate(operation: str, num1: float, num2: float) -> float:
"""计算器核心逻辑:支持加减乘除"""
if operation == "add":
return num1 + num2
elif operation == "subtract":
return num1 - num2
elif operation == "multiply":
return num1 * num2
elif operation == "divide":
if num2 == 0:
raise ValueError("除数不能为0")
return num1 / num2
else:
raise ValueError(f"不支持的操作:{operation}")
# 5. 定义MCP接口(智能体调用的入口)
@app.post("/mcp", response_model=MCPResponse)
async def handle_mcp_request(request: MCPRequest) -> MCPResponse:
try:
# 校验工具名称
if request.tool_name != "calculator":
return MCPResponse(error=f"不支持的工具:{request.tool_name}")
# 提取并校验参数
operation = request.parameters.get("operation")
num1 = request.parameters.get("num1")
num2 = request.parameters.get("num2")
if not all([operation, num1, num2]):
return MCPResponse(error="缺少必要参数:operation、num1、num2")
# 执行计算
result = calculate(operation, float(num1), float(num2))
return MCPResponse(result={"result": result, "operation": operation})
except Exception as e:
return MCPResponse(error=f"执行失败:{str(e)}")
# 6. 启动服务器
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
3. 测试 MCP 服务器
启动服务器后,用 curl 命令测试:
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{
"tool_name": "calculator",
"parameters": {
"operation": "add",
"num1": 10,
"num2": 20
}
}'
预期响应:
{
"result": {"result": 30.0, "operation": "add"},
"error": null
}
四、实战 2:进阶 MCP 工具 ------PDF 文档读取器
现在升级到更实用的场景:开发一个能读取 PDF 文档的 MCP 工具,类似之前的mcp-docx-reader:
1. 扩展代码:添加 PDF 读取功能
在main.py中添加以下代码:
import pdfplumber
# 4.2 实现PDF读取工具逻辑
def read_pdf(file_path: str, page_range: Optional[list] = None) -> Dict[str, Any]:
"""读取PDF文档内容,支持指定页码范围"""
with pdfplumber.open(file_path) as pdf:
total_pages = len(pdf.pages)
# 处理页码范围,默认读取全部
if page_range:
start, end = page_range
start = max(1, start)
end = min(total_pages, end)
pages = pdf.pages[start-1:end] # pdfplumber页码从0开始
else:
pages = pdf.pages
start, end = 1, total_pages
# 提取每页文本
text = ""
for page in pages:
text += page.extract_text() or ""
return {
"text": text.strip(),
"page_count": len(pages),
"total_pages": total_pages,
"page_range": [start, end]
}
# 5.1 扩展MCP接口,支持多工具
@app.post("/mcp", response_model=MCPResponse)
async def handle_mcp_request(request: MCPRequest) -> MCPResponse:
try:
# 计算器工具
if request.tool_name == "calculator":
operation = request.parameters.get("operation")
num1 = request.parameters.get("num1")
num2 = request.parameters.get("num2")
if not all([operation, num1, num2]):
return MCPResponse(error="缺少必要参数:operation、num1、num2")
result = calculate(operation, float(num1), float(num2))
return MCPResponse(result={"result": result, "operation": operation})
# PDF读取工具
elif request.tool_name == "pdf_reader":
file_path = request.parameters.get("file_path")
page_range = request.parameters.get("page_range")
if not file_path:
return MCPResponse(error="缺少必要参数:file_path")
result = read_pdf(file_path, page_range)
return MCPResponse(result=result)
# 未知工具
else:
return MCPResponse(error=f"不支持的工具:{request.tool_name}")
except Exception as e:
return MCPResponse(error=f"执行失败:{str(e)}")
2. 测试 PDF 读取功能
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{
"tool_name": "pdf_reader",
"parameters": {
"file_path": "./test.pdf",
"page_range": [1, 5]
}
}'
预期响应:
{
"result": {
"text": "PDF第1-5页的内容...",
"page_count": 5,
"total_pages": 20,
"page_range": [1, 5]
},
"error": null
}
五、集成到 Trae IDE:让智能体调用你的 MCP 工具
开发完成后,将 MCP 服务器集成到 Trae IDE,让智能体可以直接调用:
1. 启动 MCP 服务器
确保你的 MCP 服务器在本地运行(uvicorn main:app --host 0.0.0.0 --port 8000)。
2. 配置 Trae IDE 的 MCP 服务器
-
打开 Trae IDE,进入「智能体」面板→「⚙️ 配置」→「MCP 服务器配置」;
-
点击「添加自定义服务器」,输入以下配置:
{
"mcpServers": {
"my-mcp-tools": {
"command": "python",
"args": [
"/path/to/main.py"
]
}
}
}
或者直接连接已运行的服务器:
{
"mcpServers": {
"my-mcp-tools": {
"url": "http://localhost:8000/mcp"
}
}
}
3. 智能体调用测试
在 Trae IDE 的智能体聊天窗口输入:
帮我读取本地的test.pdf文档第1-5页的内容,用你会的工具完成。
智能体将自动调用你的pdf_reader工具,返回 PDF 内容。
六、进阶优化:让 MCP 工具更专业
1. 异步处理:提升并发性能
将 PDF 读取逻辑改为异步(需要使用支持异步的 PDF 库,如aiofiles配合pdfplumber):
import aiofiles
async def read_pdf_async(file_path: str, page_range: Optional[list] = None) -> Dict[str, Any]:
async with aiofiles.open(file_path, mode='rb') as f:
pdf_data = await f.read()
with pdfplumber.open(pdf_data) as pdf:
# 后续逻辑同同步版本...
2. 日志记录:便于排查问题
添加日志功能,记录工具调用情况:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 在工具逻辑中添加日志
logger.info(f"调用计算器工具:operation={operation}, num1={num1}, num2={num2}")
3. 权限控制:限制非法调用
添加 API 密钥验证,确保只有授权的智能体可以调用:
from fastapi import Header, HTTPException
async def verify_api_key(api_key: Optional[str] = Header(None)):
if api_key != "your-secret-key":
raise HTTPException(status_code=401, detail="无效的API密钥")
# 在接口中添加依赖
@app.post("/mcp", response_model=MCPResponse, dependencies=[Depends(verify_api_key)])
七、发布自己的 MCP 工具:让其他人一键安装
如果想让其他人使用你的 MCP 工具,可以用uv打包,实现一键安装:
1. 创建pyproject.toml
[project]
name = "mcp-pdf-reader"
version = "1.0.0"
dependencies = [
"fastapi>=0.100.0",
"pydantic>=2.0.0",
"uvicorn>=0.23.0",
"pdfplumber>=0.10.0"
]
[project.scripts]
mcp-pdf-reader = "main:run"
2. 在main.py中添加启动函数
def run():
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
if __name__ == "__main__":
run()
3. 发布到 PyPI 或 GitHub
其他人可以通过以下命令一键安装并启动:
# 从PyPI安装
pip install mcp-pdf-reader
mcp-pdf-reader
# 从GitHub安装
uvx --from git+https://github.com/yourname/mcp-pdf-reader mcp_pdf_reader
八、总结与展望
MCP 协议为 AI 智能体和外部工具搭建了标准化的桥梁,用 Python 开发 MCP 工具门槛低、灵活度高,能快速扩展智能体的能力边界。通过本文的实战,你已经掌握了:
- MCP 协议的核心概念和规范;
- 用 FastAPI+Pydantic 开发 MCP 服务器的流程;
- 从简单计算器到实用 PDF 阅读器的工具开发;
- 集成到 Trae IDE 并发布自己的 MCP 工具。
未来,MCP 生态会越来越完善,你可以开发更多实用工具:
- 数据库操作工具:让智能体执行 SQL 查询;
- API 调用工具:让智能体调用外部 API 获取数据;
- 代码生成工具:让智能体生成并运行代码;
- 多模态工具:让智能体处理图片、音频等非文本数据。
现在,动手开发你的第一个 MCP 工具,让 AI 智能体真正成为你的 "全能助手" 吧!