KMP is local-first memory for coding agents. It runs beside Codex, Claude Code and Hermes Agent as one small binary with an embedded SQLite store, and it remembers what was decided, what the evidence was and when it happened. Never the transcript. No account, no service, no API key: memory stays on your machine.
Ask your agent "Why did we choose SQLite?" and it answers from stored
evidence, or says UNKNOWN instead of guessing. Ask "Show me the memory
behind this decision" and ChronoLoom, the viewer that ships inside the
binary, opens on that decision and lights up its proof path, with time as a
dimension you can move through and a view the agent and you steer together.
Memory tools retrieve and audit the evidence, view tools steer that shared
ChronoLoom view, and the running server's tools/list defines the current
surface.
The native plugin supplies skills, host discovery and one MCP registration
for Codex and Claude Code. Setup installs the matching engine. Hermes Agent
uses the native lifecycle described below. Project instructions can opt into
memory routing; setup does not edit AGENTS.md or CLAUDE.md.
From a release package — each GitHub Release attaches
kmp-plugin-<version>-<os>-<arch>.tar.gz with a per-archive .sha256
checksum. The bundle is self-contained: it carries the kmp-mcp binary in
bin/, both host manifests, the skill, the commands and the launcher
scripts. Verify, unpack, and point the host at the resulting kmp/
directory:
sha256sum -c kmp-plugin-<version>-<os>-<arch>.tar.gz.sha256
tar -xzf kmp-plugin-<version>-<os>-<arch>.tar.gzCodex reads .codex-plugin/plugin.json and starts kmp-mcp from PATH.
Claude Code reads
.claude-plugin/plugin.json and starts through .mcp.json →
scripts/run-embedded-mcp.sh, which can prefer the binary bundled in a
release package. Put the bundled bin/ on PATH for Codex. On Windows hosts,
Claude uses scripts\run-embedded-mcp.cmd. To build the package from a checkout:
bash scripts/plugin/package-kmp-plugin.sh.
Claude Code — native install from KMP's co-located stable marketplace:
/plugin marketplace add underpass-ai/kmp@marketplace
/plugin install kmp@underpass
A marketplace install brings the skill, the commands and the launcher, but not
the binary — bin/kmp-mcp is gitignored, so it exists only in a release
package. That is what /kmp:setup is for: it downloads the engine matching
this plugin's version, from the release that published it, verified against
the checksum published beside it, and no Rust toolchain is involved.
/kmp:setup
The launcher resolves an engine matching the plugin version, checking the
bundled engine and the engine on PATH. Claude-only setup installs the
plugin-owned engine; Codex needs its matching engine on PATH. An explicit
KMP_MCP_BIN overrides resolution. If no matching engine is available, the
launcher stops and asks you to run setup.
cargo install kmp-mcp --locked remains the fallback for a platform with no published
asset, and a release package remains the way to install a pinned pair with no
download step at all.
The Claude Code session-start hook checks GitHub Releases at most once per day. It is silent when the plugin and engine are current, and fail-open when offline. If both halves are two releases behind together, it still notices — equality is not mistaken for freshness — and offers one command:
/kmp:setup
Setup bootstraps through scripts/kmp-install-binary.sh; updates use
scripts/kmp-update.sh. The native lifecycle aligns the host plugin and
checksummed engine with the requested release. Codex uses the native kmp-setup
skill; it does not copy prompts, edit AGENTS.md, or add global MCP wiring.
Both paths finish with one restart because a running host keeps the MCP
inventory it started with.
Codex CLI — install the native plugin. It owns both the skills and the
PATH-based MCP declaration, so it does not need a second registration in
~/.codex/config.toml:
codex plugin marketplace add underpass-ai/kmp --ref marketplace
codex plugin add kmp@underpassRun the native kmp-setup skill to install the matching engine and diagnose
the result. Re-running it preserves the plugin as the single MCP owner.
The native plugin is the only supported Codex owner. Do not add a second
global mcp_servers.kmp table or copy prompts and AGENTS fragments beside it.
Hermes Agent — no plugin marketplace; the native lifecycle registers the
engine through Hermes' own CLI and mirrors the kmp-* skills into
$HERMES_HOME/skills:
kmp-mcp setup --hermesThat runs hermes mcp add kmp --command kmp-mcp (answering its one
tool-enable prompt non-interactively) and copies the skill directories where
Hermes scans for them. Finish with a Hermes restart so the MCP tools load —
the same one-restart rule as Codex and Claude Code. kmp-mcp doctor
inventories Hermes as a peer host: registration owner, skills present and
the engine proof from PATH.
Pi coding agent — Pi has no native MCP and no plugin marketplace. KMP
reaches Pi through the pi-runtime Pi package, which underpass setup
installs (pi install …); the KMP lifecycle never installs Pi packages. Once
the package is present, converge the skills and the shared engine:
kmp-mcp setup --piThe Pi agent home is resolved the way Pi resolves it: $PI_CODING_AGENT_DIR
(empty counts as unset, a leading ~ expands to $HOME), otherwise
~/.pi/agent. The registration evidence is the pi-runtime entry under
packages in its settings.json; a package filter that excludes
src/adapters/inbound/pi/entry/kmp.ts reports KMP as disabled.
setup --pifails unless that package is registered and enabled, and points tounderpass setup.- A plain
kmp-mcp setuporkmp-mcp update(no host flag) never fails because of Pi: when the package is missing, its KMP extension is excluded, orsettings.jsonis unreadable — including after an earlier run converged Pi — it converges the other hosts and reports Pi asskippedwith awarningin the receipt. - Skills are mirrored into
<Pi home>/skillsonly whenkmp-mcpruns from a source checkout; released binaries only verify the registration and do not copy skills. This is the same limitation as Hermes.
The package's extension runs kmp-mcp from PATH, so kmp-mcp doctor
inventories Pi as a peer host with the same engine proof as Codex and Hermes.
Setup installs the assets without writing a store. The first guide read on a
fresh embedded store — kmp_guide, or an inspect of a guide node — seeds both
installed guides from the assets that match the engine: the plugin root the
launcher names in KMP_PLUGIN_ROOT, the plugin a bundled engine lives in, or
the Claude or Codex plugin cache for this version. It happens once per session,
through the ordinary writer, and the guide abouts never enter a project's
committed bundle. /kmp:guide in Claude Code, or kmp-guide in Codex, still
opens the human guide in ChronoLoom and forces a refresh when an upgraded guide
must replace a partial or older one. A store with no matching assets anywhere
returns GUIDE_UNAVAILABLE, naming where it looked and the explicit
kmp-mcp guide sync repair; a shared gRPC kernel always uses that explicit
sync.
kmp-mcp demowrites a worked example — a checkout service, an incident, the decision that
replaced an earlier one and the measurement that verified it — into the store
this directory resolves to, opens ChronoLoom on it and prints four questions
to ask your agent. It is idempotent and never enters a project's committed
bundle. --no-viewer writes and exits.
kmp-mcp config shows the policy agents receive at MCP initialization and the
file that owns it.
The policy opens with a gate. By default memory is opt-in: an agent calls a
kmp tool when the user asks for KMP or its memory, when a kmp skill or command
runs, or when the project's own instructions opt in — and otherwise makes no
call. Everything after the gate governs a route already underway. An operator
who wants known work to enter through kmp_wake unprompted asks for it:
kmp-mcp config memory-routing always
# or back to opt-in
kmp-mcp config memory-routing on-requestA semantic question is asked in the kernel's search language: the agent
renders it in plain English, keeps every number, identifier and acronym the
user wrote, and passes the user's own words as asked_as. The kernel searches
the rendering as given, echoes asked_as on the answer, and warns when the
rendering dropped an identifier or leans to another language. If the English
question returns UNKNOWN, the agent re-asks once in the user's own words and
stops. With a lexical-bridge table beside the store, kmp_ask also crosses
languages inside the kernel and names the word pairs that carried a citation.
There is no language setting to configure.
A writer can also attach an English rendering of a memory as the reserved
entry metadata key summary_en. kmp_ask searches it and never cites it, so
an English question reaches Spanish memory and the citation stays the Spanish
text byte for byte. kmp_ingest warns about a summary the lint refuses —
wrong language, too thin, a copy of the text, a dropped identifier — and
ranking makes the same reading, so such a summary carries nothing. A citation
the summary carried says so: matched_via: summary, with the question's words
the rendering supplied in summary_terms. kmp_write_memory takes it as
memories[].summary_en, and a strict write requires it when the memory is not
written in English. Older memories that owe one are listed by kmp-mcp summaries pending and attached with search_summaries.
Questions in Chinese, Japanese or Thai are not segmented by word yet. Storage remains byte-exact; word-based semantic retrieval in those scripts is not supported.
The fallback translates only the query. The answer follows the user's
language; evidence text, refs, relation why, and source metadata remain
byte-for-byte as stored. Temporal requests such as “yesterday” or a release
window bypass semantic Ask: the agent resolves the user's timezone, navigates
the half-open UTC interval [start, end) and consumes every page. Pass the
interval directly to temporal navigation and follow the returned continuation;
the start is included and the end is excluded. A semantic question that merely carries a date — why
something was decided in March — is one kmp_ask with that interval as
interval, or the instant as as_of: the kernel admits only what fell
inside, reads supersession and expiry as they stood then, and an UNKNOWN
names the nearest match outside the span.
Setup and update install the versioned guide assets but never select or write
a memory store. The first guide read seeds them into the store it was asked
about: guide:kmp-agent explains every live verb to the agent and guide:kmp
is the short human path. /kmp:guide opens the human path and forces an
explicit, deterministic refresh when one is needed. Check the selected store
before synchronizing explicitly.
Use it after the routing gate opens: a request for KMP or its memory, a KMP workflow, project instructions, or the configured always-on policy. It carries the operating doctrine:
- recover before re-deriving —
kmp_wake {about}before reading files to reconstruct context that may already be stored; - route every result, not only the first request — an unanswered semantic
Ask about current state, a release or decision history moves to temporal
navigation, while a genuinely semantic question may end at
UNKNOWN; - write decisions, constraints and outcomes — never transcripts;
- rich relations carry both
whyandevidence: the first explains the semantic connection and the second proves that rationale; - audit what the answer relies on — inspect a cited ref and trace a claimed connection rather than treating retrieval as proof of either.
The skill points at tools/list as the authority on the relation vocabulary,
because that catalog is generated from the kernel's own writer spec and moves
with the kernel. The skill teaches the shape; the schema carries the truth.
kmp_guide starts with a brief capability map and a persistent agent identity
with a random display name. Open one worked card by topic and consult its
extended verb when needed. Context resets preserve identity; delivery records
mean guidance was served, not learned. Agent metadata stays outside memory
retrieval. The versioned lessons reach a fresh store on the first guide read;
/kmp:guide refreshes them explicitly when needed. The separate guide:kmp is
for people and opens visually in ChronoLoom.
The payoff appears on the read path: kmp_wake reconstructs the causal
spine, kmp_ask can keep the right citation when the question is
paraphrased, and kmp_trace / kmp_inspect expose the original
rationale and proof verbatim. KMP uses what the writer supplied; it never
generates a missing why. See
Relations and their evidence for the
field-by-field model, safe fallbacks and worked examples.
| Command | What it does |
|---|---|
/kmp:setup |
Installs and wires whatever is missing, then re-checks |
/kmp:doctor |
Diagnoses the setup end to end and names the one thing to fix |
/kmp:info |
What this install is and which memory this project opens — and why that one |
/kmp:moves |
The memory and ChronoLoom moves, read from the live surface when reachable |
/kmp:guide |
Opens the human guide in ChronoLoom through open:guide; refreshes the installed guides explicitly when a store needs it |
/kmp:catchup |
What changed since you last looked, from the event log |
/kmp:save |
Exports this project's maintained memory bundle and shows the diff; does not create a Git commit |
/kmp:restore |
Loads the memory committed in the repository back into the store |
/kmp:revert |
Reverts a decision without deleting it, so both states survive |
/kmp:uninstall |
Previews whole-install, one-store or one-engine removal, names the host still holding a piece, protects memory first, and only applies when explicitly asked |
Codex gets all ten as native kmp-setup, kmp-doctor and so on. Claude Code
keeps /kmp:* commands. Copied standalone Codex prompts are retired; use the
native plugin as the single owner. capabilities.json is the machine-checked
inventory that maps each workflow to its owner and exposure. The live
tools/list catalogue defines the MCP tools for the installed version. VOICE.md
remains the source of truth
for how the host workflows talk.
/kmp:doctor exists because the failure modes are specific, and they all
look identical from inside a session — the kmp_* tools are simply not
there. It separates them:
- binary — installed, on
PATH, and its version; - backend — embedded, grpc or fixture. It flags
fixtureloudly: those responses look real and are canned; - data directory — which one wins under the resolution order
(
KMP_MCP_DATA_DIR→ the selection saved withkmp-mcp config memory-store→ project.kernel/→ XDG fallback), and why; - tool surface — a real
tools/listover stdio, counting what answers; - host registration — three separate facts, never collapsed into one: the plugin is installed and enabled, the engine binary declares its tools when run directly, and a host reports a live MCP connection. Where no live probe ran, it says unverified rather than usable — a registration in an inventory is not a conversation that can call a tool.
For Codex it also detects obsolete global wiring. If an enabled plugin and a
global mcp_servers.kmp table both claim the server, Doctor names both owners
and the global store-affecting environment instead of declaring the setup
healthy.
Two failures it names rather than leaving you to guess: an unsupported store format, which current KMP detects but deliberately does not open — Doctor points to the external archive-export contract and leaves the bytes untouched — and a session that started before the registration changed and is still carrying the old inventory. The second one cannot be fixed from inside the session; you have to restart it.
Run it directly, without a host:
bash plugins/kmp/scripts/kmp-doctor.shThe plugin registers the embedded backend: the kernel runs inside the
binary, with a local SQLite store selected by the precedence described above.
For a shared deployed kernel, select the gRPC backend and configure
KMP_KERNEL_GRPC_ENDPOINT and the deployment credentials. Core memory calls
share the public contract, but backend support has limits: the summaries audit
is unavailable over gRPC, and the embedded loopback viewer requires the local
backend. See the enterprise guide.
See Embedded KMP for the current local mode, storage and maintenance contract.