codex-reply should rehydrate sessions from disk when thread not found in memory

Resolved 💬 3 comments Opened Feb 23, 2026 by zsxkib Closed May 2, 2026
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

problem

i use codex as an MCP server inside claude code a lot. the two work really well as a team — claude handles the high-level orchestration and codex does the heavy lifting with shell access, file edits, etc.

the problem is when i've been working with just codex directly and it already has all the context for what i'm doing. i want to tell claude "go chat with codex \019c7616-b3e9-7782-9ea8-b53e6bb09329\" and have it pick up right where i left off. but if the MCP server has restarted since that session (which happens all the time — e.g. claude code restarts, laptop sleep, etc), \codex-reply\ just returns "Session not found" even though the full JSONL transcript is still sitting on disk at \~/.codex/sessions/\.

this is frustrating because the data is RIGHT THERE.

the fix is surprisingly small

all three building blocks already exist in the codebase, they just aren't wired together in the \codex-reply\ error path:

  1. \find_thread_path_by_id_str()\ in \core/src/rollout/list.rs\ — locates the JSONL rollout file by threadId (sqlite first, file search fallback)
  2. \read_session_meta_line()\ in \core/src/rollout/list.rs\ — reads the session metadata to recover the original cwd
  3. \resume_thread_from_rollout()\ in \core/src/thread_manager.rs\ — creates a new thread with the full conversation history loaded

the change is ~65 lines of new code in \mcp-server/src/message_processor.rs\:

  • when \get_thread(thread_id)\ fails, call a new \try_rehydrate_from_disk()\ method
  • that method chains the three functions above: find rollout → read session meta → resume thread
  • if rehydration also fails (e.g. no rollout file on disk), return the original "Session not found" error unchanged

the only other change needed is a 4-line \pub fn auth_manager()\ getter on \ThreadManager\ (needed to pass to \resume_thread_from_rollout\).

the response already includes \threadId\ in the output, so the client automatically picks up the new thread ID for subsequent calls. no client-side changes needed.

i already built this

i had a working implementation in #12594 (closed per contribution policy). it compiles, passes all 11 existing tests, and the diff is +75/-10 lines across 2 files. happy to share more details or help test if this gets picked up.

use case

this would make the codex MCP server way more useful for multi-agent workflows where you want to hand off context between sessions. rn the workaround is to either keep the MCP server running indefinitely (not realistic) or re-explain everything from scratch in a new session.

View original on GitHub ↗

3 Comments

Sube-py · 5 months ago

I implemented this on my fork and validated it locally.

Branch:
Sube-py:feat/codex-reply-rehydrate-sessions

Commits:

  • 1182804048f468c74a700da703bd6aeb0e5717b1
  • 05383edc8

Summary:

  • codex-reply now attempts to rehydrate a thread from rollout history when the requested threadId is not loaded in memory
  • it reconstructs config using the saved session cwd and resumes the thread through resume_thread_with_history
  • docs were updated and an end-to-end MCP test was added for resuming a VS Code-created thread

Local checks run:

  • cargo test -p codex-mcp-server
  • just fix -p codex-mcp-server
  • just fmt

I cannot open a PR because this repository is currently restricted to collaborators only. If this change is welcome, please invite me to open the PR or feel free to cherry-pick from my branch.

etraut-openai contributor · 3 months ago

This feature request hasn't received enough upvotes, so I'm closing it.

smileBeda · 3 months ago

@etraut-openai I would like to push back on this.

Maybe the reason feedback on this thread is precisely because, in its current bare-bones form, the MCP cannot be relied on for durable workflows due to the issue outlined here.

A community member already went through the effort of producing a patch. With Codex, integrating and validating something like this is realistically a matter of a few hours at most, including testing.

Consider a workflow like the multi-agent orchestration example from the cookbook:
https://developers.openai.com/cookbook/examples/codex/codex_mcp_agents_sdk/building_consistent_workflows_codex_cli_agents_sdk#orchestrating-multi-agent-workflows

Now imagine wanting those workflows to survive reboots or transient failures - whether that’s a server restart, MCP restart, or any other interruption. In that context, the behavior described by OP - recovering the thread from disk when the thread ID is missing - is not a “nice to have”; it’s what makes the MCP workflow durable and production-usable.

Without persistence and recovery semantics, long-running orchestration workflows remain fragile by design.

Closing this due to insufficient upvotes feels shortsighted to me, especially when the issue directly impacts reliability and real-world usability of the MCP tooling ecosystem.