I2147 — Transporty MCP omezují, co čtou, a dodržují pravidla Streamable HTTP, která si nárokují
Použít jeden deklarovaný limit zprávy na řádky stdin, těla požadavků i každou odpověď, kterou bridge čte, validovat MCP-Protocol-Version, vydávat nepředvídatelná id relací a nikdy neukončit relaci, jejíž požadavek stále běží.
HOTOVO vlna 0 · p2 · profil implementation · běží samostatně
Cíl
Použít jeden deklarovaný limit zprávy na řádky stdin, těla požadavků i každou odpověď, kterou bridge čte, validovat MCP-Protocol-Version, vydávat nepředvídatelná id relací a nikdy neukončit relaci, jejíž požadavek stále běží.
Proč
Meze jsou asymetrické. Řádky stdin nemají omezenou délku (apps/majordomus-cli/src/mcp/stdio.rs:40); těla požadavků jsou omezena na 1 MiB (apps/majordomus-cli/src/http/server.rs:20,207-214), ale vlastníkova in-process stdio relace ne; odpovědi, které bridge čte, nemají strop (apps/majordomus-cli/src/mcp/bridge.rs:85, read_to_end) a odpovědi rendezvous a linku meshe procházejí toutéž funkcí (apps/majordomus-cli/src/mcp/bridge.rs:84-85). Na koncovém bodu Streamable HTTP jsou hlavičky MCP-Protocol-Version a Accept ignorovány, id relací jsou pid-seq-subsecnanos a předvídatelná (apps/majordomus-cli/src/http/mcp.rs:159) a 90s idle reaper může nechat vypršet relaci, jejíž jediný požadavek ještě běží, protože last_seen se razítkuje jen při začátku požadavku (apps/majordomus-cli/src/http/mcp.rs:138). Audit základní linie z 2026-10-09 na masteru 1fb8d6be44, mezera životního cyklu 14, řádek o limitu payloadu a řádek o Streamable HTTP.
Aktuální stav
Jeden předimenzovaný řádek nebo odpověď může vyčerpat klienta nebo server; dlouhý požadavek může ztratit svou relaci.
Cílový stav
řádky stdio jsou omezeny na MAX_LINE_BYTES (mez těla HTTP, 1 MiB) a příliš dlouhý je zodpovězen chybou parsování, zatímco relace pokračuje; každá odpověď, kterou čte bridge::request, je omezena na MAX_REPLY_BYTES (32 MiB) — stdio most, rendezvous i linky mesh stejně; MCP-Protocol-Version se validuje proti PROTOCOL_VERSIONS (jinak 400); id relací mají 128 bitů ze zdroje náhody OS; last_seen se razítkuje znovu při zápisu odpovědi. Zde nehotovo: hlavička Accept a polovina GET/SSE Streamable HTTP.
Rozsah
- apps/majordomus-cli/src/mcp/stdio.rs
- apps/majordomus-cli/src/mcp/bridge.rs
- apps/majordomus-cli/src/http/mcp.rs
- apps/majordomus-cli/src/http/server.rs
- apps/majordomus-cli/tests/mcp_conformance.rs
- apps/majordomus-cli/tests/mcp_conformance_http.rs
- docs/MCP.md
Závislosti
Žádné. Tento úkol je kořenem grafu.
Kritéria přijetí
- Řádek stdin, tělo požadavku a tělo odpovědi, každé o jeden bajt nad deklarovanou mezí, jsou odmítnuty typovanou chybou a relace přežije
- Požadavek jmenující nepodporovanou MCP-Protocol-Version dostane odpověď 400
- Relace, jejíž jediný požadavek běží déle než interval úklidu, se neuklízí
- Id relací se berou ze zdroje náhody operačního systému
Validace
- bin/majordomus plan validate
- cargo test --test mcp_conformance --test mcp_conformance_http --test mcp_stdio
Požadované důkazy
- transport_bounds_test
- protocol_version_header_test
- long_request_not_reaped_test
Důkazy
| pokrývá | typ | command | výsledek | u commitu |
|---|---|---|---|---|
| transport_bounds_test | ci | cargo test --test mcp_transport_bounds | a_stdin_line_over_the_bound_is_refused_and_the_session_goes_on ... ok; a_reply_over_the_bound_is_refused ... ok — validate run 38626102499 (success) on master e8505a431d, job rust (3) 116065669794; transport code unchanged to c0e3585dc8; delivered by 9e018a302b1 | c0e3585 |
| protocol_version_header_test | ci | cargo test --test mcp_transport_bounds a_session_id_is_random_and_an_unknown_protocol_version_is_refused | a_session_id_is_random_and_an_unknown_protocol_version_is_refused ... ok (400 na nevyslovenou MCP-Protocol-Version; 128bitové OS-náhodné id relace) — běh validate 38626102499 (success) na masteru e8505a431d, job rust (3) 116065669794; kód transportu beze změny od c0e3585dc8; dodáno v 9e018a302b1 | c0e3585 |
| long_request_not_reaped_test | ci | cargo test --test mcp_transport_bounds a_session_is_not_reaped_behind_a_request_that_ran_long | a_session_is_not_reaped_behind_a_request_that_ran_long ... ok — běh validate 38626102499 (success) na master e8505a431d, job rust (3) 116065669794; kód transportu beze změny do c0e3585dc8; doručeno 9e018a302b1 | c0e3585 |
Časová osa
- zahájeno
- 2026-10-14T23:26:13Z
- ověřeno
- 2026-10-14T23:26:24Z
- dokončeno
- 2026-10-14T23:26:47Z
Tato tři pole, důkazy výše a stav závislostí jsou vše, z čeho se stav skládá. Neexistuje žádné pole stavu, které by s nimi mohlo být v rozporu.
Kanonický záznam: .ai/repo/project/issues/I2147.yaml. Načtěte ho zpět pomocí majordomus plan show I2147.