Persistent Memory for Codex, Without a Giant AGENTS.md
Start a fresh Codex session in a repo you have worked in for months. Ask it to continue the caching change from Tuesday. It reads your AGENTS.md, it reads the code, and it asks you why the first cache design was rejected.
The code kept the outcome. Nothing kept the conversation.
The instinct at that point is to write Tuesday's decision into AGENTS.md. Do that a few times a week and the file becomes a junk drawer. Stable rules start sharing space with a running log of moments, every session pays the context cost of the whole thing, and the file stops being trusted as a source of truth.
Instructions, state, decisions
Three different jobs get asked of one file, and they only look similar.
- Instructions are true before any task starts. Build commands and test conventions belong in AGENTS.md, and they should stay short.
- State is what is true right now. The current task and anything in flight. It changes fast and deserves its own small surface, not the rules file.
- Decisions are what happened in a conversation. Why the caching layer works the way it does, which approach got rejected and what made it wrong. These are episodic. You cannot know on Monday which decision from last week will matter on Friday.
Keep rules in the rules file. Put decisions in a memory layer that gets searched at the right moment.
What we built for Codex
memoryrouter-codex is the package we built for exactly this job. It connects Codex to a MemoryRouter vault, which is the private memory collection behind your key, through two mechanisms that do different things on purpose.
The first is deterministic lifecycle hooks. Before each prompt, relevant project memory is recalled and injected as context. After each completed turn, your request and the final answer are captured. This does not depend on the model deciding to call a tool, which matters, because "remember this" is not something you should have to say.
The second is a remote MCP connection at mcp.memoryrouter.ai, authenticated with OAuth. That gives Codex explicit memory tools for the moments you do want to ask directly, like searching the vault or storing something by hand.
Two design details worth knowing. Capture is message-only: your request and the final assistant response, with tool names, inputs, results, commands, and patches excluded, so your tool noise never becomes memory. And project identity is derived from the git remote, so memories from one repo do not leak into another. Worktrees of the same repository share one identity, and a clone on a new machine resolves to the same project.
The two authentication paths people mix up
This causes more confusion than anything else, so it gets its own section.
Codex uses two separate authentication paths for MemoryRouter. The browser login (codex mcp login memoryrouter) authenticates the explicit MCP tools. The automatic hooks run outside that OAuth session and need their own credential: a MemoryRouter API key supplied at install time, plus trusted command hooks inside Codex.
If you skip the key, the MCP tools can work perfectly while automatic recall and capture quietly do nothing. A successful browser login is not proof that the hooks are running. That is what /hooks, /mcp verbose, and doctor are for.
Set it up
Install the hooks with your key passed on stdin, so it never lands in shell history:
printf '%s' "$MEMORYROUTER_API_KEY" | npx -y memoryrouter-codex init --scope user --auth oauth --api-key-stdin
On macOS you can copy the key first and swap printf for pbpaste. Then sign in and choose the vault the hooks should use:
codex mcp login memoryrouter
Start Codex, run /hooks, and trust the MemoryRouter definitions. Then verify everything:
npx -y memoryrouter-codex doctor --scope user
You need Node 18 or newer and Codex 0.145.0 or newer, with 0.146.0 for the OAuth path. The key is stored under ~/.memoryrouter with owner-only permissions. It is never written to config.toml, hooks.json, AGENTS.md, or your repository. The Codex page has the short connect flow, and the documentation covers Windows, project scope, and enterprise rollout.
Prove it in two sessions
Do this on day one.
In one session, tell Codex something specific and harmless: "For the memory test, the project code phrase is amber glacier 62." Let the turn finish and close the session. Open a new Codex session in the same project and ask what the code phrase is. If the hooks are running, the new session answers from injected project memory without you pasting anything.
That exercise is the whole product test. If it fails, doctor tells you which layer is down. The two causes the documentation calls out are a hook key that was never provided and hooks that were never trusted.
What it does not do
No memory setup is honest if it only lists wins, so here are the boundaries.
The install captures from now on. It does not import your old ChatGPT or Codex conversations. There is a guided path for extracting an export, but it is experimental, not a one-click time machine.
Hooks are a lifecycle extension, not a security boundary. If you need strict isolation, use a separate vault, because the hosted MCP server does not take a project argument.
Codex cloud does not inherit your laptop's config or secrets. Project scope plus a provisioned key in the cloud environment is the documented path, and ChatGPT web never reads local ~/.codex files, so it uses MemoryRouter's separate connector.
Codex's own Memories can stay enabled. They are local to Codex by design. MemoryRouter is the cross-machine, cross-tool layer on top.
One next step
Your vault holds more than Codex. Decide something in Codex and Claude Code starts with it. Explain a project once and every connected tool begins from the same context. If the caching story at the top of this post felt familiar, fix it tonight. Create your MemoryRouter account, copy the key, and run the two commands above.