MCP: re-evaluate resume_path for Codex sessions

Open 💬 5 comments Opened May 28, 2026 by matt-wright86

Summary

Requesting that MCP clients be able to resume a prior Codex session from its rollout file — e.g. an optional resume_path (or conversation_id) parameter on the codex MCP tool, wiring the already-existing RolloutRecorderParams::Resume through the MCP runner.

Background

This was previously proposed and closed:

  • #10117 (PR) — "MCP: add resume-path support for Codex sessions"
  • #10122 (issue) — "MCP resume_path for Codex sessions"

The PR was closed under the updated contribution guidelines ("we're no longer accepting unsolicited code contributions. All code contributions are by invitation only."), not for technical reasons — so I'm filing this as a feature request rather than a contribution.

The gap

A live codex mcp-server exposes two tools: codex (start a new session) and codex-reply (continue by threadId). codex-reply resolves a threadId only through the in-memory ThreadManager of the running server process. Once that process exits, the thread map is gone and codex-reply returns "thread not found". There is no MCP path to re-attach to a session by its on-disk rollout, even though RolloutRecorderParams::Resume { path } already exists in the core crate and backs codex resume.

Why it matters

I maintain Mardi Gras, a TUI that integrates Codex over MCP. The lack of this one parameter is the only blocker to robust resume-after-restart: when the client restarts, in-flight sessions are orphaned. Today's only workaround is shelling out to codex resume in a separate pane, which leaves the MCP client's transcript out of sync. The same gap affects any MCP-mode client that wants to survive a restart.

Ask

If a rollout-based resume aligns with the roadmap, I'd be glad to see #10117 revisited (and happy to rebase it if invited), or to follow whatever shape you'd prefer.

View original on GitHub ↗

5 Comments

MachengShen · 3 months ago

I strongly support exposing a rollout/resume path through the MCP surface.

One concrete requirement from running long-lived Codex sessions is that continuity should survive three different failure modes:

  1. the MCP server process restarts and loses its in-memory thread map;
  2. the client restarts and only has an on-disk rollout/session artifact;
  3. a session fails during compact/streaming and needs a fresh continuation process to reconstruct the latest actionable state.

The useful primitive does not have to be a complex session manager. A small contract would already help:

  • accept resume_path or equivalent on the MCP codex tool;
  • return the canonical rollout/session path in tool results;
  • document whether a resumed session appends to the same rollout or starts a child rollout with a parent pointer;
  • preserve enough metadata for clients to distinguish new, resumed, resume_failed, and needs_manual_recovery.

That would let MCP clients build crash-safe orchestration without scraping CLI output or keeping fragile sidecar maps. It also lines up with Codex already having on-disk rollout persistence in the core CLI path.

