MCP Server开发踩坑全记录
问题背景:为什么我需要自己写MCP Server
我的工作流里有个痛点:每次要查客户数据时,得在浏览器里打开好几个人工后台来回切换。后来看到MCP(Model Context Protocol)的文档,说可以"让AI连接本地文件、数据库、工具",我就想自己写一个MCP Server,把CRM API包装成AI可调用的工具。
结果我花了3天才跑通第一个Hello World,期间踩了5个坑。
坑1:stdio传输协议配置错误
第一个坑是最基础的:MCP官方Python SDK默认用stdio通信,但我一开始不知道这个,直接用HTTP启动了Server:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("My Server")
# 这个Server默认是stdio模式的!
然后AI客户端连接不上,因为stdio和HTTP是不兼容的两种传输协议。HTTP模式下Server需要监听端口,但stdio模式下Server是从stdin/stdout通信的。
**排查过程**:我看了MCP Inspector的文档(npx @modelcontextprotocol/inspector可以测试stdio Server),确认stdio模式的正确启动方式。
解决方案:stdio模式下不需要启动HTTP服务器,直接运行即可:
# server.py - stdio模式
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("My Server")
@mcp.tool()
def get_customer(customer_id: str) -> dict:
"""查询客户信息"""
# 你的业务逻辑
return {"name": "张三", "status": "活跃"}
# 直接运行,用stdio通信
if __name__ == "__main__":
mcp.run()
**防止方法**:MCP Server默认是stdio模式。如果你想用HTTP,要额外配置transport参数(mcp.run(transport="streamable-http", host="0.0.0.0", port=8000))。
坑2:tool命名规范导致AI无法调用
好不容易Server跑起来了,但AI说找不到这个tool。调试后发现是命名问题。
我定义的tool是这样的:
@mcp.tool()
def Get_Customer_Info(customer_id: str) -> dict:
"""查询客户信息"""
return {"name": "张三"}
MCP协议里tool名称必须是小写字母+下划线,不能用驼峰命名。AI发送请求时用的是snake_case,但我的tool叫Get_Customer_Info,所以匹配不上。
**排查过程**:用MCP Inspector测试,在Tools tab里能看到这个tool,但名称显示为Get_Customer_Info而不是get_customer_info。
**解决方案**:tool名称必须符合^[a-z][a-z0-9_]*$正则,即小写字母开头、只含小写字母/数字/下划线:
@mcp.tool()
def get_customer_info(customer_id: str) -> dict:
"""查询客户信息(返回客户状态和联系方式)"""
return {"name": "张三", "phone": "13800000000"}
# 正确!名称符合snake_case规范
防止方法:定义tool时用snake_case命名,这是MCP协议的强制规范。
坑3:resource路径前缀处理出错
tool能调用了,但resource又出问题。
我的Server有个resource是客户列表:
@mcp.resource("customers://list")
def get_customer_list() -> str:
"""返回客户列表"""
return "张三,李四,王五"
但AI访问时报错:Invalid resource URI: customers://list。问题出在://这部分的处理。
**排查过程**:查阅MCP specification后发现,resource URI格式应该是{protocol}://{authority}/{path},但://是协议分隔符,customers://list会被解析为protocol=customers, authority=(empty), path=list,authority为空导致解析失败。
解决方案:resource URI格式必须符合RFC 3986,authority部分不能为空:
# 错误:customers://list —— authority为空
@mcp.resource("customers://list")
# 正确:customers/list 或 customers://list/
@mcp.resource("customers://")
def get_customers():
"""客户列表资源端点"""
return "张三,李四,王五"
# 或者用路径格式
@mcp.resource("customers:///list")
def get_customer_list():
return "张三,李四,王五"
**防止方法**:MCP resource URI需要包含有效的authority部分,://后面至少要有/。不确定时用MCP Inspector验证。
坑4:Python版本兼容性问题
代码本地跑通了,但部署到生产环境(Ubuntu 22.04,Python 3.10)时报错:
ImportError: cannot import name 'Fault' from 'mcp.server'
我的开发环境是Python 3.12,但MCP Python SDK的某些版本对Python版本有要求。
排查过程:检查pip show和requirements,发现MCP SDK 0.9.0+需要Python 3.11+,但客户服务器是3.10。
解决方案:
# 先检查Python版本
python3 --version
# 输出:Python 3.10.12
# 升级Python(Ubuntu 22.04)
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.11
python3.11 --version
# 用虚拟环境安装对应版本
python3.11 -m venv venv
source venv/bin/activate
pip install mcp==1.0.0 # 找兼容Python 3.11的版本
**防止方法**:部署前先确认Python版本要求,在pyproject.toml里加requires-python = ">=3.11"。
坑5:stdio模式下的buffer超时问题
Server在本地测试正常,但AI长时间调用时会超时:
Error: stdio read timeout after 30s
问题在于:我的tool要查询远程API,正常需要10-15秒。但MCP Inspector默认的stdio read timeout是30秒,生产环境里AI Client的timeout可能更短。
排查过程:用MCP Inspector在Tools tab里手动触发tool调用,发现不是每次都超时,只是当远程API响应慢时才触发。
解决方案:有两个方向:
1. 增加timeout配置(客户端设置):
# 客户端连接时设置更长timeout
mcp_client = Client(
server,
timeout=120 # 120秒timeout
)
2. 给tool加异步处理(减少阻塞):
import asyncio
@mcp.tool()
async def get_customer(customer_id: str) -> dict:
"""异步查询客户信息(带超时控制)"""
try:
# 用asyncio.wait_for控制超时
result = await asyncio.wait_for(
query_crm_api(customer_id),
timeout=60
)
return result
except asyncio.TimeoutError:
return {"error": "查询超时,请稍后重试"}
防止方法:MCP Server的tool如果涉及远程IO,一律用async写法并设置timeout,避免阻塞stdio通信。
踩坑总结:5个配置项检查清单
| 问题 | 原因 | 解决 |
|---|---|---|
| AI无法连接Server | stdio vs HTTP传输协议混淆 | stdio模式直接运行,HTTP模式才监听端口 |
| tool找不到 | 用了驼峰命名 | 改snake_case命名 |
| resource URI报错 | authority部分为空 | 加`/`使路径非空 |
| 部署后ImportError | Python版本不兼容 | 确认requires-python,必要时升级 |
| stdio超时 | 远程IO阻塞 | 用async+asyncio.wait_for |
MCP是个新协议(2024年底才发布),文档还在完善中,很多坑需要自己踩。这篇复盘希望帮你跳过这些。
👉 立即体验:部署MCP Server推荐用**DigitalOcean**($4/月,Python环境好配),参考官方MCP Inspector测试方法验证你的Server。
🔗 Related Tech Articles
Deep dive into related technical topics: