Skip to main content
Glama
zq4282

mcp-stateless-http-demo

by zq4282

mcp-stateless-http-demo

基于 MCP 2.0 SDK无状态 Streamable HTTP 最小可运行示例,并落地了 2026-07-28 协议大版本 的关键新特性。

约束遵循 项目开发文档.md(SDD):无 stdio、无 SSE、无 session-id、无 LLM。

一、项目定位:新版本要解决什么

MCP 协议在 2026-07-28 迎来了一次大版本升级(协议 era 从 2024/2025 演进到 2026-07-28)。本项目是这次升级的最小落地示范,用一套可运行的 Server + Client 验证"现代协议时代"的完整交互流程,重点回答三件事:

  • 协议怎么变 —— 移除 initialize 握手、改走 server/discover,请求自动携带协议版本头;

  • 架构怎么变 —— 从"有状态会话"变为"无状态请求自包含",服务端零会话存储;

  • 生产能力补了什么 —— 工具列表缓存、W3C Trace Context 分布式追踪、单行请求/响应日志、MCP Apps 交互式 UI。

能力

解决的问题

以前 MCP(传统模式)

新方向(Server/Capability 模式)

对 Agent / Planner 的影响

ChatBI 示例

1. 动态发现(Dynamic Discovery)

工具和服务越来越多,不想全部写死

Client 先知道有哪些 Server,然后调用 tools/list 获取工具

Client 可以先发现业务能力 / Server,再发现 Server 下的 Tool

Planner 不需要维护所有工具清单,可以根据任务找到对应能力

用户问“分析销售下降原因”,先发现 Sales Analytics Server,再选择 analyze_growth

核心变化

发现范围扩大

Server → Tools

Capability → Server → Tools

从“找工具”变成“找解决问题的能力”

从找 query_sales,变成找“销售分析能力”

2. Server 自描述能力增强(Server Self Description)

Agent 不知道一个 Server 能干什么

Tool 有 namedescriptioninputSchema

Server 自己描述领域、业务对象、能力范围、权限、工具集合

Planner 可以理解业务边界,不只是看到工具名字

Sales MCP Server 描述:负责销售领域,支持收入、订单、客户分析

核心变化

描述粒度提升

Tool 级描述

Server / Domain 级描述

LLM 可以先理解“这个服务适合解决什么问题”

不只是看到 query_sales,而知道“这是销售分析领域能力”

3. 对 Agent Planner 更友好(Planner-oriented)

Tool 数量爆炸,Prompt 塞不下

Planner Prompt 中维护大量工具列表

Planner 根据当前任务加载相关能力和工具

Planner 从“工具选择”升级为“能力选择 + 工具选择”

先选择 Sales Analytics 能力,再选择 query_sales、analyze_growth

一句话总结新版本的价值:

旧版本演示"MCP 怎么跑起来";新版本演示"MCP 在 2026-07-28 时代该怎么设计"——无状态、可观测、可缓存、可交互。

Related MCP server: API MCP Server

二、新版本特性总览(功能 + 意义)

能力

说明

意义

MCP Server / Client

分别位于 server/client/

一个仓库同时示范两端,闭环验证协议

Streamable HTTP

http://localhost:8000/mcp,仅 POST

单一 HTTP 端点,对网关/防火墙友好

Stateless(无状态)

服务端不保存 session、不产生 mcp-session-id,每个请求自包含

无共享状态 → 天然支持水平扩展、容器化/边缘部署,故障恢复简单

现代协议 era(2026-07-28)

客户端用 server/discover 握手,移除 initialize,自动发送 Mcp-Method / Mcp-Name / Mcp-Protocol-Version

单请求完成握手、请求自描述,连接更快、更贴近 REST 语义

Tools

add multiply query_order list_orders get_user semantic_query

覆盖算术、业务查询、语义查询(§13 Phase 2 预览)

Resource

resource://company/profile(静态)、resource://orders/{order_id}(模板)

数据资源化访问,支持动态参数

Prompt

welcomeorder_analysis(order_id)

提示词模板化,便于复用 LLM 引导

MCP Apps(2026-07-28)

orders_table 工具绑定 ui://orders/table HTML 资源

工具输出从"纯文本"升级为"可交互界面"

tools/list 缓存(2026-07-28)

响应带 _meta.ttlMs / cacheScope

减少重复拉取,降低 LLM 应用的延迟与带宽

W3C Trace Context(2026-07-28)

OpenTelemetry 分布式追踪,客户端 span 跨进程级联到服务端

端到端链路可观测,生产排障必备

请求/响应日志

每个 JSON-RPC 请求打印 [REQ] / [RESP](单行、可 grep)

审计友好,无需额外中间件即可排查问题

三、与旧版本对比:优势一目了然

旧时代 = 2024/2025 协议(基于 initialize + 会话);现代时代 = 2026-07-28 协议。

