📚 相关阅读

← 返回首页

MCP Server开发踩坑全记录

PythonMCPSDK开发者工具踩坑记录

问题背景:为什么我需要自己写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无法连接Serverstdio vs HTTP传输协议混淆stdio模式直接运行,HTTP模式才监听端口
tool找不到用了驼峰命名改snake_case命名
resource URI报错authority部分为空加`/`使路径非空
部署后ImportErrorPython版本不兼容确认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:

MCP Server开发踩坑全记录
技术标签: python, mcp
MCP Server Python SDK Pitfalls
技术标签: mcp, python
MCP Server Python SDK Pitfalls
技术标签: mcp, python
💻 Recommended Hardware
查看推荐 →