1. MCP Server开发入门:构建AI可调用的本地服务接口
MCP(Model Context Protocol)是一种让大语言模型安全访问本地资源的协议框架。作为一名长期从事AI应用开发的工程师,我发现MCP特别适合需要将AI能力与本地业务系统对接的场景。它就像给大模型装上了标准化的"操作手柄",让AI可以安全可控地调用我们预先定义好的功能模块。
在实际项目中,我主要用MCP来实现以下三类功能对接:
- 业务系统API的封装调用(如ERP、CRM系统)
- 本地文件和数据的安全访问
- 特定领域知识的提示词模板管理
下面我将通过两个典型示例,带你从零开始构建MCP服务。这些代码都来自我的实际项目经验,包含了许多官方文档中没有提到的实用技巧。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境准备与SDK选择
2.1 环境配置建议
在开始编码前,我建议先建立一个干净的Python虚拟环境。这是我多年开发总结出的最佳实践:
bash复制python -m venv mcp-env
source mcp-env/bin/activate # Linux/Mac
# 或
mcp-env\Scripts\activate # Windows
官方SDK可以通过pip直接安装:
bash复制pip install mcp
注意:建议固定SDK版本以避免兼容性问题。我在项目中通常使用
pip install mcp==0.4.2这样的明确版本号。
2.2 开发工具选择
根据我的经验,以下工具组合效率最高:
- VS Code + Python插件:提供优秀的代码补全和调试支持
- Postman:用于API测试(当需要HTTP接口时)
- MCP Inspector:官方调试工具,后面会详细介绍用法
3. 基础示例:问候服务实现
3.1 服务端代码解析
让我们从最简单的"Hello World"示例开始。创建server.py文件:
python复制from mcp.server.fastmcp import FastMCP
# 初始化服务实例
mcp = FastMCP("Greeting Service")
@mcp.tool()
def say_hello(name: str) -> str:
"""
向指定用户打招呼。
参数说明:
name -- 用户名,支持中英文
"""
if not name.strip():
return "错误:名字不能为空"
# 这里可以添加业务逻辑,比如查询数据库获取用户信息
return f"你好,{name}!当前系统时间:{datetime.now().strftime('%Y-%m-%d %H:%M')}"
if __name__ == "__main__":
mcp.run()
这段代码展示了MCP开发的三个核心步骤:
- 初始化FastMCP实例
- 使用
@mcp.tool()装饰器注册工具函数 - 启动服务
3.2 服务测试方法
方法一:使用标准输入输出测试
直接运行脚本:
bash复制python server.py
然后通过stdin输入JSON格式的请求:
json复制{"tool": "say_hello", "params": {"name": "张三"}}
方法二:使用Inspector工具
安装并运行Inspector:
bash复制npx @modelcontextprotocol/inspector python server.py
这会启动一个本地Web界面,可以可视化地测试工具调用。
4. 文件操作服务实战
4.1 安全文件访问实现
下面这个文件服务器示例包含更多实际开发中的考量:
python复制import os
from pathlib import Path
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("File Manager")
# 使用Path对象更安全地处理路径
BASE_DIR = Path("./safe_files").resolve()
@mcp.resource("dir://files")
def list_files() -> list[str]:
"""列出可访问的文件列表"""
if not BASE_DIR.exists():
BASE_DIR.mkdir(parents=True, exist_ok=True)
return []
return [
f.name for f in BASE_DIR.iterdir()
if f.is_file() and not f.name.startswith('.')
]
@mcp.tool()
def read_file(filename: str) -> str:
"""
读取文件内容(安全版本)
参数:
filename -- 纯文件名(不含路径)
"""
# 安全校验
if not filename.isprintable() or any(c in filename for c in '/\\'):
return "错误:非法文件名"
target = BASE_DIR / filename
try:
return target.read_text(encoding='utf-8')
except Exception as e:
return f"读取失败:{str(e)}"
@mcp.tool()
def write_file(filename: str, content: str) -> str:
"""安全写入文件"""
if not filename.isprintable() or any(c in filename for c in '/\\'):
return "错误:非法文件名"
target = BASE_DIR / filename
try:
target.write_text(content, encoding='utf-8')
return f"成功写入 {filename}"
except Exception as e:
return f"写入失败:{str(e)}"
4.2 安全防护要点
在实际部署时,文件操作必须考虑以下安全因素:
- 路径隔离:使用resolve()获取绝对路径,防止相对路径遍历
- 输入校验:检查文件名是否包含特殊字符
- 权限控制:确保程序只有必要的文件系统权限
- 异常处理:妥善处理各种IO异常情况
5. 高级开发技巧
5.1 性能优化建议
当工具函数需要执行耗时操作时,建议采用异步模式:
python复制import asyncio
@mcp.tool()
async def process_large_file(filename: str):
"""异步处理大文件"""
# 模拟耗时操作
await asyncio.sleep(1)
return "处理完成"
5.2 状态管理方案
MCP服务默认是无状态的,如果需要维护状态,可以使用类封装:
python复制class ChatSession:
def __init__(self):
self.history = []
@mcp.tool()
def chat(self, message: str):
self.history.append(message)
return f"已记录:{message}(历史消息数:{len(self.history)})"
session = ChatSession()
mcp.register_instance(session)
6. 调试与部署实战
6.1 使用Claude Desktop集成
配置文件示例(claude_desktop_config.json):
json复制{
"mcpServers": {
"file-service": {
"command": "/usr/local/bin/python3",
"args": [
"/path/to/file_server.py"
],
"timeout": 30
}
}
}
6.2 生产环境部署建议
- 使用进程管理工具:如systemd或supervisor
- 日志记录:添加详细的日志输出
- 健康检查:实现/health端点
- 资源限制:控制内存和CPU使用
7. 常见问题排查
7.1 连接问题
症状:Claude无法识别MCP服务
- 检查配置文件路径是否正确
- 确认Python路径是绝对路径
- 查看服务是否正常启动
7.2 性能问题
症状:响应缓慢
- 检查工具函数是否有阻塞操作
- 考虑使用异步实现
- 分析日志查找瓶颈
7.3 安全问题
症状:出现未授权访问
- 确保所有输入都经过验证
- 限制文件系统访问范围
- 使用最小权限原则运行服务
8. 扩展应用场景
基于MCP可以构建各种实用工具:
- 数据库查询代理:安全地暴露只读SQL查询接口
- 内部知识库检索:连接企业文档管理系统
- 业务流程触发器:启动审批流程等业务操作
- 数据分析服务:执行特定的数据处理任务
在实际项目中,我通常会将MCP服务与FastAPI结合,同时提供AI调用和常规API访问两种方式。这种混合架构既保持了灵活性,又能复用业务逻辑。