维度

旧时代(2024/2025)

现代时代(2026-07-28)

新版本优势

握手方式

initialize 协商,需维护握手状态

server/discover 单请求完成

少一轮往返、更简单,接近普通 HTTP 调用

会话模型

有状态,携带 mcp-session-id

无状态,每个请求自包含

可水平扩展、部署/运维简化、无粘性会话需求

传输格式

默认 SSE 流式响应

Streamable HTTP,支持 json_response=True 返回纯 JSON

客户端实现简单,任何 HTTP 栈都能对接

方法路由

靠请求体 method 字段识别

自动带 Mcp-Method / Mcp-Name / Mcp-Protocol-Version

网关/代理可直接按头路由,无需解析 body

工具列表

每次全量拉取

ttlMs / cacheScope 缓存提示

减少重复请求,LLM 应用首屏响应更快

UI 能力

仅文本/结构化输出

MCP Apps(ui:// 交互式 HTML)

工具结果可渲染成可操作界面,而非静态文本

可观测性

无标准追踪

W3C Trace Context(OTel)

跨进程分布式追踪,一个 trace_id 贯穿两端

请求审计

[REQ] / [RESP] 单行中间件

可直接 grep、可审计,无需额外部署

核心结论:新版本不是在旧模型上打补丁,而是把 MCP 的传输层、握手层、能力层全部升级——从"会话式 RPC"变成"无状态可观测的 HTTP 风格协议",这让 MCP Server 可以像普通 Web 服务一样部署、扩容、排障。

目录结构

.
├── 项目开发文档.md          # SDD 规范(§5/6/7/8 为实现依据)
├── pyproject.toml          # 依赖(mcp[cli]>=2.0.0、fastapi、uvicorn、opentelemetry-sdk)
├── README.md
├── server/                 # MCP Server
│   ├── main.py             # 入口 + McpServerLauncher 启动类
│   ├── tools.py            # 工具 / 资源 / 提示词 / MCP Apps 定义
│   ├── logging_middleware.py  # 请求/响应日志中间件(ServerMiddleware)
│   └── tracing.py          # OpenTelemetry 追踪配置(Console/OTLP 导出)
└── client/                 # MCP Client
    ├── main.py             # discover → list → call 流程演示
    └── tracing.py          # 客户端追踪 + W3C traceparent 注入

快速开始

环境:Python 3.12+,包管理用 uv

# 1. 安装依赖
uv sync

# 2. 启动服务端(终端 1)
.venv/bin/python server/main.py
#   -> Uvicorn running on http://127.0.0.1:8000
#   或使用启动类自定义端口:
#   .venv/bin/python -c "from server.main import McpServerLauncher; McpServerLauncher(port=9000).run()"

# 3. 运行客户端(终端 2)
.venv/bin/python client/main.py

客户端预期输出:

[Connected] modern protocol, supported=2026-07-28
  client root span: 337fa235c2870945c7d857160f4dd58b
[Available Tools] orders_table, add, multiply, query_order, list_orders, get_user, semantic_query
  [cache] tools/list ttlMs=300000 cacheScope=public
[Available Resources] ui://orders/table, resource://company/profile
[Available Prompts] welcome, order_analysis
[call] add(10, 20) -> 30
[call] query_order('10001') -> {...}
[resource] company/profile -> ...
[mcp-app] ui://orders/table -> <!DOCTYPE html>...
[prompt] order_analysis('10003') -> ...
[error] unknown tool -> is_error=True: Unknown tool: unknown

注意输出中的 [cache] tools/list ttlMs=300000 cacheScope=public[mcp-app] ui://orders/table——这两行就是 2026-07-28 新特性(缓存提示、MCP Apps)的实际效果。

架构与协议流程

MCP Client(modern era)
   │  discover(server/discover) ── Mcp-Method / Mcp-Protocol-Version 头,无会话
   │  list_tools / call_tool / read_resource / get_prompt
   ▼  (每个请求自包含:capabilities/clientInfo 放 _meta,带 traceparent)
MCP Server(stateless_http=True, json_response=True)
   │  OpenTelemetryMiddleware 提取 traceparent 建 span
   │  RequestResponseLoggingMiddleware 打印 [REQ]/[RESP]
   ▼
Tools / Resources / Prompts / MCP Apps(MCPServer 注册)

协议时代说明:SDK 2.0 支持"双时代"——首个请求是 initialize 走旧协议(2024/2025 版本), 首个请求是 server/discover(或带 2026 封装的请求)则进入现代 era(2026-07-28)。 本 demo 客户端显式走现代 era。

2026-07-28 新特性实现细节

1. 无状态化 + 移除 initialize 握手

  • 服务端:streamable_http_app(stateless_http=True) —— 每次请求新建 transport,零会话存储。

  • 客户端:session.discover() 替代 session.initialize() —— 请求自动携带 Mcp-Protocol-Version / Mcp-Method / Mcp-Name 头。

  • 验证:裸 curl -Dmcp-session-id 响应头;连续请求各自独立。

2. tools/list 缓存(ttlMs / cacheScope)

server/tools.py 中:

cache_hints={
    "tools/list": CacheHint(ttl_ms=300_000, scope="public"),
    "server/discover": CacheHint(ttl_ms=60_000, scope="public"),
}

响应会带上 cacheScope/ttlMs;客户端可据此缓存 tools/list 结果 5 分钟。

3. MCP Apps(交互式 HTML 工具)

apps = Apps()
@apps.tool(resource_uri="ui://orders/table")
async def orders_table() -> list[dict]: ...
apps.add_html_resource("ui://orders/table", html, ...)
mcp = MCPServer(..., extensions=[apps])

宿主(如 Claude Desktop)在沙箱 iframe 渲染 ui:// HTML,经 postMessage + JSON-RPC 双向通信,把工具返回的数据渲染成可交互表格。本 demo 是文本客户端,只能读取 HTML 源文件, 不渲染界面。

4. W3C Trace Context(OTel)

  • 服务端:SDK 内置 OpenTelemetryMiddleware 为每个请求建 span (mcp.method.name / mcp.protocol.version / gen_ai.tool.name)。

  • 客户端:trace_meta()opentelemetry.propagate.injecttraceparent 写进每个请求的 _meta,服务端 extract 出上下文 → 服务端 span 挂到客户端 span 下。

  • 观察:客户端与服务端日志中 span 共享同一 trace_id,且 parent_id 指向客户端对应请求 span。

  • 导出器:默认 ConsoleSpanExporter(打印 span);设置环境变量 OTEL_EXPORTER_OTLP_ENDPOINT 可切换为 OTLP(需另装 opentelemetry-exporter-otlp-proto-http)。

请求/响应日志

server/logging_middleware.py 基于 SDK 的 ServerMiddleware 协议实现, 在每个 JSON-RPC 请求前后记录方法与参数/结果(单行、长内容截断到 500 字符):

08/01 15:54:43 INFO    [REQ ] id=5 method=tools/call params={"name": "add", "arguments": {"a": 10, "b": 20}, "_meta": {...}}
08/01 15:54:43 INFO    [RESP] id=5 method=tools/call result={"content": [{"text": "30", "type": "text"}], "isError": false, ...}

处理失败时记 [RESP] ... error=... 后原样抛出。

验证清单(AC)

  • AC-001 服务端启动:python server/main.pyUvicorn running on http://127.0.0.1:8000

  • AC-002 客户端连接:[Connected] ...

  • AC-003 工具发现:add, multiply, query_order, list_orders, get_user, semantic_query(+ orders_table)

  • AC-004 工具调用:add(10, 20) -> 30

  • AC-005 无状态验证:无 mcp-session-id,连续请求独立

  • §10 错误场景:未知工具/非法参数以 is_error=True 结果返回

  • 2026 新特性:现代协议 era、tools/list 缓存、MCP Apps、W3C Trace Context

注意事项

  1. 文本客户端无法渲染 MCP Apps 界面;想看交互式 UI 需使用支持 MCP Apps 的宿主。

  2. OTel span 由 BatchSpanProcessor 异步导出,打印可能晚于请求执行。

  3. 客户端 span 输出会混在演示输出里(结尾统一 flush),属正常现象。

  4. _ORDERS / _USERS 为只读演示数据(相当于 mock 数据库),不违反无状态要求。

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    A minimal demonstration server showcasing MCP protocol capabilities including tools, resources, and prompts with basic examples like hello world functionality.
    Last updated
    2
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    A Model Context Protocol server that provides basic tools for arithmetic operations (addition) and dynamic greeting resources, demonstrating MCP integration patterns for other projects and clients.
    Last updated
    6
    ISC
  • F
    license
    -
    quality
    D
    maintenance
    A minimal Model Context Protocol (MCP) server that uses streamable HTTP transport to provide demo tools for calculations, notes, and time. It serves as a standalone example for testing MCP connectivity and gateway registration through a standard HTTP endpoint.
    Last updated
  • A
    license
    -
    quality
    D
    maintenance
    A foundational Model Context Protocol server demonstrating core functionality through basic arithmetic tools and personalized greeting resources. It serves as a template for developers learning to build and deploy MCP-enabled AI applications.
    Last updated
    GPL 3.0

View all related MCP servers

Related MCP Connectors

  • AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.

  • Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.

  • Read-only MCP server for the WebAssembly spec: instructions, types, sections, search, proposals.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zq4282/McpPython'

If you have feedback or need assistance with the MCP directory API, please join our Discord server