[PR #4955] [MERGED] feat(mcp): serve the MCP server over streamable HTTP #6691

Closed
opened 2026-11-01 21:42:20 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4955
Author: @earakely-scale
Created: 10/18/2026
Status: ✅ Merged
Merged: 10/19/2026
Merged by: @gensokyo-dev

Base: main ← Head: feat/mcp-streamable-http


📝 Commits (10+)

  • 46dd8f0 feat(mcp): serve the MCP server over streamable HTTP
  • b0ec63c fix(mcp): harden the streamable HTTP listener's session replacement and shutdown
  • 9ed8f06 fix(mcp): compare the media type proper and bind before creating the server
  • b76f354 fix(mcp): classify loopback from the bound address and keep startup failures out of onerror
  • fb22df3 fix(mcp): match Accept ranges exactly and keep a session whose shutdown failed
  • 54a7475 refactor(mcp): release the listener through one helper
  • 1741882 fix(mcp): fire the shutdown hook once, stop awaiting the probe's tee and keep every Set-Cookie
  • 354b4d8 fix(mcp): latch startup signals so the HTTP entry never ends without cleanup
  • 136d073 fix(mcp): keep a startup signal's exit status through the entry's normal return
  • a23f5f1 fix(mcp): close the connection after a reply sent before the body was read

📊 Changes

36 files changed (+5211 additions, -57 deletions)

View changed files

📝 docs/architecture.mermaid (+3 -3)
📝 docs/cli.md (+26 -0)
📝 docs/mcp-contracts.md (+92 -1)
➕ docs/specs/agent-environments/http-transport/plan.md (+32 -0)
➕ docs/specs/agent-environments/http-transport/spec.md (+79 -0)
➕ docs/specs/agent-environments/http-transport/tasks.md (+11 -0)
➕ docs/specs/agent-environments/http-transport/verification.md (+297 -0)
📝 scripts/rea.mjs (+23 -12)
➕ src/config/mcpHttpEndpoint.ts (+68 -0)
📝 src/main.ts (+117 -3)
➕ src/main/mcpHttpArguments.ts (+104 -0)
📝 src/main/messages.ts (+2 -0)
📝 src/main/processShutdown.ts (+89 -10)
📝 src/main/shutdown.ts (+6 -4)
📝 src/main/transport.ts (+18 -7)
📝 src/main/types.ts (+23 -1)
📝 src/server/EvidenceMcpServer.ts (+2 -2)
➕ src/server/RequestTrackingMcpServer.test.ts (+88 -0)
➕ src/server/RequestTrackingMcpServer.ts (+92 -0)
➕ src/server/http/NodeHttpRequestOwner.ts (+180 -0)

...and 16 more files

📄 Description

Summary

Adds rea mcp --http [--host <h>] [--port <n>] for gateway/environment hosts while keeping stdio as the default and registered transport. It serves the existing MCP catalog at /mcp, on loopback by default, with one shared active target and one client session at a time.

Direct follow-up commits remain on this original PR through ba73ccafd, with main 49b4edfe7 merged. The requesting human explicitly authorized the HTTP scope, initial readiness and merging; the original author's history and declarations remain.

Problem and expected behavior

A host that reaches MCP services over HTTP can use REA's existing tools without changing stdio registrations. DELETE or a new initialize ends the previous client session while preserving the shared target; cancelled work finishes cleanup before another session or provider teardown can reuse its resources.

Change and scope

  • Adds a node:http bridge and the pinned SDK's stateful Streamable HTTP transport, with streamed replies and Host/Origin validation classified solely from the actual bound IP, with configured aliases added afterward. HTTP is explicit; server.json, setup registrations and stdio behavior remain.
  • The shared server tracks tool and provider-backed completion callbacks through finalization. HTTP sessions also fence late message dispatch and own parsing/response cleanup. Handovers wait ten seconds and return 503 while retaining unfinished work for retry; full shutdown waits for completion.
  • The HTTP request owner admits at most eight concurrent input/route requests by default, before body conversion or initialize tees. MCP input permits end after dispatch and input settlement; plain responses retain admission through delivery and asynchronous source cleanup. Unread uploads retain admission until input completes or either side closes. Excess receives 503/connection close; queued HTTP/1.1 pipelining is disconnected before work starts. Sequential keep-alive remains supported. maxConcurrentDispatches permits an explicit embedding budget.
  • SDK body forwarding ends per request, including early refusals. Shutdown joins full exchanges, handler finalizers and response-source cancellation before provider hooks; failed cleanup retains ownership and stops new admission. All routes return 503 until the factory succeeds. HEAD cancellation stays nonblocking; a retained tee sibling must be consumed or cancelled by its caller before shutdown completes. The native byte bridge preserves reply ownership when cancelling unread input. One response writer owns its reader/cancellation across headers, pumping and completion, so output failures join the same cleanup barrier. Raw fragment delimiters are rejected before URL parsing; encoded query data is preserved.

Contract and boundary impact

  • Semantic owner: HTTP bootstrap/adapters own listener, admission and request lifetimes; the shared MCP server owns callback completion. Domain/provider contracts and Evidence shapes remain.
  • Contribution scope: inbound listener scope is tracked in #4933 and explicitly authorized by the requesting human in the implementation session. No new provider execution authority is introduced.
  • CLI/MCP: HTTP-only host/port flags and MCP_HOST/MCP_PORT fallbacks; port 0 announces the bound URL on stderr. No new MCP tool or dependency. Standard registrations stay stdio.
  • Compatibility: one shared target, plain HTTP, with explicit non-loopback binding. Environment manifest serving/export are later increments. Authored docs cover transport, CLI and architecture; generated outputs are not committed.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

Real HTTP negative controls reproduce late SDK tool dispatch, refused-body retention, admission bypass, premature handler/body cleanup, unread-upload release, startup readiness and queued pipelining. Eight negative controls for the latest response/pipelining fixes fail on the previous implementation. The fixes pass public client/reconnection, partial-upload, overload/recovery, cancellation and teardown workflows. Default stdio and catalog configurations are exercised.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.
Representative output
listening: {"transport":"streamable-http","url":"http://127.0.0.1:57093/mcp","msg":"MCP transport listening"}
--- session A ---
>>> POST /mcp  accept=application/json, text/event-stream  content-type=application/json
      body: {"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"mcp","version":"0.1.0"}},"jsonrpc":"2.0","id":0}
<<< 200 POST /mcp  content-type=text/event-stream  mcp-session-id=e6e795ba-5e0c-469a-997a-015a62d134ac
>>> POST /mcp  mcp-session-id=e6e795ba-…  body: {"method":"notifications/initialized","jsonrpc":"2.0"}
>>> GET /mcp  mcp-session-id=e6e795ba-…
<<< 202 POST /mcp
>>> POST /mcp  mcp-session-id=e6e795ba-…  body: {"method":"tools/list","jsonrpc":"2.0","id":1}
<<< 200 GET /mcp  content-type=text/event-stream  mcp-session-id=e6e795ba-…
<<< 200 POST /mcp  content-type=text/event-stream  mcp-session-id=e6e795ba-…
>>> POST /mcp  mcp-session-id=e6e795ba-…  body: {"method":"tools/call","params":{"name":"binary_session","arguments":{}},"jsonrpc":"2.0","id":2}
<<< 200 POST /mcp  content-type=text/event-stream  mcp-session-id=e6e795ba-…
[A] session=e6e795ba-5e0c-469a-997a-015a62d134ac tools=207 has_binary_session=True binary_session.isError=False
>>> DELETE /mcp  mcp-session-id=e6e795ba-…
<<< 200 DELETE /mcp
--- session B ---
>>> POST /mcp  body: {"method":"initialize",...,"id":0}
<<< 200 POST /mcp  content-type=text/event-stream  mcp-session-id=b654ce7e-9909-4937-9497-185062379fbc
>>> POST /mcp  body: {"method":"notifications/initialized",...}   <<< 202 POST /mcp
>>> GET /mcp                                                   <<< 200 GET /mcp  text/event-stream
>>> POST /mcp  body: {"method":"tools/list",...,"id":1}          <<< 200 POST /mcp  text/event-stream
>>> POST /mcp  body: {"method":"tools/call","params":{"name":"binary_session","arguments":{}},...,"id":2}   <<< 200 POST /mcp  text/event-stream
[B] session=b654ce7e-9909-4937-9497-185062379fbc tools=207 has_binary_session=True binary_session.isError=False
>>> DELETE /mcp  mcp-session-id=b654ce7e-…   <<< 200 DELETE /mcp
client exit=0
server exit=143  stdout bytes=0
server log msgs: 1 "MCP transport listening", 2 "MCP HTTP session opened", 2 "MCP HTTP session closed by the client"

Validation performed

  • Current ba73ccafd on main 49b4edfe7: 8/8 static/build tasks passed (typecheck/runtime build, lint with 0 errors, module boundaries, formatting, Knip and metadata). Registry metadata passed. All 83 adapter tests passed, including two prior-code failures for localhost-looking names bound to external IPv4/IPv6 addresses and the earlier stream ownership, capacity, pipelining and URL controls.
  • Current 15-file public CLI/MCP/process boundary run: 149 passed / 2 failed (151 total). The failures occur in binary_session provider-status probing: native Java cleanup fails before the CLI provider assertion and the HTTP identity/session test can finish. Stdio initialization/catalog with invalid HTTP-only settings, HTTP Host refusal/options, signal/port shutdown, prompts/completions and lifecycle controls pass. No provider/process patch masks these failures.
  • Clean-main 3ea0d9489 control reproduced the stdio-doctor/process-cleanup family: 16 passed / 9 failed in four affected files, including environment_errno_EACCES. Relevant compiled ownership/direct-analysis/status modules were byte-identical. The new main only adds the upstream browser base64 fix. Current base main's CI is also failing. Broader previous-head run: 155 passed / 14 failed in 19 files.
  • Actual installed /usr/bin/gh, 40,149,832 bytes, SHA-256 ccb3b6fc7719fbae9e027d11856dc1c73ee7503075b23e28a723ab5975c09dde: seven equal normalized_result reports across CLI/stdio/HTTP on this build. Operation, subject path/digest, artifact size/digest, Go version and module path match file identity and independent go version -m. DELETE/replacement, SIGTERM 143, empty stdout, released port and unchanged input all pass.
  • Current CI static/source/build/docs, SQLite compatibility, JavaScript recovery, real Go metadata and Linux native package lanes passed. Darwin packaging fails in unchanged doctor/Java cleanup (process identity could not be revalidated); a test shard fails in unchanged keyed-archive/setup/doctor workflows with native cleanup errors, cancelling peers. Windows packaging passed; CI aggregation completed with Portable tests and CI required failing. The normal exact-head merge request for ba73ccafd was rejected with HTTP 405: 2 of 4 required status checks are failing. The requesting human subsequently authorized a bypass attempt: gh pr merge --admin --match-head-commit ba73ccafd3b9513c975b926c875b115dfc13c075 succeeded as gensokyo-dev on 2026-10-19 at 15:58:52 UTC, squash commit 60bd646478dcfab6c296b7e4765254eea787ffa9. The failing baseline CI checks were bypassed explicitly; they did not pass. Prior reruns produced the same native-ownership family; these failures were not repaired in this HTTP contribution.
  • Greptile reviewed ba73ccafd at 5/5 with no actionable finding. Codex completed its current-head review with no new inline finding observed. Its latest bound-address finding is fixed and resolved with root-cause, structural-fix and validation evidence.
  • Real Hopper/Ghidra/IDA analysis, actual off-host/DNS-reconfigured binds and later environment serve/export remain unverified. Binding classification is covered at its native-address predicate and live loopback behavior through public workflows. The original author's shared startup-failure cleanup limitation remains source-derived and outside this contribution: cleanup before a shutdown handle exists has no retry path; the common stdio failure path is unchanged.

Heavy work used one CPU/worker; no OOM. Static gate: 274.482s wall / 273.851s CPU / 4435.84 MiB sampled peak family RSS. Current 151-case attempt (with failures above): 63.336s / 60.930s / 1409.88 MiB. Equivalent installed-app workflow, 4c09146b6 → ba73ccafd: 34.220 → 27.417s wall, 34.197 → 27.331s CPU, 886.34 → 993.91 MiB; HTTP first/warm 8.518/0.538 → 6.839/0.348s, stdio 8.679/0.677 → 7.840/0.370s. These are single shared-host runs, main also changed and OS caches were not reset; no isolated performance effect is established. RSS sampling every 50ms can double-count shared pages. Agent tokens are unmeasured; 3536-byte envelopes are not token counts.

Compatibility, safety, and release

HTTP does not add TLS, client authentication or isolated target state. Non-loopback binding relaxes Host/Origin validation with a logged warning and requires explicit selection. Stdio stays the default. Shutdown is signal-driven, with SIGINT/SIGTERM 130/143 and provider teardown after the request barrier. No installer, dependency, registry registration or tracked generated-file change.

Author readiness

Human owner: @earakely-scale

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4955 **Author:** [@earakely-scale](https://github.com/earakely-scale) **Created:** 10/18/2026 **Status:** ✅ Merged **Merged:** 10/19/2026 **Merged by:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Base:** `main` ← **Head:** `feat/mcp-streamable-http` --- ### 📝 Commits (10+) - [`46dd8f0`](https://github.com/morluto/rea/commit/46dd8f0e2b5ff74e09821e09e51bc6fd47f3bc1a) feat(mcp): serve the MCP server over streamable HTTP - [`b0ec63c`](https://github.com/morluto/rea/commit/b0ec63cc0399ad9ca7bd00a65cb1c2d753cfd47b) fix(mcp): harden the streamable HTTP listener's session replacement and shutdown - [`9ed8f06`](https://github.com/morluto/rea/commit/9ed8f06f75ea772dfd81d552142b059852e530c3) fix(mcp): compare the media type proper and bind before creating the server - [`b76f354`](https://github.com/morluto/rea/commit/b76f354d76384abe56b079b0b37e1367d1908efd) fix(mcp): classify loopback from the bound address and keep startup failures out of onerror - [`fb22df3`](https://github.com/morluto/rea/commit/fb22df370b5146b3798b6f83e64317e2785ecfcb) fix(mcp): match Accept ranges exactly and keep a session whose shutdown failed - [`54a7475`](https://github.com/morluto/rea/commit/54a747560207c06196a1ba4eb8b8ca062f15ddc5) refactor(mcp): release the listener through one helper - [`1741882`](https://github.com/morluto/rea/commit/174188279b6ce482354966ed542436514d3d4624) fix(mcp): fire the shutdown hook once, stop awaiting the probe's tee and keep every Set-Cookie - [`354b4d8`](https://github.com/morluto/rea/commit/354b4d8c0867f3d0eadaae2b0dfe42cea810287e) fix(mcp): latch startup signals so the HTTP entry never ends without cleanup - [`136d073`](https://github.com/morluto/rea/commit/136d073fa019fb8a1c5ef95ff70ecaf6d34676c4) fix(mcp): keep a startup signal's exit status through the entry's normal return - [`a23f5f1`](https://github.com/morluto/rea/commit/a23f5f13524b5403794f3599e26f93cc18398820) fix(mcp): close the connection after a reply sent before the body was read ### 📊 Changes **36 files changed** (+5211 additions, -57 deletions) <details> <summary>View changed files</summary> 📝 `docs/architecture.mermaid` (+3 -3) 📝 `docs/cli.md` (+26 -0) 📝 `docs/mcp-contracts.md` (+92 -1) ➕ `docs/specs/agent-environments/http-transport/plan.md` (+32 -0) ➕ `docs/specs/agent-environments/http-transport/spec.md` (+79 -0) ➕ `docs/specs/agent-environments/http-transport/tasks.md` (+11 -0) ➕ `docs/specs/agent-environments/http-transport/verification.md` (+297 -0) 📝 `scripts/rea.mjs` (+23 -12) ➕ `src/config/mcpHttpEndpoint.ts` (+68 -0) 📝 `src/main.ts` (+117 -3) ➕ `src/main/mcpHttpArguments.ts` (+104 -0) 📝 `src/main/messages.ts` (+2 -0) 📝 `src/main/processShutdown.ts` (+89 -10) 📝 `src/main/shutdown.ts` (+6 -4) 📝 `src/main/transport.ts` (+18 -7) 📝 `src/main/types.ts` (+23 -1) 📝 `src/server/EvidenceMcpServer.ts` (+2 -2) ➕ `src/server/RequestTrackingMcpServer.test.ts` (+88 -0) ➕ `src/server/RequestTrackingMcpServer.ts` (+92 -0) ➕ `src/server/http/NodeHttpRequestOwner.ts` (+180 -0) _...and 16 more files_ </details> ### 📄 Description ## Summary Adds `rea mcp --http [--host <h>] [--port <n>]` for gateway/environment hosts while keeping stdio as the default and registered transport. It serves the existing MCP catalog at `/mcp`, on loopback by default, with one shared active target and one client session at a time. Direct follow-up commits remain on this original PR through `ba73ccafd`, with main `49b4edfe7` merged. The requesting human explicitly authorized the HTTP scope, initial readiness and merging; the original author's history and declarations remain. ## Problem and expected behavior A host that reaches MCP services over HTTP can use REA's existing tools without changing stdio registrations. DELETE or a new initialize ends the previous client session while preserving the shared target; cancelled work finishes cleanup before another session or provider teardown can reuse its resources. ## Change and scope - Adds a `node:http` bridge and the pinned SDK's stateful Streamable HTTP transport, with streamed replies and Host/Origin validation classified solely from the actual bound IP, with configured aliases added afterward. HTTP is explicit; `server.json`, setup registrations and stdio behavior remain. - The shared server tracks tool and provider-backed completion callbacks through finalization. HTTP sessions also fence late message dispatch and own parsing/response cleanup. Handovers wait ten seconds and return 503 while retaining unfinished work for retry; full shutdown waits for completion. - The HTTP request owner admits at most eight concurrent input/route requests by default, before body conversion or initialize tees. MCP input permits end after dispatch and input settlement; plain responses retain admission through delivery and asynchronous source cleanup. Unread uploads retain admission until input completes or either side closes. Excess receives 503/connection close; queued HTTP/1.1 pipelining is disconnected before work starts. Sequential keep-alive remains supported. `maxConcurrentDispatches` permits an explicit embedding budget. - SDK body forwarding ends per request, including early refusals. Shutdown joins full exchanges, handler finalizers and response-source cancellation before provider hooks; failed cleanup retains ownership and stops new admission. All routes return 503 until the factory succeeds. HEAD cancellation stays nonblocking; a retained tee sibling must be consumed or cancelled by its caller before shutdown completes. The native byte bridge preserves reply ownership when cancelling unread input. One response writer owns its reader/cancellation across headers, pumping and completion, so output failures join the same cleanup barrier. Raw fragment delimiters are rejected before URL parsing; encoded query data is preserved. ## Contract and boundary impact - Semantic owner: HTTP bootstrap/adapters own listener, admission and request lifetimes; the shared MCP server owns callback completion. Domain/provider contracts and Evidence shapes remain. - Contribution scope: inbound listener scope is tracked in #4933 and explicitly authorized by the requesting human in the implementation session. No new provider execution authority is introduced. - CLI/MCP: HTTP-only host/port flags and `MCP_HOST`/`MCP_PORT` fallbacks; port 0 announces the bound URL on stderr. No new MCP tool or dependency. Standard registrations stay stdio. - Compatibility: one shared target, plain HTTP, with explicit non-loopback binding. Environment manifest serving/export are later increments. Authored docs cover transport, CLI and architecture; generated outputs are not committed. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [ ] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [x] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage Real HTTP negative controls reproduce late SDK tool dispatch, refused-body retention, admission bypass, premature handler/body cleanup, unread-upload release, startup readiness and queued pipelining. Eight negative controls for the latest response/pipelining fixes fail on the previous implementation. The fixes pass public client/reconnection, partial-upload, overload/recovery, cancellation and teardown workflows. Default stdio and catalog configurations are exercised. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. <details><summary>Representative output</summary> ``` listening: {"transport":"streamable-http","url":"http://127.0.0.1:57093/mcp","msg":"MCP transport listening"} --- session A --- >>> POST /mcp accept=application/json, text/event-stream content-type=application/json body: {"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"mcp","version":"0.1.0"}},"jsonrpc":"2.0","id":0} <<< 200 POST /mcp content-type=text/event-stream mcp-session-id=e6e795ba-5e0c-469a-997a-015a62d134ac >>> POST /mcp mcp-session-id=e6e795ba-… body: {"method":"notifications/initialized","jsonrpc":"2.0"} >>> GET /mcp mcp-session-id=e6e795ba-… <<< 202 POST /mcp >>> POST /mcp mcp-session-id=e6e795ba-… body: {"method":"tools/list","jsonrpc":"2.0","id":1} <<< 200 GET /mcp content-type=text/event-stream mcp-session-id=e6e795ba-… <<< 200 POST /mcp content-type=text/event-stream mcp-session-id=e6e795ba-… >>> POST /mcp mcp-session-id=e6e795ba-… body: {"method":"tools/call","params":{"name":"binary_session","arguments":{}},"jsonrpc":"2.0","id":2} <<< 200 POST /mcp content-type=text/event-stream mcp-session-id=e6e795ba-… [A] session=e6e795ba-5e0c-469a-997a-015a62d134ac tools=207 has_binary_session=True binary_session.isError=False >>> DELETE /mcp mcp-session-id=e6e795ba-… <<< 200 DELETE /mcp --- session B --- >>> POST /mcp body: {"method":"initialize",...,"id":0} <<< 200 POST /mcp content-type=text/event-stream mcp-session-id=b654ce7e-9909-4937-9497-185062379fbc >>> POST /mcp body: {"method":"notifications/initialized",...} <<< 202 POST /mcp >>> GET /mcp <<< 200 GET /mcp text/event-stream >>> POST /mcp body: {"method":"tools/list",...,"id":1} <<< 200 POST /mcp text/event-stream >>> POST /mcp body: {"method":"tools/call","params":{"name":"binary_session","arguments":{}},...,"id":2} <<< 200 POST /mcp text/event-stream [B] session=b654ce7e-9909-4937-9497-185062379fbc tools=207 has_binary_session=True binary_session.isError=False >>> DELETE /mcp mcp-session-id=b654ce7e-… <<< 200 DELETE /mcp client exit=0 server exit=143 stdout bytes=0 server log msgs: 1 "MCP transport listening", 2 "MCP HTTP session opened", 2 "MCP HTTP session closed by the client" ``` </details> ## Validation performed - Current `ba73ccafd` on main `49b4edfe7`: **8/8 static/build tasks passed** (typecheck/runtime build, lint with 0 errors, module boundaries, formatting, Knip and metadata). Registry metadata passed. All **83 adapter tests** passed, including two prior-code failures for localhost-looking names bound to external IPv4/IPv6 addresses and the earlier stream ownership, capacity, pipelining and URL controls. - Current 15-file public CLI/MCP/process boundary run: **149 passed / 2 failed** (151 total). The failures occur in `binary_session` provider-status probing: native Java cleanup fails before the CLI provider assertion and the HTTP identity/session test can finish. Stdio initialization/catalog with invalid HTTP-only settings, HTTP Host refusal/options, signal/port shutdown, prompts/completions and lifecycle controls pass. No provider/process patch masks these failures. - Clean-main `3ea0d9489` control reproduced the stdio-doctor/process-cleanup family: 16 passed / 9 failed in four affected files, including `environment_errno_EACCES`. Relevant compiled ownership/direct-analysis/status modules were byte-identical. The new main only adds the upstream browser base64 fix. [Current base main's CI is also failing](https://github.com/morluto/rea/commit/49b4edfe7/checks). Broader previous-head run: 155 passed / 14 failed in 19 files. - Actual installed `/usr/bin/gh`, 40,149,832 bytes, SHA-256 `ccb3b6fc7719fbae9e027d11856dc1c73ee7503075b23e28a723ab5975c09dde`: **seven equal `normalized_result` reports** across CLI/stdio/HTTP on this build. Operation, subject path/digest, artifact size/digest, Go version and module path match file identity and independent `go version -m`. DELETE/replacement, SIGTERM 143, empty stdout, released port and unchanged input all pass. - Current CI static/source/build/docs, SQLite compatibility, JavaScript recovery, real Go metadata and Linux native package lanes passed. Darwin packaging fails in unchanged doctor/Java cleanup (`process identity could not be revalidated`); a test shard fails in unchanged keyed-archive/setup/doctor workflows with native cleanup errors, cancelling peers. Windows packaging passed; CI aggregation completed with `Portable tests` and `CI required` failing. The normal exact-head merge request for `ba73ccafd` was rejected with HTTP 405: `2 of 4 required status checks are failing.` The requesting human subsequently authorized a bypass attempt: `gh pr merge --admin --match-head-commit ba73ccafd3b9513c975b926c875b115dfc13c075` succeeded as `gensokyo-dev` on 2026-10-19 at 15:58:52 UTC, squash commit `60bd646478dcfab6c296b7e4765254eea787ffa9`. The failing baseline CI checks were bypassed explicitly; they did not pass. Prior reruns produced the same native-ownership family; these failures were not repaired in this HTTP contribution. - Greptile reviewed `ba73ccafd` at **5/5 with no actionable finding**. Codex completed its current-head review with no new inline finding observed. Its latest bound-address finding is fixed and resolved with root-cause, structural-fix and validation evidence. - Real Hopper/Ghidra/IDA analysis, actual off-host/DNS-reconfigured binds and later environment serve/export remain unverified. Binding classification is covered at its native-address predicate and live loopback behavior through public workflows. The original author's [shared startup-failure cleanup limitation](https://github.com/morluto/rea/pull/4955#discussion_r4308551075) remains source-derived and outside this contribution: cleanup before a shutdown handle exists has no retry path; the common stdio failure path is unchanged. Heavy work used one CPU/worker; no OOM. Static gate: 274.482s wall / 273.851s CPU / 4435.84 MiB sampled peak family RSS. Current 151-case attempt (with failures above): 63.336s / 60.930s / 1409.88 MiB. Equivalent installed-app workflow, `4c09146b6` → `ba73ccafd`: 34.220 → 27.417s wall, 34.197 → 27.331s CPU, 886.34 → 993.91 MiB; HTTP first/warm 8.518/0.538 → 6.839/0.348s, stdio 8.679/0.677 → 7.840/0.370s. These are single shared-host runs, main also changed and OS caches were not reset; no isolated performance effect is established. RSS sampling every 50ms can double-count shared pages. Agent tokens are unmeasured; 3536-byte envelopes are not token counts. ## Compatibility, safety, and release HTTP does not add TLS, client authentication or isolated target state. Non-loopback binding relaxes Host/Origin validation with a logged warning and requires explicit selection. Stdio stays the default. Shutdown is signal-driven, with SIGINT/SIGTERM 130/143 and provider teardown after the request barrier. No installer, dependency, registry registration or tracked generated-file change. ## Author readiness Human owner: @earakely-scale - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:42:20 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6691
No description provided.