文章摘要

MCP在Java和Spring AI项目中常见三种部署方式:STDIO适合本地进程工具,Streamable HTTP适合需要会话和双向能力的远程服务,Stateless HTTP则适合请求—响应型工具和云原生水平扩容。三种方式在网络边界、状态管理、Sampling、Elicitation、负载均衡、鉴权和故障恢复方面存在明显差异。本文给出生产选型方法和迁移建议。

一、三种方式解决的不是同一个问题

STDIO

客户端启动本地子进程
→ 通过标准输入输出交换JSON-RPC

Streamable HTTP

客户端通过HTTP连接远程MCP Server
→ 协议可能维护逻辑会话
→ 支持更完整的双向交互

Stateless HTTP

每次HTTP请求相互独立
→ 不维护协议级会话
→ 任意实例都可以处理

选择传输方式,不能只看“哪个更新”,而要看业务交互模型。

二、STDIO适合什么场景

适合:

  • 桌面AI客户端;
  • 本地文件工具;
  • 本地Git工具;
  • 本地数据库开发环境;
  • CLI;
  • 单机插件;
  • 不希望开放网络端口。

配置通常需要:

command
args
environment
working_directory

示意:

{
  "command": "java",
  "args": [
    "-jar",
    "local-tools.jar"
  ]
}

优点

  • 网络攻击面小;
  • 部署简单;
  • 凭证可留在本机;
  • 与桌面客户端生命周期一致;
  • 调试方便。

缺点

  • 每个客户端都要部署一份;
  • 升级困难;
  • 难以统一审计;
  • 不适合共享企业服务;
  • 子进程崩溃会中断工具;
  • 资源占用随客户端增加。

三、Streamable HTTP适合什么场景

适合:

  • 远程共享MCP Server;
  • 需要Sampling;
  • 需要Elicitation;
  • 服务端需要向客户端发送请求或通知;
  • 复杂Agent交互;
  • 会话中持续报告进度;
  • 长时间连接。

Spring AI服务端:

spring:
  ai:
    mcp:
      server:
        protocol: STREAMABLE

优点

  • 远程集中部署;
  • 支持更丰富的双向能力;
  • 适合复杂Agent;
  • 便于统一安全与审计;
  • 可以共享后端资源。

缺点

  • 需要管理逻辑会话;
  • 负载均衡更复杂;
  • 连接和超时配置更复杂;
  • 滚动升级需要考虑会话;
  • 网关可能缓冲流式响应;
  • 断线恢复设计更复杂。

四、Stateless HTTP适合什么场景

Spring AI:

spring:
  ai:
    mcp:
      server:
        protocol: STATELESS

适合:

  • 查询订单;
  • 查询库存;
  • 获取客户信息;
  • 检索知识库;
  • 计算报价;
  • 生成短报告;
  • 高并发只读工具;
  • 云原生微服务。

优点

  • 普通Round-Robin负载均衡;
  • 不需要Sticky Session;
  • 实例可快速扩缩;
  • 容器故障恢复简单;
  • 更适合Serverless;
  • 网关和监控更标准。

限制

无状态服务端通常不支持需要服务端主动回调客户端的能力,例如:

  • Sampling;
  • Elicitation;
  • 部分双向通知;
  • 连接级交互。

业务状态仍需保存到:

  • 数据库;
  • Redis;
  • 工作流引擎;
  • 任务服务。

五、三种方式对比

维度 STDIO Streamable HTTP Stateless HTTP
典型部署 本地进程 远程服务 云原生远程服务
协议会话 进程连接 通常存在 不存在
水平扩容 不适用 较复杂 最简单
双向能力 可用 最完整 受限
Sampling 可支持 可支持 通常不支持
Elicitation 可支持 可支持 通常不支持
网络暴露 无远程端口
统一审计 较难 容易 容易
客户端安装 需要 不需要 不需要
适合高并发查询 一般 可以 最适合

六、不要把业务状态与协议状态混淆

订单审批工具即使使用Stateless HTTP,业务仍然有状态:

DRAFT
→ PENDING_APPROVAL
→ APPROVED
→ EXECUTED

这些状态应该由业务系统保存。

错误:

