Back to Openviking

Codex Memory Plugin

docs/en/agent-integrations/04-codex.md

0.4.1810.4 KB
Original Source

Codex Memory Plugin

Equip Codex with persistent memory across sessions. Install it once, and your OpenViking profile and memory index are loaded at session start, relevant memories are recalled with every prompt, new turns are captured after each response, and sessions are committed before compaction. The plugin also connects Codex to OpenViking's /mcp endpoint, enabling the model to call tools such as find, search, read, and remember directly.

Source: examples/codex-memory-plugin | Blog: Motivation & demo

Install

Claude Code and Codex share one installer. It asks for your language (English/中文), which harnesses to install, the download source, and your OpenViking credentials; every step is idempotent.

bash
bash <(curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/memory-plugin-shared/install.sh)

TraeCode CLI 2.0 accepts this Codex-format plugin directly. Its default installer entry is --harness trae-cli:

bash
bash <(curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/memory-plugin-shared/install.sh) \
  --harness trae-cli

In regions where GitHub is hard to reach, run the same installer from the Volcengine TOS mirror (or pick "TOS mirror" at the download-source prompt). Codex installs from a TOS-hosted git repo and keeps remote update support:

bash
bash <(curl -fsSL https://ovrelease.tos-cn-beijing.volces.com/memory-plugin-shared/install.sh)

No shell wrapper is needed anymore — the plugin ships a stdio MCP proxy that reads ~/.openviking/ovcli.conf (or OPENVIKING_* env vars) at runtime, same as the hooks. After installing:

bash
codex              # First run: approve hooks once when prompted via /hooks
<details> <summary><b>Manual setup</b></summary>

Prerequisites: Node.js >= 22, Codex >= 0.130.0, and the plugin_hooks feature enabled.

  1. Configure the connection — write ~/.openviking/ovcli.conf (url, api_key, optional account/user), or run the bundled wizard node <plugin-dir>/scripts/setup.mjs after installing.

  2. Install the plugin from the remote marketplace:

    bash
    codex plugin marketplace add volcengine/OpenViking
    codex plugin add openviking-memory@openviking
    

    Then enable plugin hooks in ~/.codex/config.toml if your build doesn't already: [features]plugin_hooks = true. Update later with codex plugin marketplace upgrade openviking.

</details>

Verify

Launch codex; on the first prompt of a session, the SessionStart hook should load your profile, and the plugin should then recall relevant memories for every prompt. Set OPENVIKING_DEBUG=1 to write events to ~/.openviking/logs/codex-hooks.log. For TraeCode CLI 2.0, launch trae-cli and use trae-cli plugin list to confirm the plugin is enabled.

How it works

The plugin integrates with Codex's lifecycle by hooking into key events. On SessionStart (startup, clear, or resume), it injects profile.md plus URI and abstract indexes for preferences/ and entities/ through the same shared, CJK-aware profile builder used by the other coding-agent integrations. It then searches OpenViking and injects relevant memories before every prompt (UserPromptSubmit), appends new turns to the session after each response (Stop), commits the full transcript before compaction (PreCompact), and commits the session when the thread shuts down (SessionEnd) so memory extraction processes the entire conversation. Upon starting a fresh session, it also sweeps any orphaned sessions left by previous runs. A resumed session may combine the fixed profile block with its latest archive digest.

Known limitation: SessionEnd requires Codex 0.145 or newer, and it only fires on a graceful exit (/quit, /exit, double Ctrl-C, EOF, end of a codex exec run). It does not fire on SIGTERM, a closed terminal, kill -9, or a crash, and it is deferred when the TUI runs against a codex app-server daemon. Those sessions — and every session on Codex older than 0.145, and any TraeCode CLI build without it — are recovered by the idle-TTL sweep (30 minutes) at the next SessionStart.

Tool calls and results are captured as dedicated tool parts, and tool_output is reported verbatim. Truncation is the server's job: output larger than tool_output_externalization.threshold_chars (default 20000) is written to the session's tool-result store, and the part keeps a synopsis stub plus tool_output_ref, so the original stays readable through /api/v1/sessions/{id}/tool-results.

<details> <summary><b>Configuration</b></summary>

Credential source: env vars win by default — when any OPENVIKING_* credential env var (OPENVIKING_URL/OPENVIKING_BASE_URL, OPENVIKING_BEARER_TOKEN/OPENVIKING_API_KEY, OPENVIKING_ACCOUNT, OPENVIKING_USER, OPENVIKING_PEER_ID) is set, its value takes precedence over the active ovcli.conf. Only when none of them are set does the active ovcli.conf (OPENVIKING_CLI_CONFIG_FILE or ~/.openviking/ovcli.conf) drive hooks, MCP proxy, and child ov commands together, so ov config switch <name> takes effect on the next launch. Set OPENVIKING_CREDENTIAL_SOURCE=cli to force the active ovcli config even while credential env vars are present. Fields not covered by either fall back to ovcli.conf, then ov.conf, then built-in defaults.

Env VarDefaultDescription
OPENVIKING_URL / OPENVIKING_BASE_URLFull server URL
OPENVIKING_API_KEYAPI key (sent as Authorization: Bearer)
OPENVIKING_CLI_CONFIG_FILE~/.openviking/ovcli.confActive CLI config to use for hooks, MCP, and child ov commands
OPENVIKING_CREDENTIAL_SOURCEautoauto prefers env-var credentials when any are set; cli forces the active ovcli config, env forces env vars
OPENVIKING_NO_AUTO_INJECTfalseDisable fixed session-start profile/background injection without disabling per-prompt recall
OPENVIKING_PROFILE_TOKEN_BUDGET10000CJK-aware token budget for profile.md plus preferences/ and entities/ indexes
OPENVIKING_CODEX_IDLE_TTL_MS1800000SessionStart idle-TTL sweep threshold
OPENVIKING_CODEX_LOCK_WAIT_MS120000 (SessionEnd), 40000 (PreCompact)How long a capture hook waits for the per-session state lock
OPENVIKING_CODEX_COMMITTED_TTL_MS2592000000How long a committed session's transcript cursor is kept before its state file is retired
OPENVIKING_DEBUGfalseWrite logs to ~/.openviking/logs/codex-hooks.log

If recall latency matters most, see Low-latency recall for the environment-variable and ovcli.conf settings that disable query expansion and Codex's local result compression.

Additional tuning options (e.g., OPENVIKING_RECALL_LIMIT, OPENVIKING_CAPTURE_ASSISTANT_TURNS) are documented in the plugin README.

</details>

Workspace peer

Memories are filed under a peer derived from the repository you are working in, so one project keeps one memory across clones, worktrees, and subdirectories. The default peer.source: "git" uses the repository's normalized origin URL — with origin [email protected]:volcengine/OpenViking.git, the peer is github.com-volcengine-openviking — falling back to the repository root path; outside a repository no peer is sent at all, and what is remembered there goes to your user-level space at viking://user/<you>/memories. A fork has its own origin, so it stays a separate peer.

Change it with OPENVIKING_PEER_SOURCE, with plugin.peerSource in ovcli.conf, or with peer.source in the workspace's .openviking/config.json (a "version": 1 file the team can commit): "cwd" restores the previous behavior — the working directory with every non-alphanumeric character replaced by -"none" sends no peer, and a template such as "team-{dir}" builds your own. To give a directory that is not a repository its own memory, create .openviking/config.json in it containing {"version": 1, "peer": {"id": "my-project"}}. Memories written under the earlier cwd-derived peer are still recalled, so nothing needs migrating. The layer precedence and the full workspace-file schema are in Client Configuration → Workspace Configuration.

Troubleshooting

SymptomCauseFix
MCP tool calls fail with an auth errorThe active ovcli config has no valid api_key for an authenticated serverFix ~/.openviking/ovcli.conf (or run node <plugin-dir>/scripts/setup.mjs) and restart Codex; the stdio proxy re-reads it on launch and after auth failures.
MCP tool calls fail with a connection errorServer unreachable or the URL is wrongCheck the endpoint: curl "$(jq -r '.url' ~/.openviking/ovcli.conf)/health"
4 hooks need reviewSecurity review on first launchRun /hooks within Codex and approve the hooks.
Plugin still targets an old server after ov config switchCodex keeps the proxy process from the previous sessionRestart Codex; the proxy resolves credentials at startup.
Hooks use one server, MCP anotherStale OPENVIKING_* credential env vars in one context (env vars override ovcli.conf by default)Unset the stale env vars (ovcli.conf then drives both), set OPENVIKING_CREDENTIAL_SOURCE=cli, or make the env vars consistent.

See also