modelcontextprotocol / modelcontextprotocol/php-sdk

Streamable HTTP server does not validate body/header protocol-version consistency on initialize

未关闭
#309 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

bug
主要语言
PHP
星标
1.6k
派生
173
平均合并
2 天 49 分钟
30 天内合并 PR
23

描述

Describe the bug

When the initial initialize request carries an MCP-Protocol-Version HTTP header that disagrees with initialize.params.protocolVersion in the JSON-RPC body, the server accepts the request without error. In both mismatch directions, the server returned 2025-06-18 as the negotiated version rather than following either input value.

The current MCP 2025-11-25 specification does not explicitly require the server to check body/header consistency on initialize, so this is filed as an implementation observation rather than a strict spec-violation claim.

  • Environment
    • Reproduced with stable releasev0.5.0 (fb2c8c2e)
    • Also reproduced with a main snapshot from 2026-05-16 (5e0731f7)
    • Transport: Streamable HTTP server (stateful profile)

To reproduce

  1. Start a PHP SDK Streamable HTTP server.
  2. Send an initialize request where the body protocolVersion is 2025-11-25 but the MCP-Protocol-Version header is 2025-03-26 (or vice versa).
  3. Observe that the server returns HTTP 200 with a normal initialize result.
  4. Check the negotiated protocol version in the response.

Expected behavior

Option A: the server rejects the mismatch before negotiation, for example with HTTP 400 or a JSON-RPC Invalid Request error.

Option B: the spec clarifies which field is authoritative, and the SDK documents that behavior and covers it with a regression test.

Logs

Both mismatch directions were accepted:

body=2025-11-25 header=2025-03-26 -> HTTP 200, negotiated version = 2025-06-18 (server-determined)
body=2025-03-26 header=2025-11-25 -> HTTP 200, negotiated version = 2025-06-18 (server-determined)

The server returned its own preferred protocol version (2025-06-18) regardless of both the body and header values. In these tests, the negotiated version was server-determined rather than derived from either mismatched input.

With a Streamable HTTP server running, set ENDPOINT to the server endpoint and send an initial initialize request whose HTTP header and JSON-RPC body disagree:

ENDPOINT=http://127.0.0.1:8080/mcp

curl -i -sS --http1.1 -X POST "$ENDPOINT" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-03-26' \
  --data '{"jsonrpc":"2.0","id":"init-conflict-1","method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"version-conflict-repro","version":"0.1.0"}}}'

Repeat with the values reversed: body 2025-03-26, header 2025-11-25.

Additional context

  • Related: SEP-2575 introduces a related future-state requirement that, for HTTP requests, the MCP-Protocol-Version header match _meta["io.modelcontextprotocol/protocolVersion"].

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先定位 PHP SDK 中 Streamable HTTP 服务器对 initialize 请求的处理,并使用提供的 curl 命令在两个方向上复现不匹配。决定应拒绝不匹配,还是将其记录为使用权威字段,然后为所选行为添加覆盖测试,并验证协商版本响应。

由索引模型根据 Issue 内容生成。

评估

技术栈
php
领域
api, backend
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
48/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。