private final Map<String, ApprovalState> states =
        new ConcurrentHashMap<>();

容器重启后全部丢失。

正确:

MCP Server无状态
+审批状态进入数据库

七、Sampling与Elicitation决定传输选择

Sampling

MCP Server请求客户端调用模型。

例如:

工具读取复杂数据
→ 请求客户端模型总结
→ 服务端继续处理

Elicitation

服务端请求用户补充结构化信息。

例如:

退款工具发现缺少退款原因
→ 请求客户端向用户提问
→ 用户填写
→ 工具继续

如果业务强依赖这两种能力,不应优先选择Stateless。

八、企业远程服务为什么通常不选STDIO

企业工具需要:

  • 统一版本;
  • 统一权限;
  • 统一审计;
  • 数据库连接池;
  • 高可用;
  • 灰度发布;
  • 限流;
  • 服务发现。

如果每个客户端本地启动一个MCP Server:

工具版本不一致
凭证散落
日志分散
权限难以撤销
升级依赖用户

因此,订单、客户、仓储、财务类工具更适合远程服务。

九、什么时候选择WebMVC,什么时候选择WebFlux

WebMVC

适合:

  • 阻塞式业务系统;
  • JDBC;
  • 普通请求—响应;
  • 团队熟悉Servlet;
  • 工具并发中等。

WebFlux

适合:

  • 大量并发连接;
  • 流式响应;
  • 异步I/O;
  • Reactive数据源;
  • 多个远程调用组合。

不能只因为MCP支持流式就强制使用WebFlux。

如果底层全部是阻塞JDBC和同步SDK,错误使用WebFlux可能造成Event Loop阻塞。

十、网关层需要注意什么

远程HTTP方式需要配置:

  • 请求体大小;
  • 流式缓冲;
  • 连接超时;
  • 读取超时;
  • 请求头转发;
  • OAuth Token;
  • CORS;
  • WAF规则;
  • 负载均衡;
  • Trace ID。

Stateless方式可以按请求路由。

Streamable方式还需要考虑:

  • 长连接;
  • 会话亲和;
  • 断线重连;
  • 连接排空;
  • 滚动发布。

十一、安全差异

STDIO

风险:

  • 本地命令注入;
  • 环境变量泄露;
  • 文件权限;
  • 恶意子进程;
  • 自动启动不可信程序。

HTTP

风险:

  • 未授权访问;
  • Token泄露;
  • 重放;
  • 跨租户;
  • 网关绕过;
  • SSRF;
  • 公网暴露。

远程服务至少需要:

TLS
OAuth 2.0或API Key
最小Scope
租户校验
工具级权限
审计

十二、成本与运维

STDIO

成本分散到客户端机器,服务端基础设施少,但维护成本高。

Streamable HTTP

需要连接管理、会话管理和更复杂的容量规划。

Stateless HTTP

最接近普通微服务,容易使用现有Kubernetes、网关和APM体系。

十三、选型决策树

工具只在本机使用?
→ STDIO

需要远程共享?
→ HTTP

服务端必须主动向客户端请求Sampling或Elicitation?
→ Streamable HTTP

主要是独立请求—响应,并要求简单扩容?
→ Stateless HTTP

十四、推荐组合

一个企业可以同时使用三种方式:

本地代码与文件工具
→ STDIO

复杂交互与长会话Agent
→ Streamable HTTP

订单、库存、客户、知识查询
→ Stateless HTTP

MCP的价值就是使用统一协议连接不同部署形态,而不是强迫所有工具使用同一传输。

十五、迁移建议

从SSE旧传输迁移:

确认客户端支持Streamable HTTP
→ 建立新入口
→ 双入口运行
→ 测试工具发现和调用
→ 灰度切换
→ 下线SSE

从有状态迁移无状态:

盘点进程内状态
→ 状态外置
→ 移除会话依赖
→ 测试任意实例处理
→ 关闭Sticky Session

总结

三种MCP传输的核心定位是:

STDIO
→ 本地、进程级、低网络暴露

Streamable HTTP
→ 远程、会话型、双向能力

Stateless HTTP
→ 远程、无状态、云原生扩容

正确选型应从业务交互和部署要求出发,而不是简单选择最新的协议模式。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