加载中

MCP服务器中的stateless_http和json_response标志控制着服务器行为的基本方面。理解何时以及为何使用它们至关重要,尤其是当您计划扩展服务器规模或将其部署到生产环境时。

何时需要无状态HTTP

想象您构建了一个变得流行的MCP服务器。最初,您可能只有少数几个客户端连接到单个服务器实例:

三个MCP客户端,一个标记为"您",另外两个标记为"其他人",全部连接到远程机器上的一个MCP服务器。

随着服务器的增长,您可能会有成千上万的客户端尝试连接。运行单个服务器实例无法扩展以处理所有这些流量:

三个MCP客户端,您的和另外两个,加上99999个其他人,全部连接到远程机器上的一个MCP服务器。

典型的解决方案是水平扩展——在负载均衡器后面运行多个服务器实例:

三个MCP客户端,您的和另外两个,全部通过一个负载均衡器路由,该均衡器分发到三个MCP服务器。

但这正是事情变得复杂的地方。请记住,MCP客户端需要两个独立的连接:

  • 一个用于接收服务器到客户端请求的GET SSE连接
  • 用于调用工具和接收响应的POST请求

一个"GET SSE响应"箭头从两个MCP服务器之一指向MCP客户端,负载均衡器位于两者之间。

使用负载均衡器时,这些请求可能会被路由到不同的服务器实例。如果您的工具需要使用Claude(通过采样),处理POST请求的服务器将需要与处理GET SSE连接的服务器进行协调。这会在服务器之间产生复杂的协调问题。

一个MCP客户端,两个服务器:一个提供GET SSE响应,另一个提供带有创建消息请求和调用工具结果的POST SSE响应。

无状态HTTP如何解决这个问题

设置stateless_http=True可以消除这个协调问题,但会带来显著的权衡:

FastMCP构造函数带有stateless_http=True和json_response=True参数,每个参数都与下面列出的权衡相关联。

启用无状态HTTP时:

  • 客户端不会获得会话ID - 服务器无法跟踪单个客户端
  • 没有服务器到客户端的请求 - GET SSE通道变得不可用
  • 没有采样 - 无法使用Claude或其他AI模型
  • 没有进度报告 - 无法在长时间操作期间发送进度更新
  • 没有订阅 - 无法就资源更新通知客户端

不过,有一个好处:不再需要客户端初始化。客户端可以直接发出请求,而无需经过初始握手过程。

图示显示一个从MCP客户端到服务器的实线POST SSE响应箭头,以及一个返回的虚线灰色GET SSE响应箭头。

理解JSON响应

json_response=True标志更简单——它只是禁用POST请求响应的流式传输。在工具执行过程中,您不会收到多条SSE消息,而只会以纯JSON形式获得最终结果。

禁用流式传输后:

  • 没有中间进度消息
  • 执行期间没有日志语句
  • 只有最终的工具结果

何时使用这些标志

在以下情况下使用无状态HTTP:

  • 您需要使用负载均衡器进行水平扩展
  • 您不需要服务器到客户端的通信
  • 您的工具不需要AI模型采样
  • 您希望最小化连接开销

在以下情况下使用JSON响应:

  • 您不需要流式响应
  • 您更喜欢更简单的非流式HTTP响应
  • 您正在与期望纯JSON的系统集成

开发环境与生产环境

如果您在本地使用标准I/O传输进行开发,但计划使用HTTP传输进行部署,请使用与生产环境相同的传输方式进行测试。有状态模式和无状态模式之间的行为差异可能很显著,最好在开发阶段发现任何问题,而不是在部署之后。

这些标志从根本上改变了MCP服务器的运行方式,因此请根据您具体的扩展和功能需求来选择它们。