FastMCP全篇教程以及解决400 Bad Request和session termination的问题
1.背景
随着MCP的概念火爆,越来越多的程序员接触MCP概念,而作为其中部署的佼佼者吗——FastMCP,则更是进入开发者的视角。以下是让AI整合的表格:
MCP通常是指Model Context Protocol(模型上下文协议),FastMCP是基于MCP的Python框架,以下是相关介绍表格:
名称 | 定义 | 核心组件 | 主要功能 | 应用场景 |
---|---|---|---|---|
MCP(Model Context Protocol,模型上下文协议) | 由Anthropic推出的开放式协议,为现代人工智能和大模型服务场景设计,用于标准化应用程序向大语言模型提供上下文的方式 | 包含MCP主机、MCP客户端、MCP服务器三个关键组件。MCP主机是需访问数据的应用程序;MCP客户端管理与服务器的连接,处理通信细节;MCP服务器是通过标准化协议暴露特定功能的轻量级程序 | 为模型推理、上下文管理、数据流转和多模型协作提供统一、标准化的接口和语义描述方式,让大语言模型能以一致方式连接到多样化数据源和工具生态系统,实现敏感数据可保留本地,通过权限控制确保数据访问可控 | 广泛应用于Claude、Cursor、百度智能云、阿里云等,用于构建更自然、更复杂的智能体交互体验,是LLM使用工具方面事实上的标准 |
FastMCP | 基于Python的高级框架,用于构建MCP服务器和客户端,可帮助开发者以最小代码量创建MCP服务器,让AI助手更好地与本地工具进行交互 | / | 具备工具、资源、提示模板等功能,支持图片处理、数据库交互、文件处理、API集成等。可通过装饰器定义功能,支持多种传输方式,能从OpenAPI规范或FastAPI应用自动生成服务器,还可将多个服务器组合成更大应用 | 主要用于简化MCP相关开发工作,为开发者提供便捷方式为AI助手如Claude等扩展本地功能,构建特定领域工具链 |
MCP首次出现的时间是 2024 年 11 月 24 日,而FastMCP 出现时间暂无公开的明确报道,但根据其 1.0 版本已被纳入官方 MCP Python SDK,且在 2025 年 5 月 29 日已更新至 2.0 版本来推测,其首次发布时间应早于 2025 年 5 月,可能在 2024 年 MCP 发布后不久。
因此FastMCP的更新迭代速度极快,这导致其官方文档一直跟不上其代码速度。
2.相关资料
官方地址:https://github.com/jlowin/fastmcp
官方文档:https://gofastmcp.com/getting-started/installation
具体的使用demo,直接看QuickStart即可:
3.版本说明
MCP协议支持 STDIO、SSE、Streamable HTTP,关于这三者的应用场景如下:
传输方式 | 全称 | 核心特点 | 应用场景 |
---|---|---|---|
STDIO | Standard Input/Output(标准输入输出) | 基于命令行的文本流传输,通过进程间的标准输入输出进行通信,简单轻量,无需网络配置 | 1. 本地脚本与LLM交互:适用于单个设备内的本地工具调用,如Python脚本、终端程序与AI助手(如Claude)的交互,无需复杂网络设置。 2. 开发调试场景:开发者在本地测试MCP服务器/客户端功能时,通过命令行即可快速验证通信逻辑,减少环境依赖。 3. 轻量工具集成:小型工具(如本地文件处理器、简单计算器)与LLM的低成本集成,适合资源有限或对实时性要求不高的场景。 |
SSE | Server-Sent Events(服务器发送事件) | 基于HTTP的单向流式传输协议,由服务器主动向客户端推送事件流,支持持续数据发送,低延迟 | 1. 实时AI响应推送:LLM生成长文本(如论文、代码)时,通过SSE将内容分段实时推送给客户端,实现“边生成边展示”的流畅体验。 2. 动态数据更新:工具或数据源(如实时日志监控、股票行情工具)向LLM持续推送最新数据,确保模型获取实时上下文。 3. 跨设备/网络通信:适用于客户端(如Web应用、远程设备)与云端MCP服务器的交互,兼顾实时性和网络兼容性。 |
Streamable HTTP | 可流式HTTP | 基于HTTP的双向流式传输,支持客户端与服务器双向发送流式数据,兼容HTTP生态,灵活性高 | 1. 复杂多轮交互场景:需要LLM与工具双向持续通信的场景,如AI辅助的代码调试(工具返回错误日志,LLM实时生成修复建议)、多步骤数据分析(工具逐步返回计算结果,模型逐步调整分析逻辑)。 2. Web应用集成:与现有Web服务(如FastAPI、OpenAPI接口)无缝对接,支持浏览器、移动应用等通过HTTP与MCP服务器交互,适合面向用户的线上AI产品。 3. 跨平台协作:在不同网络环境(如企业内网、公网)中,实现LLM、本地工具、云端服务的跨平台数据流转,兼顾兼容性和交互复杂度。 |
在早期大家用sse用的较多,但随着FastMCP的更新,大家越来越推崇通过http来部署生产版本,原因如下:
以下是FastMCP推崇用HTTP(Streamable HTTP)取代SSE的核心原因对比表格,从技术痛点与HTTP的优势两方面展开:
对比维度 | SSE的局限性 | Streamable HTTP的优势 | 核心应用价值 |
---|---|---|---|
连接与资源管理 | 需维持长连接,高并发下服务器资源消耗大;连接中断后无法断点续传,易丢失上下文 | 支持无状态通信,无需长期占用连接,降低服务器资源压力;通过session机制支持断点重连和状态恢复,保障数据完整性 | 提升系统扩展性,适应高并发场景,减少因连接问题导致的故障 |
通信模式与端点设计 | 仅支持服务器单向推送,需通过专门的/sse 端点通信,增加架构复杂性 | 支持双向流式通信,所有交互整合到统一端点,无需额外维护专用端点 | 简化通信模型,降低开发和维护成本,统一接口设计 |
基础设施兼容性 | 部分企业防火墙、代理服务器会强制终止长期SSE连接,导致服务不稳定 | 基于标准HTTP协议,兼容现有网络基础设施(防火墙、负载均衡器等),无需特殊配置 | 提升跨环境部署的可靠性,减少因基础设施限制导致的适配问题 |
客户端实现复杂度 | 客户端需专门处理SSE流解析,实现逻辑较繁琐 | 复用标准HTTP客户端库,无需额外开发复杂的流处理逻辑,代码量更少 | 降低开发者门槛,加速集成效率,减少潜在的实现bug |
随着FastMCP的更新迭代,如果使用的版本不对,让AI比如元宝、豆包、kimi这类国产应用结合网页生成代码的话,经常生成的不可用,所以必须得明白各个版本的主要变动:
以下是对FastMCP四个版本核心特性的梳理与修正说明,结合版本演进逻辑呈现:
版本号 | 核心特性说明(修正与补充) | 版本意义 |
---|---|---|
v2.2.5 | 该版本对SSE(Server-Sent Events)传输方式的支持较为完善,是当时主流的通信方式。 此阶段官方文档中关于HTTP(Streamable HTTP)的示例代码存在兼容性问题,实际使用中多依赖 mcp 库来实现客户端(Client)的初始化与交互,客户端对接以SSE为主 | 处于SSE向HTTP过渡的初期,SSE仍是稳定选择,但HTTP支持尚不成熟,依赖外部库完成客户端基础功能 |
v2.3.2 | 该版本重点优化了HTTP(Streamable HTTP)的客户端对接能力,将客户端功能整合到FastMCP自身库中,无需依赖外部mcp 库,通过内置的Client 类即可直接实现HTTP协议的客户端初始化、连接与交互,大幅简化了HTTP接入的代码量和复杂度 | 标志着HTTP传输方式的实用性显著提升,降低了开发者采用HTTP的门槛,加速了从SSE向HTTP的迁移 |
v2.6.0 | 正式推出基于JWT(JSON Web Token)的权限认证封装,包括令牌生成、验证、过期管理等功能,支持在客户端与服务器交互时进行身份校验和权限控制,增强了MCP通信的安全性 | 填补了早期版本在安全认证上的空白,使FastMCP更适用于生产环境,尤其是需要严格权限管理的多用户、跨域场景 |
v2.9.0 | 引入中间件(Middleware)模块,支持在请求处理链路中插入自定义逻辑(如日志记录、请求过滤、数据转换、异常处理等),开发者可通过注册中间件对请求/响应流程进行灵活干预 | 提升了框架的扩展性和可定制性,便于构建模块化、可复用的功能组件,适应复杂业务场景的需求 |
4.问题解决
在使用v2.3.2部署生产环境时,由于文档里基本都是使用mcp.run的部署方式,基于ASGI的部署方式是uvicorn:
在使用这个部署和测试client的过程中出现两个报错:
- 频繁报307:Incorrect 307 Temporary Redirect
解决方式:将http://xxx.com/mcp加斜杠,即:http://xxx.com/mcp/ - 频繁报Session termination failed: Server disconnected without sending a response
解决方式:调整长连接的时间,比如用uvicorn启动的服务,则加上 --timeout-keep-alive 300即可解决
在此说明下,Python web常用的gunicorn和uvicorn的区别:
以下是Uvicorn与Gunicorn的核心区别对比表格,从定位、特性、适用场景等方面展开说明,尤其结合FastMCP作为异步框架的部署需求:
对比维度 | Uvicorn | Gunicorn |
---|---|---|
核心定位 | 异步HTTP服务器,基于uvloop 和httptools ,专门用于运行ASGI(异步服务器网关接口)应用 | 同步/异步兼容的WSGI服务器,最初为WSGI(Web服务器网关接口)设计,支持通过worker类扩展异步能力 |
协议支持 | 仅支持ASGI协议,原生适配异步框架(如FastAPI、FastMCP、Starlette等) | 默认支持WSGI协议,可通过gevent 、eventlet 等worker类支持异步,或通过uvicorn.workers.UvicornWorker 桥接ASGI应用 |
并发模型 | 基于异步I/O(非阻塞),单进程可处理大量并发连接,资源利用率高 | 默认采用多进程同步模型(prefork),通过多进程分担请求压力,异步能力需依赖第三方库 |
部署角色 | 通常作为应用服务器,直接运行ASGI应用,但生产环境中常搭配Gunicorn作为进程管理器 | 通常作为进程管理器,管理多个Uvicorn worker进程,提供负载均衡、进程监控、平滑重启等功能 |
与FastMCP的适配性 | FastMCP是异步框架,Uvicorn可直接运行其ASGI应用,匹配度高 | 需配置UvicornWorker 作为worker类,间接运行FastMCP应用,多一层进程管理抽象 |
优势场景 | 开发环境快速启动、轻量部署,或作为Gunicorn的worker运行于生产环境 | 生产环境中管理多个异步worker进程,提升稳定性(如自动重启崩溃进程)、支持水平扩展 |
典型命令 | uvicorn main:app --host 0.0.0.0 --port 8000 (直接启动应用) | gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 (管理4个Uvicorn worker) |
由于uvicorn一直是单进程启动的,而如果要加进程数可以通过–worker来指定,但FastMCP的session id是由服务端维护的,导致多worker无法识别已存在的session id,而在客户端就容易报400 Bad Request,这时候我翻到一篇issue聊的session id的设计,挺有意思:https://github.com/jlowin/fastmcp/issues/956
即为啥不在客户端维护session_Id的理念(主要是安全理念)
而他也画了完整的流程图介绍如何在初始化时获得session id,然后再后续使用