Persistent memory for Codex.
After setup, it does two things automatically:
- recalls relevant memories before each user prompt
- saves a recent
user/assistantwindow when Codex stops
Automatic recall uses recallMinPromptLength, which defaults to 5, after stripping already-injected memory context from the current prompt.
The plugin exposes:
$mem9:setup$mem9:cleanup$mem9:recall$mem9:store
$mem9:setup is the main entrypoint. It manages shared profiles in the mem9 home, applies either global or project scope, and repairs the managed Codex hooks in the Codex home.
- Codex CLI
0.122.0or newer - A Codex App build with plugin and hook support
- Node.js 22 or newer
- Network access to the mem9 server API
- Add the marketplace:
codex plugin marketplace add mem9-ai/mem9-
In Codex, run
/plugins, search formem9, open themem9-aimarketplace entry, and chooseInstall plugin. -
Restart Codex or open a fresh Codex session with the same
CODEX_HOME. For normal installs, that is$HOME/.codex. -
Run:
$mem9:setup -
If one repository needs a different profile, timeout, or recall prompt-length threshold, see Profiles and Project Scope.
-
When you want an on-demand recall or an explicit store, run:
$mem9:recall $mem9:store
You do not need to enable hooks manually first. $mem9:setup inspects the saved profiles, enables the Codex hooks feature, and installs the managed hooks. Codex 0.129.0+ uses hooks = true; Codex 0.122.0 through 0.128.x uses codex_hooks = true.
The Codex plugin uses two home directories:
| Variable | Default when unset | What lives there |
|---|---|---|
CODEX_HOME |
~/.codex on macOS/Linux |
Codex user state, hooks.json, config.toml, and mem9-managed Codex runtime files under $CODEX_HOME/mem9/ |
MEM9_HOME |
~/.mem9 on macOS/Linux |
Shared mem9 credential profiles in $MEM9_HOME/.credentials.json |
Most macOS/Linux users can leave both variables unset. With the defaults, Codex integration files live under ~/.codex/, and mem9 credentials live in ~/.mem9/.credentials.json. In shell commands, ~ means the same home directory as $HOME.
The defaults are equivalent to starting Codex from a shell with:
export CODEX_HOME="$HOME/.codex"
export MEM9_HOME="$HOME/.mem9"
codexOn Windows PowerShell, the same defaults resolve under your user profile:
$env:CODEX_HOME = "$env:USERPROFILE\.codex"
$env:MEM9_HOME = "$env:USERPROFILE\.mem9"
codexUse the same CODEX_HOME and MEM9_HOME in trusted-shell commands that save or update profile keys. $mem9:setup keeps API key entry out of the Codex TUI and writes the key to $MEM9_HOME/.credentials.json.
Use $mem9:setup for profile setup. It creates or selects mem9 profiles, saves profile keys, and applies the selected profile globally or for the current repository.
- Run
$mem9:setup. - Choose
create-newto create a mem9 API key, or chooseuse-existingto reuse a saved profile. - Choose
user scope.
This selects the default profile Codex uses across repositories.
- Open Codex from that repository.
- Run
$mem9:setup. - Choose
create-neworuse-existingfor the repository profile. - Choose
project scope.
Project scope can override:
profileIddefaultTimeoutMssearchTimeoutMsrecallMinPromptLength
- Open Codex from that repository.
- Run
$mem9:setup. - Choose
clear project scope.
The repository will use the user-scope default profile again.
Use the same CODEX_HOME and MEM9_HOME when starting Codex and when saving profile keys from a trusted shell. With the defaults above, Codex reads integration files from ~/.codex and mem9 reads shared profiles from ~/.mem9.
Manual edits are mainly for recovery or automation. The recommended path is still $mem9:setup.
Saved profiles are written to $MEM9_HOME/.credentials.json:
The keys under profiles are profile IDs. For example, "profileId": "work" selects the profiles.work entry.
{
"schemaVersion": 1,
"profiles": {
"default": {
"label": "Personal",
"baseUrl": "https://api.mem9.ai",
"apiKey": "..."
},
"work": {
"label": "Work",
"baseUrl": "https://api.mem9.ai",
"apiKey": "..."
}
}
}The user-scope default is written to $CODEX_HOME/mem9/config.json.
A project override is written to <project>/.codex/mem9/config.json. It only needs the fields that differ from the user-scope default:
{
"schemaVersion": 1,
"profileId": "work",
"searchTimeoutMs": 15000,
"recallMinPromptLength": 5
}Remote update-check settings stay in user scope. Project scope only controls the active profile and request tuning for that repository.
Single entrypoint for mem9 setup in Codex.
What it does:
- inspects the current runtime, profiles, and scope config
- lets you create a new mem9 API key or reuse an existing global profile
- applies either user scope or project scope
- repairs the Codex hooks feature flag,
$CODEX_HOME/hooks.json, and the managed hook shims - keeps API key entry out of the Codex TUI
Project scope keeps profile, timeout, and recall prompt-length overrides.
User scope also owns updateCheck.enabled and updateCheck.intervalHours.
Cleanup for the mem9-managed Codex files.
What it does:
inspectemits machine-readable JSON with sanitized paths and the current removable targetsrunremoves mem9-managed entries from$CODEX_HOME/hooks.jsonrunremoves$CODEX_HOME/mem9/hooks/runremoves$CODEX_HOME/mem9/install.jsonrunremoves$CODEX_HOME/mem9/config.jsonrunremoves$CODEX_HOME/mem9/state.jsonrun --include-projectalso removes<project>/.codex/mem9/config.json
What it does not do:
- it keeps
$MEM9_HOME/.credentials.json - it keeps
$CODEX_HOME/config.toml - it keeps
$CODEX_HOME/mem9/logs/codex-hooks.jsonl
Manual memory lookup for the current request.
What it does:
- uses the current effective profile
- respects project override config when present
- searches
/v1alpha2/mem9s/memorieswith the current API key - uses
searchTimeoutMs
Manual memory store for one user-approved fact, preference, or instruction.
What it does:
- uses the current effective profile
- respects project override config when present
- stores one
contententry with synchronous confirmation - uses
defaultTimeoutMs
Upgrade the Git marketplace entry, then restart Codex:
codex plugin marketplace upgrade mem9-aiThis updates the installed mem9 plugin for normal releases.
Migration releases surface a SessionStart notice that asks for $mem9:setup once.
Follow this order:
-
Enter Codex and run
$mem9:cleanup. -
In Codex, open
/plugins, search formem9, and uninstall the plugin. -
After step 2 succeeds, exit Codex and run:
codex plugin marketplace remove mem9-ai
This order keeps mem9-managed hooks and plugin state in sync while you remove the integration.
This uninstall flow keeps $MEM9_HOME/.credentials.json.
If you want a full removal, delete $MEM9_HOME/.credentials.json after the uninstall steps finish.
This repository also ships a repo-local marketplace manifest at:
<repo>/.agents/plugins/marketplace.json
For local testing:
-
Clone this repository.
-
Open Codex with the repository root as the working directory. Codex discovers the repo-local marketplace from
<repo>/.agents/plugins/marketplace.json. -
In Codex, run
/plugins, search formem9, open the repo-local marketplace entry for this checkout, and chooseInstall plugin. -
Run
$mem9:setup. -
Restart Codex after plugin or marketplace changes.
-
Reinstall
mem9from the repo-local marketplace when Codex still shows the older package after restart. -
Verify the plugin package from the repo root:
pnpm --dir codex-plugin test pnpm --dir codex-plugin typecheck
For script-level help during development:
node ./skills/setup/scripts/setup.mjs --help
node ./skills/setup/scripts/setup.mjs profile save-key --help
node ./skills/cleanup/scripts/cleanup.mjs --help
node ./skills/cleanup/scripts/cleanup.mjs run --helpSet this before starting Codex:
export MEM9_DEBUG=1By default the Codex plugin writes JSONL logs here:
$CODEX_HOME/mem9/logs/codex-hooks.jsonl
You can override the file path with MEM9_DEBUG_LOG_FILE.
Common issues:
- If
$mem9:setupreturnsno matchesafter installing from/plugins, restart Codex or open a fresh Codex session. Codex loads plugin skills when the session starts. - If
inspectreportsmissing_install_metadatabefore setup finishes, continue with$mem9:setup.scope applywrites$CODEX_HOME/mem9/install.json. - If
SessionStartsays mem9 is not configured, run$mem9:setup. - If a repository needs a different profile, timeout, recall prompt-length threshold, or a cleared local override, rerun
$mem9:setupin that repository and apply or clear project scope. - If you want to remove the managed Codex files before reinstalling or resetting mem9, run
$mem9:cleanup. - If the selected profile is missing, run
$mem9:setupto create or repair global profiles. - If the selected profile is missing an API key, run
$mem9:setupand choosecreate-new, or add the profile manually in$MEM9_HOME/.credentials.jsonand rerun$mem9:setup, then chooseuse-existing. - If setup repairs malformed JSON files, it keeps sibling
.bakcopies before rewriting them. - If you installed an older prerelease that still points hooks at
$CODEX_HOME/mem9/runtime/, run$mem9:setuponce after upgrading.
Runtime defaults:
CODEX_HOME=~/.codex
MEM9_HOME=~/.mem9
Global Codex integration:
$CODEX_HOME/hooks.json
$CODEX_HOME/config.toml
Global mem9 runtime and config:
$CODEX_HOME/mem9/hooks/
$CODEX_HOME/mem9/install.json
$CODEX_HOME/mem9/config.json
$CODEX_HOME/mem9/state.json
$CODEX_HOME/mem9/logs/codex-hooks.jsonl
Project override written by scope apply --scope project:
<project>/.codex/mem9/config.json
Shared credentials:
$MEM9_HOME/.credentials.json
Credentials file:
{
"schemaVersion": 1,
"profiles": {
"default": {
"label": "Personal",
"baseUrl": "https://api.mem9.ai",
"apiKey": "..."
}
}
}Global default config:
{
"schemaVersion": 1,
"profileId": "default",
"defaultTimeoutMs": 8000,
"searchTimeoutMs": 15000,
"recallMinPromptLength": 5,
"updateCheck": {
"enabled": true,
"intervalHours": 24
}
}Project override example:
{
"schemaVersion": 1,
"profileId": "work",
"recallMinPromptLength": 5
}Remote update-check settings stay in the global config.
Set recallMinPromptLength to 0 to recall on every non-empty stripped user prompt.
Runtime and setup can use environment variables:
MEM9_API_URLMEM9_API_KEYCODEX_HOMEMEM9_HOME