Skip to content
Cockpit0.29.0
A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live

I2147

The MCP transports bound what they read and follow the Streamable HTTP rules they claim

Where it stands

devtask.issue
Readiness
complete completion is recorded and every required evidence token is present
Status
DONE
Can start
not now
Milestone
Milestone status
VERIFY
Wave
0
Waiting on
none
Holds back
none
Behind it in all
0
Evidence
3 of 3
A move writes the repository: it stamps one field of this issue's record and appends one event to the ledger, and a commit will carry both.
The same moves from a terminal

majordomus plan start I2147

majordomus plan verify I2147

majordomus plan done I2147

What it is

Objective
Apply one declared message bound to stdin lines, request bodies and every response the bridge reads, validate MCP-Protocol-Version, issue unpredictable session ids, and never reap a session whose request is still running.
Why
Bounds are asymmetric. stdin lines have no length bound (apps/majordomus-cli/src/mcp/stdio.rs:40); request bodies are capped at 1 MiB (apps/majordomus-cli/src/http/server.rs:20,207-214) but the owner's in-process stdio session is not; responses the bridge reads have no cap (apps/majordomus-cli/src/mcp/bridge.rs:85, read_to_end), and the mesh's rendezvous and link replies go through the same function (apps/majordomus-cli/src/mcp/bridge.rs:84-85). On the Streamable HTTP endpoint the MCP-Protocol-Version and Accept headers are ignored, session ids are pid-seq-subsecnanos and predictable (apps/majordomus-cli/src/http/mcp.rs:159), and the 90 s idle reaper can expire a session whose single request is still running, because last_seen is stamped only when a request starts (apps/majordomus-cli/src/http/mcp.rs:138). Baseline audit of 2026-10-09 at master 1fb8d6be44, lifecycle gap 14, the payload-limit row and the Streamable HTTP row.
Now
One oversized line or response can exhaust a client or a server; a long request can lose its session.
Wanted
stdio lines are bounded at MAX_LINE_BYTES (the HTTP body bound, 1 MiB) and an over-long one is answered with a parse error while the session goes on; every reply bridge::request reads is bounded at MAX_REPLY_BYTES (32 MiB) — the stdio bridge, rendezvous and mesh links alike; MCP-Protocol-Version is validated against PROTOCOL_VERSIONS (400 otherwise); session ids are 128 bits from the OS random source; last_seen is stamped again when the answer is written. Not done here: the Accept header and the GET/SSE half of Streamable HTTP.
Done when
unknown: the record declares no `completion`
Risk
unknown: the record declares no `risk`

Acceptance

  • A stdin line, a request body and a response body each one byte over the declared bound are refused with a typed error, and the session survives
  • A request naming an unsupported MCP-Protocol-Version is answered 400
  • A session whose single request runs longer than the reap interval is not reaped
  • Session ids are drawn from the operating system's random source
Validation
bin/majordomus plan validatecargo test --test mcp_conformance --test mcp_conformance_http --test mcp_stdio
Evidence required
transport_bounds_testprotocol_version_header_testlong_request_not_reaped_test
Evidence present
transport_bounds_testprotocol_version_header_testlong_request_not_reaped_test

Scope

Touches
apps/majordomus-cli/src/mcp/stdio.rsapps/majordomus-cli/src/mcp/bridge.rsapps/majordomus-cli/src/http/mcp.rsapps/majordomus-cli/src/http/server.rsapps/majordomus-cli/tests/mcp_conformance.rsapps/majordomus-cli/tests/mcp_conformance_http.rsdocs/MCP.md
Not
unknown: the record declares no `non_scope`
Depends on
none
Priority
p2
Profile
implementation
Parallel safe
false
Owner
unknown: the record declares no `owner`

The work so far

Branches
none
Merged
none
Commits
0
Trunk
master
Sessions
none
Created
2026-10-09
Updated
2026-10-14T23:26:47Z
Started
2026-10-14T23:26:13Z
Verified
2026-10-14T23:26:24Z
Completed
2026-10-14T23:26:47Z

Synchronisation

Adapter
scripts/github-sync
Repository
unknown: the derived plan's header carries no repository
External issue
unknown: a live GitHub state; this executable makes no network call, so only `scripts/github-sync --check` can answer it
State there
unknown: a live GitHub state; this executable makes no network call, so only `scripts/github-sync --check` can answer it

Findings

Nothing is wrong with these records.