[Sent by Macheng's AI assistant]

norika1207-lab · 2 months ago

The remote-agent use case makes this more urgent than a convenience feature.

If Codex sessions can be launched or supervised from outside the original terminal, the durable identity of a session cannot be only the live MCP server's in-memory threadId. Remote clients, mobile clients, schedulers, and IDE integrations all need a way to recover the work from the on-disk rollout after the original process dies.

A small contract would cover most of it:

{
  "resume_path": "...",
  "resume_mode": "append|child_rollout",
  "parent_rollout": "...",
  "resume_status": "resumed|not_found|version_mismatch|needs_manual_recovery"
}

The key is that every codex tool result should return the canonical rollout path, not just a transient thread id. Then an MCP client can persist that path and recover after restart without scraping CLI output or launching a separate codex resume process that drifts from the MCP transcript.

This also creates a cleaner observability boundary: dashboards can distinguish “new session”, “continued live thread”, “resumed from rollout”, and “resume failed but artifacts exist.”

Necmttn · 2 months ago

For MCP, threadId and durable session identity should be separate fields.

A resumed run can return both the live MCP thread id and a persistent resume_path or conversation id. Clients can then recover after server/client restarts by reopening from durable identity, while still using codex-reply for the live process.

That boundary also makes audit logs and remote supervisors easier to reconcile.

---

_Generated with ax._

safal207 · 2 months ago

This issue maps directly to LS work on durable trajectory identity, resumable continuations, and deterministic replay.

A useful distinction may be:

session process restarted
≠ task trajectory ended

rollout file found
≠ rollout is valid for safe resume

A resumed MCP session should preserve the original task trajectory while creating a new continuation:

trajectory_id: stable across the task
continuation_id: new after pause, restart, or recovery

A possible resume request envelope:

{
"schema_version": "codex-resume-request/v0.1",
"trajectory_id": "trajectory-001",
"previous_continuation_id": "continuation-004",
"requested_continuation_id": "continuation-005",
"rollout": {
"path": "/home/user/.codex/sessions/rollout.jsonl",
"digest": "sha256:..."
},
"workspace_binding": {
"repository": "owner/project",
"workspace_id": "workspace-abc",
"git_head": "61a66df7e829de9fab98f783c2f6d7bb56c6d92f",
"dirty_state_digest": "sha256:..."
},
"policy_binding": {
"policy_decision_id": "policy-044",
"sandbox_mode": "workspace-write",
"approval_mode": "on-request"
},
"resume_nonce": "nonce-2026-001"
}

The resume path could then evaluate:

load rollout
→ verify digest
→ verify trajectory binding
→ verify workspace identity and drift
→ verify policy binding
→ detect replay
→ RESUME / DEFER / REJECT

The central invariant would be:

«Resume must restore continuity without silently restoring stale authority.»

For example, a rollout created under one sandbox or approval policy should not automatically resume under a different policy while retaining previous permissions.

Another useful invariant:

«The same rollout and resume nonce must not create multiple active continuations.»

A typed result could look like:

{
"trajectory_id": "trajectory-001",
"new_continuation_id": "continuation-005",
"decision": "DEFER",
"reason_code": "WORKSPACE_DRIFT_REQUIRES_REVALIDATION",
"revalidation_required": [
"git_head",
"dirty_files",
"active_constraints",
"pending_approvals"
]
}

This would also keep the MCP client transcript synchronized. Instead of starting a parallel shell-based "codex resume", the client could reattach to the same durable trajectory and receive the new continuation identity.

A deterministic conformance fixture could test:

  1. MCP process restarts, rollout is unchanged, workspace and policy match → "RESUME";
  2. rollout digest has changed unexpectedly → "REJECT";
  3. rollout belongs to another workspace → "REJECT";
  4. repository state drifted during downtime → "DEFER" for revalidation;
  5. "policy_decision_id" is substituted during resume → fail closed;
  6. identical resume nonce is replayed → reject duplicate continuation;
  7. interrupted tool operation has no terminal receipt → resume with the operation unresolved;
  8. previous approval expired or changed → do not restore authority;
  9. resumed session keeps the same "trajectory_id";
  10. every restart receives a new "continuation_id".

For interoperable signed resume envelopes, deterministic JSON canonicalization such as RFC 8785 could also prevent equivalent payloads from producing inconsistent digests.

Related LS work:

  • recovered-evidence and continuation envelope:

https://github.com/safal207/LS/pull/651

  • causal audit:

https://github.com/safal207/LS/issues/594

  • evidence and authorization gates:

https://github.com/safal207/LS/issues/595

  • deterministic replay:

https://github.com/safal207/LS/issues/597

Would a small vendor-neutral "ResumeRequestEnvelope" fixture help test process-restart recovery, workspace binding, policy substitution, and replay rejection across MCP clients?

boombx403-byte · 9 days ago

Hi @matt-wright86, regarding the missing tool output / unfinished call state in the transcript, Codex Rescue Alpha5 has bounded tool-correlation diagnostics to detect persisted correlation anomalies and incomplete turn boundaries without assuming non-execution.

To inspect the rollout locally and safely in read-only mode:

pip install codex-rescue==0.1.0a5
codex-rescue doctor <path-to-rollout.jsonl>

No private files need to be uploaded; please sanitize any repository details before sharing diagnostic output.