Skip to content

Convert _meta on initialize to Meta (1.x). Refs #54 - #64

Merged
logiscapedev merged 1 commit into
logiscape:1.xfrom
peter-gribanov:fix/1.x-initialize-meta-typeerror
Jul 28, 2026
Merged

Convert _meta on initialize to Meta (1.x). Refs #54#64
logiscapedev merged 1 commit into
logiscape:1.xfrom
peter-gribanov:fix/1.x-initialize-meta-typeerror

Conversation

@peter-gribanov

Copy link
Copy Markdown

Summary

ClientRequest::createInitializeRequest() on the 1.x line passes the decoded _meta array straight into the ?Meta parameter of InitializeRequestParams, so an initialize request carrying _meta aborts with a TypeError during validation. This converts it through the existing extractMeta() helper — the same fix that already exists on main (v2) — and adds a regression test.

Motivation

Refs #54. That issue was closed with "should be fixed in the latest release", but the fix only ever landed on main: on 1.x (up to and including v1.7.4) line 192 is still _meta: $params['_meta'] ?? null, while every other request family — resources/read, resources/subscribe, tools/call, … — already goes through extractMeta() / an equivalent new Meta() loop.

Real-world impact: initialize is allowed to carry _meta (SEP-414 trace context on any request), and Claude's web client now does — it attaches traceparent, baggage and x-cloud-trace-context to the handshake:

{"id":1,"jsonrpc":"2.0","method":"initialize","params":{
  "_meta":{"traceparent":"00-0cb6548322595e40d670720bbba87ac4-c8a51f90c9021bec-01","baggage":"sentry-trace_id=…"},
  "capabilities":{},"clientInfo":{"name":"Anthropic/ClaudeAI","version":"1.0.0"},
  "protocolVersion":"2025-11-25"}}

Which fails before the server can answer anything:

TypeError: Mcp\Types\InitializeRequestParams::__construct(): Argument #4 ($_meta)
must be of type ?Mcp\Types\Meta, array given, called in
.../src/Types/ClientRequest.php on line 188
#13 src/Types/InitializeRequestParams.php(32)
#12 src/Types/ClientRequest.php(188): createInitializeRequest
#11 src/Types/ClientRequest.php(94):  fromMethodAndParams
#10 src/Shared/BaseSession.php(441):  validateIncomingRequest
#9  src/Shared/BaseSession.php(368):  handleIncomingMessage
#8  src/Server/HttpServerSession.php(175)
#7  src/Shared/BaseSession.php(86)
#6  src/Server/ServerSession.php(120)
#5  src/Server/HttpServerRunner.php(183)
#4  src/Server/Transport/Http/StandardPhpAdapter.php(62)
#3  src/Server/McpServer.php(724):     runHttp

Since it happens on the handshake, the whole connection is unusable — such clients cannot talk to a 1.x server at all. Note the TypeError also escapes StandardPhpAdapter::handle(), which catches \Exception only, so the embedder sees a fatal rather than a JSON-RPC error.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • Minor feature or improvement (non-breaking, additive)
  • Major feature (non-breaking but substantial — requires a minor version bump)
  • Expanded MCP protocol version support (adopting a new spec revision — requires a minor version bump)
  • Breaking change (public API or documented flow — requires a minor version bump)
  • Documentation only
  • Tooling / CI only

Versioning impact

  • Patch (v1.7.X) — non-breaking bug fix or minor feature/improvement
  • Minor (v1.X) — breaking change, major new feature, or expanded MCP protocol version support
  • Major (v2) — aligned with a wider MCP ecosystem v2 (not chosen unilaterally)

Test plan

  • composer check passes locally — 840 tests / 3159 assertions, PHPStan clean
  • composer conformance passes locally (or documented baseline change included) — not run: no Node.js available in the environment I had. The change is confined to one params-construction call site in ClientRequest, no baseline files touched; happy to have CI or a maintainer run the suite.
  • Relevant unit tests added or updated — tests/Types/ClientRequestInitializeMetaTest.php: array _meta becomes Meta with fields preserved (and the request still validate()s), absent _meta stays null, non-array _meta is ignored instead of fatal. All three fail on 1.x without the source change (the first two with exactly the TypeError above).
  • Spot-checked with the MCP Inspector — not run.
  • Smoke-tested against a real MCP client — the failing request above is real production traffic from Claude's web client against a v1.7.1 server; the fix itself is so far verified by the unit tests only.

Compatibility

  • Change preserves core-feature compatibility under cPanel / Apache / PHP-FPM
  • If this introduces a feature that cannot work under shared hosting, it fails gracefully (typed exception, not a fatal error) — n/a
  • No new required runtime dependencies (or new dependency justified in the PR)

Documentation

  • Updated README.md if the public API or usage changed — n/a, no public API change
  • Added an entry to CHANGELOG.md under [Unreleased]
  • Updated anything under docs/ that this PR contradicts — nothing contradicted
  • Updated AGENTS.md / CLAUDE.md if the contributor-facing guidance changed — n/a

Additional notes

The inline comment is adapted from the v2 call site; I dropped its reference to the modern-envelope probe path, which doesn't exist on 1.x.

Two things you may want to decide separately:

  1. Whether _meta data leads to type error in ClientRequest.php #54 should be reopened until this ships on 1.x — anyone on the stable line still hits it.
  2. Whether StandardPhpAdapter::handle() should catch \Throwable rather than \Exception, so a future Error in the parse path degrades into a JSON-RPC error response instead of a fatal. Not touched here to keep this PR to one logical change.

🤖 Generated with Claude Code

`ClientRequest::createInitializeRequest()` passed the decoded `_meta` array
straight into the `?Meta` parameter of `InitializeRequestParams`, so any
`initialize` request carrying `_meta` died with a TypeError during
validation, before the handshake could be answered. Every other request
family already converted `_meta` through `extractMeta()`.

Clients that attach trace context to the handshake (SEP-414; Claude's web
client sends `traceparent` / `baggage` there) could not connect at all.

Backported from the v2 line, where the same call site already uses
`extractMeta()`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@peter-gribanov
peter-gribanov force-pushed the fix/1.x-initialize-meta-typeerror branch from 3dfc9b0 to 2dc2ad5 Compare July 27, 2026 13:04
@logiscapedev logiscapedev self-assigned this Jul 28, 2026
@logiscapedev
logiscapedev merged commit 2aeedac into logiscape:1.x Jul 28, 2026
7 checks passed
@peter-gribanov
peter-gribanov deleted the fix/1.x-initialize-meta-typeerror branch July 28, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants