在Starlette中集成MCP服务器时Messages接口随机返回404
解决MCP服务器随机出现会话ID未找到的404错误
可能的原因及修复方案
1. 路由路径配置冲突
你在Starlette中把MCP服务器挂载到/mcp路径,但FastMCP的http_app设置了path="/",这可能导致会话路由的匹配逻辑出现异常。调整FastMCP的http_app路径,和挂载路径对齐:
修改MCP路由设置代码:
def mcp_asgi_server(): # 将path改为与Starlette挂载路径一致的"/mcp" return mcp.http_app(path="/mcp", transport="sse")
Starlette的Mount配置保持不变:
routes.append(Mount(name="mcp", path="/mcp", app=MCP_SERVER))
2. 生命周期逻辑冲突
直接替换Starlette的lifespan为MCP服务器的lifespan,会覆盖原应用的生命周期逻辑,可能导致会话存储无法正确初始化或持久化。需要合并两个生命周期函数:
async def combined_lifespan(app): # 先执行原Starlette应用的生命周期逻辑 async with create_lifespan(app): # 再执行MCP服务器的生命周期逻辑 async with MCP_SERVER.lifespan(app): yield # 使用合并后的生命周期函数 lifespan = combined_lifespan
3. 会话超时设置过短
FastMCP默认会话超时可能过短,导致活跃会话被提前清理。初始化时调整超时时间:
# 设置会话超时为3600秒(可根据业务需求调整) mcp = FastMCP( resource_prefix_format="path", session_timeout=3600 )
4. 线程/协程安全的会话存储问题
如果应用采用多进程或多协程部署,默认内存会话存储可能存在线程安全问题,导致会话丢失。若FastMCP支持,可切换到Redis会话存储:
from fastmcp.session import RedisSessionStore # 初始化Redis会话存储 session_store = RedisSessionStore(redis_url="redis://localhost:6379/0") mcp = FastMCP( resource_prefix_format="path", session_store=session_store )
5. 客户端会话ID复用问题
确保客户端在捕获到404错误后,立即触发新会话创建流程,不再复用已失效的session_id。
内容的提问来源于stack exchange,提问作者Devin Yu
相关产品推荐
相关产品推荐

