@llmnesia/local-agent-host
v0.2.0
Published
LLMnesia native messaging host — lets the browser extension read local coding-agent sessions (Claude Code, Codex) automatically.
Maintainers
Readme
LLMnesia local agent host
A tiny local helper that lets the LLMnesia browser extension (1) index your local coding-agent sessions automatically — Claude Code and Codex, with no folder picking and no hidden-folder navigation — and (2) sync your LLMnesia conversation corpus for the MCP companion without the File System Access picker.
It reads .jsonl session files under ~/.claude/projects and ~/.codex/sessions. It writes only inside the corpus root named in its own config (~/.llmnesia/config.json) — there is no protocol field that lets a caller choose a different write location. It makes no network calls.
Previously published as
@llmnesia/claude-code-host. That name still works and installs this same helper; see the compatibility package.
Install
Requires Node 18+.
npx -y @llmnesia/local-agent-host@latest [--corpus <dir>] [--codex-home <dir>]For the Chrome Web Store build, no arguments are needed — the installer already knows its permanent extension id.
Only pass an id if you're running a dev / unpacked build (its id is random per machine — find it at brave://extensions or chrome://extensions with Developer mode on):
npx -y @llmnesia/local-agent-host@latest <your-dev-extension-id> [--corpus <dir>]Any ids you pass are allowed in addition to the Web Store build, so this also covers running both at once. (From a checkout of this repo you can also run it directly: node cli.mjs [<your-extension-id>] [--corpus <dir>].)
Then fully quit and reopen your browser and open LLMnesia → Settings. The "Local coding sessions" card detects the helper and switches to one-click Sync now (and auto-syncs on open).
Where Codex sessions are read from
Resolved once at install time, in this order: --codex-home <dir>, then the
CODEX_HOME environment variable Codex itself honours, then ~/.codex. The
result is written into ~/.llmnesia/config.json, because native messaging
launches the host with almost no environment — it can't re-derive CODEX_HOME
at runtime.
Works on macOS, Linux, and Windows, with Brave, Chrome, Edge, and Chromium. allowed_origins is locked to the extension id(s) you pass, so only LLMnesia can talk to the host.
Choosing the corpus root
--corpus <dir> sets where the host is allowed to write your synced conversation corpus. If you omit it, the installer resolves the same order the companion does: $LLMNESIA_CORPUS_DIR, then the default ~/.llmnesia/corpus. Point it at the same directory your MCP companion reads from.
Re-running the installer is safe: it won't move a corpus that already has a different root written unless you pass --force.
node cli.mjs <your-extension-id> --corpus ~/.llmnesia/corpus --forceWhat it installs
The host script goes to ~/.llmnesia/llmnesia-claude-host.mjs on every platform. How each browser is pointed at it differs:
- macOS / Linux: a
com.llmnesia.claude_code.jsonmanifest is written into each browser'sNativeMessagingHostsfolder, and the host script's shebang is pinned to the node that ran the installer (native messaging launches hosts with a barePATH). - Windows: a
llmnesia-claude-host.batlauncher and thecom.llmnesia.claude_code.jsonmanifest go to~/.llmnesia, and a registry keyHKCU\Software\<vendor>\NativeMessagingHosts\com.llmnesia.claude_code(per browser found) is set to the manifest path.
Plus, on every platform: ~/.llmnesia/config.json (mode 0600) → { "corpusRoot": "…" }, the host-owned write root for corpus sync. The host reads this and only this to decide where corpus deltas land; the browser can never name a write target.
Troubleshooting
If the extension's Settings page says the helper isn't answering, run:
npx -y @llmnesia/local-agent-host@latest doctorIt's read-only — checks the host script, each browser's manifest, config.json, whether Claude Code / Codex sessions were found, and pings the helper directly — and prints exactly which step is missing instead of a generic failure.
Uninstall
npx -y @llmnesia/local-agent-host@latest uninstallThis removes only the helper script, browser manifests / registry entries, and
the Windows launcher. It deliberately keeps ~/.llmnesia/config.json and the
corpus directory it names, so uninstalling the browser integration cannot erase
conversation history. Remove those separately only if you intentionally want to
delete the retained data too.
Protocol
Native messaging over stdio (little-endian uint32 length prefix + UTF-8 JSON):
{ cmd: "ping" }→{ type: "pong", version }{ cmd: "list" }→{ type: "list", sessions: [{ sessionId, mtime, project }] }{ cmd: "get", sessionId }→{ type: "chunk", sessionId, seq, total, data }× N, then{ type: "sessionDone", sessionId }{ cmd: "corpusInfo" }→{ type: "corpusInfo", present: false }, or{ type: "corpusInfo", present: true, root }if~/.llmnesia/config.jsonnames a corpus{ cmd: "putChunk", filename, seq, total, data }→{ type: "chunkAck", seq }, one call per chunk. Once every chunk0..total-1for afilenamehas arrived, the host writes<corpusRoot>/inbox/<filename>(via a.part-<pid>temp file,rename()d into place so a concurrent drain never sees a partial file).filenamemust be a bare basename — anything containing/,\, or..is rejected with{ type: "error" }and nothing is written. Transfers are bounded to 256 chunks, 512 KiB characters per chunk, 64 MiB characters across pending data, eight simultaneous filenames, and a five-minute idle lifetime. The corpus root always comes from the host's own config; it cannot be set over the protocol.
putChunk is how the extension's service worker pushes corpus sync deltas without ever holding a File System Access handle. Deltas are sent as plain uncompressed NDJSON text (each data string is written verbatim into a .jsonl file the companion drains directly), so there is no base64 or gzip round-trip. The corpus root is written by the installer into ~/.llmnesia/config.json.
Support
If doctor does not resolve the problem, email [email protected] and paste its output.
