Skip to content

mcpx: Phase 1 of #1414 — persist legacy HTTP upstream sessions and resume them after a cold restart #1415

Closed

Description

@dezren39

Phase 1 of design #1414 (cold-restart upstream HTTP session resume). Design doc: files/designs/code-mcpx-cold-restart-session-resume.md in the keep-the-four-repos-healthy goal workspace.

Scope

Persist the resumable half of each legacy streamable-HTTP upstream session in the mcpx daemon state directory and restore it on cold start, reusing the takeover restore path:

  • New versioned state file next to sessions.json, written/read with the internal/daemon/sessions.go discipline: atomic tmp+rename, defaults.PrivateMode, version envelope, ignore-and-log on version mismatch or corruption.
  • Record per pool instance: instance key (server name + pool scope key), upstream URL, config fingerprint (hash over the session-defining config fields + header/auth names — never values), SessionID, Negotiated, the full mcpclient.Session protocol state (as returned by Client.SessionState()), savedAt.
  • The record type has no field for headers or resolved secret values — that absence is the security invariant (handoff headers travel over the takeover socket only; see HTTPHandoff comment in internal/mcpclient/http.go). On restore, headers are re-derived from live config via the existing httpOptions() / resolveAuth() path.
  • Save triggers: successful legacy initialize (session established) and any response that installs a new Mcp-Session-Id (internal/mcpclient/http.go:156). Save failure: log, non-fatal — the daemon behaves exactly as today.
  • Restore: at pool connect, if a record exists and its fingerprint matches the live config, seed the transport with ht.Resume(...) and build the client with mcpclient.Resume(...) — the identical calls the takeover path makes (internal/pool/handoff.go:238,326). No parallel resume implementation.
  • Fingerprint mismatch → record discarded, fresh initialize, no error surfaced.
  • Scope limits: legacy-era streamable HTTP only. Modern era (no sessions) and legacy SSE (session lives in the GET stream) are untouched. Takeover behaviour unchanged. The standalone GET stream is re-established on resume exactly as takeover re-establishes it — parity with takeover is the bar.

Out of scope (Phase 2 / Phase 3 of #1414): 404/401 expiry fallback and retry, record removal on config removal, graceful-shutdown DELETE semantics, TTL, dashboard visibility.

Acceptance

  • Defining test passes: daemon against a test HTTP upstream → legacy session established → daemon killed with SIGKILL → daemon restarted → first call succeeds; the upstream saw no second initialize; the request carried the original Mcp-Session-Id.
  • Fingerprint-mismatch record is ignored and a fresh initialize happens (test).
  • Corrupt / version-mismatched state file is ignored and logged; daemon starts and operates normally (test).
  • No test or code path writes a resolved header/secret value into the state file (record type has no such field; assert in test by scanning the written file for a sentinel secret value).
  • Takeover tests and the full suite pass: cd pkgs/mcpx && go test ./....

agent-note:v1 — filed by the repo design architect (dedicated code job, pass 2, 2026-10-27) as a sub-issue of design #1414. Filed as task/triage: triage confirms scope against current main and enqueues the implementation packet; do not implement in the triage task. The direction decision sits with Drew on #1414 (user/review) — triage may proceed, implementation start should respect that decision.

Activity

  1. added
    kind/featureNew feature or capability request
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/normalOrdinary priority (the default)
    on Oct 27, 2026
  2. developing-today commented on Oct 27, 2026

    @developing-today
    Contributor
  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    effort/lLarge: multi-day or open-ended; expect staged check-ins
    on Oct 27, 2026
  4. added
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 27, 2026
  5. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    Intake review

    Fleet-monitor intake pass (2026-10-27). Phase 1 of design #1414 (which carries user/review — the direction decision is Drew's there; this intake does not pre-empt it). Related: #1416 (Phase 2, expiry fallback), #1414 (design). The body already carries a full ## Acceptance section, so no body edit; labels were already normalized by the filer (kind/feature, priority/normal, effort/l, app/mcpx, source/design-architect) — I added only meta/enriched.

    Notes / risks: the security invariant is structural — the persisted record type must have no field capable of holding a resolved header/secret value, and the acceptance test scanning the written file for a sentinel secret is the right proof. Suggested approach: reuse the takeover restore calls exactly as scoped (ht.Resume / mcpclient.Resume); no parallel resume path.

  6. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  7. 53 remaining items

  8. added
    status/parkedDeliberately paused with a recorded resume condition
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 4, 2026
  9. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    Resumed by repo queue worker lane code-u for task 1483: PR #5455 at head 9c8b465 (lane code-v parked it for CI + Codex re-review after fixing both Codex P2 findings at the previous head, threads replied). Fresh state: no new Codex findings on the current head, only check run is CodeRabbit (neutral/skipping) — this repo runs CI on main, so re-verifying the targeted mcpx suites on the laptop at this head, then merging per standing criteria if green.

  10. added a commit that references this issue on Nov 4, 2026
  11. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    Done (task 1483, lane code-u resume): PR #5455 merged at 7cd293e. Resume verification at head 9c8b465: laptop go test for pkgs/mcpx internal/pool, internal/mcpclient, and internal/daemon all pass; both Codex P2 findings from the previous head were fixed in the PR with thread replies and no new Codex findings exist on the merged head; the only PR check run was CodeRabbit (neutral) — this repo runs CI on main. Phase 2 (expiry fallback / record hygiene) remains issue #1416, already separately queued.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)effort/lLarge: multi-day or open-ended; expect staged check-inskind/featureNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/design-architectFiled by the repo design architect jobstatus:donetask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions