Skip to content

Latest commit

 

History

History
350 lines (287 loc) · 17.2 KB

README.md

File metadata and controls

350 lines (287 loc) · 17.2 KB

KMP plugin — discovery for agents and humans

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.

Install

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.gz

Codex 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.

Catching up

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@underpass

Run 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 --hermes

That 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 --pi

The 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 --pi fails unless that package is registered and enabled, and points to underpass setup.
  • A plain kmp-mcp setup or kmp-mcp update (no host flag) never fails because of Pi: when the package is missing, its KMP extension is excluded, or settings.json is unreadable — including after an earlier run converged Pi — it converges the other hosts and reports Pi as skipped with a warning in the receipt.
  • Skills are mirrored into <Pi home>/skills only when kmp-mcp runs 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.

The guide arrives on its own

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.

See something in the first minute

kmp-mcp demo

writes 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.

Agent routing policy

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-request

A 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.

What you get

For the agent — the kmp-memory skill

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 why and evidence: 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.

For you — ten commands

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.

The doctor

/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 fixture loudly: those responses look real and are canned;
  • data directory — which one wins under the resolution order (KMP_MCP_DATA_DIR → the selection saved with kmp-mcp config memory-store → project .kernel/ → XDG fallback), and why;
  • tool surface — a real tools/list over 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.sh

Backends

The 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.