codex-lcm
Provides local, lossless context management for OpenAI Codex CLI sessions, capturing conversation events, compacting older context into hierarchical summaries, and exposing MCP tools for lexical recall and source expansion.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@codex-lcmsearch my Codex session history for the term 'flaky test'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
codex-lcm
Local, lossless context management for OpenAI Codex CLI.
codex-lcm captures Codex conversation events in SQLite, compacts older context into a hierarchy of summaries without deleting the source messages, restores relevant context when a session starts, and exposes lexical recall through a local MCP server.
Meaning of “lossless”: source content is retained after configured secret redaction. Searchable tool previews are bounded, while complete redacted tool input and output remain available through paged expansion.
Status and platform
codex-lcm is beta software for macOS. It relies on Codex hooks and POSIX flock; Windows and Linux are not currently supported or claimed.
Related MCP server: memtree
Features
Live capture: user prompts, assistant responses, and tool activity are captured through Codex hooks.
Durable local storage: SQLite in WAL mode stores raw messages, structured message parts, summaries, and FTS5 indexes.
Hierarchical compaction: older messages become leaf summaries; eligible summary runs can be condensed into deeper DAG nodes. Source rows are never deleted automatically.
Context restore: active summaries and the newest unsummarized messages are injected at session start within a strict size bound.
Local recall: six stdio MCP tools provide lexical search, recent-session lookup, metadata inspection, and paged source expansion.
Fail-open hooks: capture or compaction failures do not block a Codex turn.
Safety controls: secret redaction, per-session compaction locks, atomic message/FTS writes, provider-call reservations, progress checks, and private default file permissions.
Install from a repository checkout
python3 -m venv ~/.codex-lcm/venv
~/.codex-lcm/venv/bin/python -m pip install .
~/.codex-lcm/venv/bin/codex-lcm install
~/.codex-lcm/venv/bin/codex-lcm doctorRestart Codex after installation. Use /hooks in Codex to inspect and trust the installed hooks.
The installer merges codex-lcm entries into ~/.codex/hooks.json and ~/.codex/config.toml. It creates timestamped backups before changing existing files. Running the installer again is idempotent.
A source checkout also includes scripts/install.sh, which performs the same isolated installation and verification.
Optional LLM summarization
On Python 3.11+, the core package has no third-party runtime dependencies. Python 3.10 installs the tomli compatibility backport for safe TOML configuration handling. Without an LLM client, compaction uses deterministic head/tail truncation.
To enable OpenAI-compatible summarization, install the optional extra and configure credentials:
~/.codex-lcm/venv/bin/python -m pip install ".[llm]"
export CODEX_LCM_API_KEY="..."OPENAI_API_KEY is also recognized. Use CODEX_LCM_BASE_URL or OPENAI_BASE_URL for an OpenAI-compatible endpoint. The CODEX_LCM_* provider settings are treated as a pair and take precedence as a pair, so a global key is never sent to a scoped endpoint. When CODEX_LCM_BASE_URL is set, configure CODEX_LCM_API_KEY too.
CLI
codex-lcm install Wire hooks and the MCP server into Codex
codex-lcm uninstall Remove codex-lcm wiring and keep stored data
codex-lcm status Show database statistics
codex-lcm doctor Verify package, database, hooks, and MCP wiring
codex-lcm compact --session <id> Compact one session synchronously
codex-lcm compact --all Compact every recorded session synchronouslyUninstalling does not delete ~/.codex-lcm/ or its database.
MCP tools
Tool | Purpose |
| Database and active-session statistics |
| Literal and FTS5 lexical search over messages and summaries |
| Ranked lexical recall with bounded result counts |
| Summary-source inspection or paged raw-message recovery |
| Sessions updated inside a UTC look-back window |
| Session or summary metadata |
Recall is lexical, not semantic: there are no embeddings or vector-similarity claims in this release.
Configuration
Configuration is read from environment variables.
Variable | Default | Purpose |
|
| SQLite database path |
|
| Newest raw messages protected from compaction |
|
| Maximum estimated tokens in a leaf chunk |
|
| Active leaf summaries required for condensation |
|
| Active deeper summaries required for condensation |
|
| Compaction rounds per worker run |
|
| Provider attempts allowed per session and call window |
|
| Provider-attempt accounting window |
|
| Provider request timeout |
|
| Marks a compaction run stalled below this savings ratio |
|
| Restore-context budget in estimated tokens |
|
| Extra unsummarized messages allowed before |
|
| Leaf summarization model |
|
| Condensation model |
| — | Optional provider credential |
| — | Optional OpenAI-compatible endpoint |
|
| Set to |
|
| Searchable tool-input preview length |
|
| Searchable tool-output preview length |
The default data directory is mode 0700; the database, WAL sidecars, lock files, and compaction log are mode 0600 on POSIX systems.
Data and security boundaries
Redaction occurs before persistence for known API keys, tokens, authorization headers, password/secret assignments, JWTs, and PEM private keys.
Credential-bearing Git remote URLs are stored without user information, query parameters, or fragments.
Redaction is defence in depth, not a guarantee that every possible secret format will be recognized.
Complete redacted tool payloads can still contain private conversation or project data. Protect the local account and database backups accordingly.
No data is sent to an LLM provider unless the optional client is installed and provider credentials or a base URL are configured.
Automatic retention and deletion are intentionally absent. The application does not silently discard source history.
Development
Use a project-local environment; tests never need the live Codex profile or database.
python3 -m venv .venv
.venv/bin/python -m pip install -e ".[dev]"
.venv/bin/python -m pytest -q
.venv/bin/python tests/smoke_test.py
.venv/bin/python tests/reliability_test.py
.venv/bin/python tests/package_test.py
.venv/bin/ruff check .
.venv/bin/bandit -q -r codex_lcmThe package test builds and installs into a throwaway home directory and virtual environment. The smoke and reliability scripts also use temporary databases.
See DESIGN.md for the storage model, invariants, hook flow, and failure behaviour.
License
MIT
Available Tools
6 toolslcm_describeC
Structured metadata for a session or summary.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | No | ||
| summary_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden, and it discloses almost nothing: it doesn't say whether this is a read-only lookup, what happens with an unknown id, or what the metadata contains. The only behavioral hint is that two entity types (session, summary) are addressable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single clause is front-loaded and contains no filler, but it is sized for a much simpler tool than a two-parameter metadata lookup with zero schema documentation. Brevity here reads as under-specification rather than economy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No annotations, no output schema, and no parameter descriptions mean this one fragment must carry everything, and it doesn't. An agent cannot determine exclusivity rules, return shape, or how this differs from sibling metadata tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description only vaguely implies the two parameters map to 'session' and 'summary'. It never says the parameters are optional, whether they are mutually exclusive, what happens if both or neither are supplied, or what identifier format is expected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource ('structured metadata for a session or summary') and the tool name supplies the verb 'describe', so an agent can infer this retrieves metadata. But it never states that it returns/describes data, and it gives no differentiation from siblings like lcm_status or lcm_recall, which also sound like metadata readers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite, and no mention of alternatives among lcm_expand, lcm_recent, lcm_status, lcm_grep, or lcm_recall. The only implicit signal is that it targets a session or summary rather than a search or listing operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lcm_expandB
Drill into a summary: for a leaf summary returns its source messages, for a condensed summary returns its parent summaries.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Character offset for paged raw expansion. | |
| max_chars | No | Characters to return (maximum 2000). | |
| session_id | No | Session id for raw message expansion. | |
| summary_id | No | The summary id (sum_...). | |
| message_seq | No | Message sequence for raw expansion. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it only discloses the return-shape branching for summary expansion. It says nothing about the raw message expansion path implied by session_id/message_seq, the 2000-character cap, offset paging, or whether the operation is read-only. That leaves a mutation-free but behaviorally nontrivial tool under-described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the action, using a parallel two-clause structure that maps cleanly onto the two branch outcomes. No filler and nothing buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The main summary-expansion semantics are complete enough to call correctly, and the schema documents the raw-expansion parameters at full coverage. Still, the description never acknowledges that two distinct invocation modes exist or that results are paged, which an agent needs to interpret a truncated response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already documented in the schema; the description adds only the conceptual link between summary_id and which result set comes back. It contributes no format, constraint, or mutual-exclusivity guidance beyond that baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
A specific verb ('drill into') applied to a specific resource ('a summary'), with the two outcome branches spelled out (leaf → source messages, condensed → parent summaries). It is distinguishable from lookup-style siblings like lcm_describe or lcm_grep, though it never names them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the reader infers this is the tool to use once they hold a summary id and need to go one level deeper. There is no explicit when-to-use versus lcm_describe/lcm_recall/lcm_grep, and no statement of preconditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lcm_grepA
FTS5 lexical search with literal substring fallback across messages and summaries. Returns snippets with session and summary references.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results (default and maximum 10). | |
| query | Yes | Search terms. | |
| session_id | No | Optional session to restrict search to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses the search mechanism (FTS5 with literal substring fallback) and return shape (snippets with session/summary references), but it omits ranking behavior, case/substring semantics, ordering, and confirmation that the operation is read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with no filler. The core mechanism, scope, and return format are front-loaded and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity three-parameter search tool, it covers what is searched and what is returned adequately. However, the absence of annotations and lack of sibling-routing guidance leave the agent without enough context to confidently choose lcm_grep over lcm_recall or lcm_recent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already defines query, limit, and session_id. The description adds no parameter-level meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: lexical search across messages and summaries, with deterministic fallback. It is clearly a search tool and distinguishable from siblings like lcm_recent and lcm_expand, though it does not explicitly contrast with lcm_recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The FTS5 lexical search framing implies a keyword/exactish search use case, but the description gives no explicit when-to-use guidance, exclusions, or comparison to alternatives such as semantic recall or recent-message listing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lcm_recallB
Lexical FTS5 recall with literal substring fallback across retained summaries and raw messages.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results (default and maximum 5). | |
| query | Yes | What are you trying to remember? |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It usefully discloses the lexical FTS5 search behavior, literal substring fallback, and searchable corpus, but it does not explicitly state that the operation is read-only or describe result ordering, output shape, or limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is a single efficient sentence with no filler. It is front-loaded with the retrieval mechanism, though the dense technical phrasing could be slightly clearer for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter retrieval tool with fully documented schema fields, the description covers the search mechanism and corpus. However, it omits return format, result ordering, and sibling differentiation, which are relevant because no output schema or annotations are provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both query and limit. The description adds corpus context but no additional parameter-level meaning, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific retrieval mechanism and corpus: lexical FTS5 recall with substring fallback across retained summaries and raw messages. It is clear what the tool does, but it does not explicitly distinguish itself from sibling tools such as lcm_grep or lcm_recent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance about when to use this tool rather than lcm_grep, lcm_recent, lcm_expand, or lcm_describe. The query parameter's text hints at remembering, but the description itself leaves usage selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lcm_recentC
Recent activity across sessions in a time window.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | Look-back window in hours (default 24). | |
| limit | No | Max sessions (default and maximum 20). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, yet it only states that results are recent activity across sessions. It does not clarify read-only/non-destructive behavior, output shape, pagination or limit behavior, or what 'activity' includes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler. It is appropriately short for a simple two-parameter tool, though its brevity contributes to gaps elsewhere rather than wasting words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity, two optional parameters, and high schema coverage, the description is minimally adequate. However, without annotations or an output schema, it should do more to explain what recent activity is returned and how the tool differs from its siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters are fully documented in the schema. The description's phrase 'time window' loosely maps to the hours parameter but adds no syntax or semantic detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a scope—recent activity across sessions within a time window—but 'activity' is vague and it does not differentiate itself from siblings such as recall, grep, or status. An agent can tell it is a recent-data tool, but not precisely what data or operation is involved.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus lcm_recall, lcm_grep, or lcm_status. The time-window framing implies a recency use case, but no alternatives or exclusions are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lcm_statusB
Health and storage status of the codex-lcm memory database.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It does communicate that this is a non-mutating inspection covering two axes (health and storage), which is enough to signal low risk, but it says nothing about cost, permissions, or whether the check can fail or time out.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the resource and the two status dimensions, and no filler. It is efficient, though its brevity is partly under-specification rather than pure economy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param diagnostic tool with no annotations and no output schema, the description leaves open what 'health and storage' actually returns (index size? record count? backend availability?). It is adequate to recognize the tool but not complete enough to predict its response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a no-parameter tool applies. The description adds no param detail because none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (the codex-lcm memory database) and a specific concern (health and storage status), which clearly distinguishes it from the sibling retrieval tools like lcm_grep or lcm_recall. It stops short of explicitly contrasting itself with those siblings, but the verb+resource pairing is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus the other lcm_* tools, nor any precondition such as 'call before lcm_recall to check the index is healthy'. Usage is only inferable from the word 'status' in the name and description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
lcm_describe - First observed
lcm_expand - First observed
lcm_grep - First observed
lcm_recall - First observed
lcm_recent - First observed
lcm_status
TDQS
Scored across 6 tools
lcm_grep and lcm_recall are nearly indistinguishable: both are described as lexical FTS5 search with literal substring fallback across messages and summaries. The remaining tools are distinct, but this overlap creates a real risk of misselection.
All tools share the lcm_ prefix and snake_case convention, which is highly predictable. Most names are verb-like, though lcm_recent and lcm_status are descriptive/adjectival rather than action verbs.
Six tools is well-scoped for a memory-database access server, covering expansion, recent activity, metadata, health, and search without excessive surface area.
The retrieval surface is fairly complete for reading and inspecting memory, including expansion and health status. However, there is no visible write/ingest operation, so agents cannot persist or update memories through this server.
Maintenance
Related MCP Connectors
Cross-tool persistent memory and context for AI assistants over MCP.
Persistent memory for AI agents to retain, retrieve, and recall conversation context through MCP.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
A paid remote MCP for OpenAI Codex context compressor, built to return verdicts, receipts, usage log
Related MCP Servers
- AlicenseBqualityCmaintenanceProvides local cross-session memory for Codex by importing transcripts, indexing in SQLite, and exposing search, context, and memory management through MCP tools.13MIT
- FlicenseNot gradedqualityDmaintenanceCollects session JSONL from Codex and Claude Code into local SQLite memory, exposed through MCP with tools for memory context, search, get, put, forget, sleep, and status.-
- AlicenseNot gradedqualityBmaintenanceCentralizes verbatim local AI conversation history into a SQLite database and exposes it via an MCP server, enabling tools like Claude Code and Codex to retrieve exact context from other tools.1 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables local-first personal knowledge management for Codex by turning conversations into a searchable archive, extracting durable facts, building a knowledge graph, and injecting relevant context into later sessions.13 npmMIT