Kemory · plugin
Agent plugin · Apache-2.0

Tools make memory possible.
Hooks make it happen.

An MCP server gives an agent memory tools. This plugin makes it actually use them: relevant memories arrive under every prompt, a turn that settles something durable does not end with it unwritten, and recalls get rated so retrieval improves instead of decaying.

It is a client and nothing more. It sends data to one place — the Kemory instance you point it at — and adds no telemetry, no analytics and no endpoint of its own. With no credential configured, every hook no-ops and nothing is sent.

One plugin, one tree, a manifest per host. Claude Code is the first host — the one it installs and is tested on today, and the commands on this page are its commands. A Grok Build manifest ships alongside and that catalog entry is in review.

Marketplace SeKondBrainAILabs/kemory-plugin

What it adds

You can reach Kemory from any host without this plugin — a config-file entry gives you the same kemory_* tools, and Connect a local client covers that path. What it does not give you is any reason for the model to reach for them. A tool sits unused unless something prompts it, and prompting is the whole of what the plugin contributes.

  • A standing instruction that ships with the plugin — nothing to paste into CLAUDE.md, nothing to keep in sync per project.
  • Prompt recall — every substantive prompt is searched against your vault and the matches arrive before the agent answers, without it deciding to look.
  • Context injection — your namespace summaries load at session start, so a session begins informed rather than blind.
  • Rate reminder — the agent rates the memories it actually used, so retrieval keeps improving.
  • Store nudgeopt-in. When a turn reached a decision and stored nothing, the turn does not just end.
  • Session captureopt-in. A bounded, redacted digest of what the session was about, stored as it goes.
  • /kemory:status — one command that says what is and is not working.

It works against hosted Kemory and against the open-source Community Edition — one variable, KEMORY_URL, moves the whole plugin.

Hosts and surfaces

The plugin is one tree with a manifest per host, so a second host is a manifest rather than a fork. ${CLAUDE_PLUGIN_ROOT} in the hook and MCP entries is what the hosts resolve, not a Claude-only spelling — the hooks, skills, commands and scripts underneath are shared.

HostManifestStatus
Claude Code.claude-plugin/plugin.jsonShips today. The host it installs and is tested on, and the one every command on this page is written for
Grok Build.grok-plugin/plugin.jsonSame manifest, same version. The catalog entry is in review

A release check fails if the two manifests drift: nothing at runtime reads both, so a version bump applied to one and not the other would ship a plugin that disagrees with itself, and the host reading the stale manifest would never see the update — every marketplace gates on the version string, not the commit.

Which Claude surface you are on

Read this before the install commands. Claude Code and Claude Desktop are different products, and only one of them has plugins at all. The row that trips people is the middle one: the plugin works there, the command to manage it does not.

SurfacePlugin: tools + hooks/pluginHow to install
Claude Code — terminalyesyes/plugin install kemory@kemory, then /reload-plugins
Claude Code — Desktop app, IDE extensionsyesnoclaude plugin install kemory@kemory in a shell, then restart the app fully
Claude Desktop — the chat appno plugins, no hookskemory mcp install --host claude-desktop, or the Kemory connector

The Desktop app and the IDE extensions read the same ~/.claude/plugins as the terminal, which is why installing from a shell is enough for them.

Claude Desktop is a different application with no plugin system: it takes MCP servers through its own config, so you get the memory tools there and none of the hooks. Claude Code on the web cannot install plugins either, and claude.ai chat has no hooks — use the Kemory connector on both.

Windows

The hooks are bash scripts calling curl and python3, so on Windows they need Git Bash or WSL. That combination is untested, so Windows is not claimed for the hooks even though the CLI runs on it natively.

Install

On Claude Code, in a terminal:

/plugin marketplace add SeKondBrainAILabs/kemory-plugin
/plugin install kemory@kemory
/reload-plugins

/reload-plugins is not optional. /plugin install says so in its own output, and until it runs the plugin's commands do not exist yet. Skipping it is the single most common way to land on Unknown command: /kemory:login after a perfectly good install.

Nothing is downloaded beyond the plugin itself: the bundled MCP entry launches a script inside the plugin, so there is no binary to install and nothing to put on PATH.

Sign in

/kemory:login

It prints one link. Open it, approve in the browser, and the credential is written for you — nothing to install, nothing to paste. It is an RFC 8628 device authorization grant against the same public client the CLI uses, so the user code is already in the URL.

It signs you in the same way kemory login does and writes the same file, ~/.kemory/credentials-<env> — so if you install the CLI later it finds you already signed in.

Restart Claude Code fully afterwards. Closing the window is not enough, and context injection begins with your next session because the hook that performs it runs at session start.

Already reach Kemory another way?

You haveDo this
The Kemory CLI, signed in with kemory loginNothing at all — that is the same credential /kemory:login writes, and both halves read it. kemory connect is only needed for other MCP hosts.
The claude.ai Kemory connectorTools already work; disable the bundled entry under /mcp so you are not running two. The hooks still need export KEMORY_API_KEY="..." — the connector's OAuth token lives inside Claude and a shell script cannot read it.
A self-hosted or Community Edition instanceexport KEMORY_URL=http://... alongside KEMORY_API_KEY. One URL moves the whole plugin.
A headless machine — CI, a container, no browserexport KEMORY_API_KEY="kemory_...". It is a long-lived secret, so prefer /kemory:login anywhere a browser exists.

Confirm it works

/kemory:status

One command, three blocks, and it is the first thing to run whenever something looks wrong.

BlockWhat it answers
HOOKSWhether a credential resolves at all, and whether the API accepts it — the two checks that have to pass.
TOOLSWhether the bundled MCP server will start, which credential it will serve with, whether another server on this machine already covers the same Kemory, and the installed plugin version.
SETTINGSHow capture and context injection are configured, and how many sessions have been captured so far.

/mcp then shows which Kemory server Claude Code is actually talking to. There is one case /kemory:status cannot see and says so rather than reporting a reassuring zero: a claude.ai connector lives inside Claude and is invisible from a shell.

Staying current

Plugins do not update themselves. What you installed is a snapshot, and hooks are where this plugin's behaviour lives — an install left alone keeps running the set that was current the day you ran it, however much has been fixed since.

/plugin update kemory@kemory

It refreshes the marketplace on its way through, so this is the whole command. Restart Claude Code afterwards to load the new hooks — the update itself does not apply them. /kemory:status prints the version you are on, and the changelog says what moved.

The repository was renamed from claude-kemory to kemory-plugin when a second host appeared. GitHub redirects the old path, so an existing /plugin marketplace add keeps working — but kemory-plugin is the name to use from here.

The hooks

Seven hooks, none of which need remembering. Five are on by default; the two that could surprise you ship off.

HookEventWhat it doesLeaves your machineDefault
context injectionSessionStartInjects your namespace summaries; warns once if Kemory is not set up yetYour credential; reads summaries backon
prompt recallUserPromptSubmitSearches your vault with the prompt you typed and injects what matchesThe text of your prompton
recall approvalPreToolUseAuto-approves Kemory read-only tools so memory stops interrupting you. Writes still ask, every timeNothingon
rate reminderPostToolUsePrompts the agent to rate the memories it actually used. Fires only when the response is rateable — a recall_id or a non-empty result listNothingon
consolidate reminderSessionStart after compactionPrompts the agent to store facts that would otherwise survive only as a summaryNothingon
store nudgeStopWhen the turn settled something durable and no Kemory write happened, asks for it before the turn endsNothingoff
session captureStop, SessionEndStores a redacted digest of your own prompts: last 12 turns, 8000 charactersYour prompts, redactedoff

Prompt recall

This is the difference between an instruction and a mechanism. Telling an agent to "recall when the topic shifts" relies on it noticing the shift; searching every prompt does not.

The query is redacted before it leaves your machine, using the same rules as capture. Prompts under 12 characters and those starting with /, ! or # are skipped, so slash commands are never sent. A memory injected once is not injected again in the same session.

Because this path uses POST /api/v1/memories/search, which returns memory ids rather than an invocation id, hook-injected memories carry no recall_id. The agent is told to rate them by memory_id; they will not appear in recall coverage metrics, which join on recall ids.

The store nudge

Every other hook feeds the model and hopes; a standing instruction asks and hopes. This is the only mechanism in the plugin that makes a write actually happen — when a turn stated a conclusion and nothing was stored, it says so before the turn ends.

The phrases it looks for are deliberately narrow: each one states a conclusion rather than merely discussing a topic. "We could use Redis" is not a decision; "we'll use Redis" is. It reads the transcript on your machine and sends nothing.

It is off by default anyway — a hook that continues a turn is disruptive when it is wrong, so it ships off until the false-positive rate has been measured on real sessions. KEMORY_STORE_NUDGE_SIGNALS adds your own |-separated regexes to the built-in set.

Session capture

Capture is off unless you set it explicitly, because it uploads conversation content to your Kemory instance.

What is captured: your own turns only — assistant replies and tool output are skipped — capped at the last N turns and 8000 characters, with common secret patterns redacted. Digests are written to POST /api/v1/memories tagged session-capture and carry the session_id, so the server-side Reflector can consolidate them into semantic summaries.

SessionEnd fires on exit, /clear and resume, so the same turns can be offered more than once. The hook stores a hash of each digest under ~/.kemory/.captured/<session_id> and skips a write whose content it has already stored, so repeats do not accumulate duplicate memories. The hash is recorded only after the write succeeds.

Why compaction is handled at SessionStart

The consolidate reminder deliberately does not use PreCompact: that event rejects additionalContext, and fires as compaction begins, so the model gets no turn in which to act. SessionStart with source=compact fires on the other side of it, where there is still something to do.

Every hook is best-effort

Missing credentials, an unreachable server, or a malformed transcript all exit cleanly and never block a session. Every network call is capped at 3–6 seconds so a dead network cannot stall a session. The hooks whose output is actually read — SessionStart, UserPromptSubmit, PreToolUse — run synchronously, because an async hook's stdout is discarded and that would silently kill context injection and read-only auto-approval while still appearing to run. Capture writes and has no output anyone reads, so it runs async.

The cost of failing open is that a broken setup looks like an idle one. A quiet session is a setup problem, not a healthy one — see Troubleshooting.

Skills and commands

Ships asWhat it is for
/kemory:loginBrowser sign-in. One link, approve, credential written for you.
/kemory:statusWhether credentials resolve, whether the API accepts them, which server will serve the tools, and how capture and injection are configured.
kemory skillHow to recall, rate, store and phrase memories so semantic search can find them again.
kemory-setup skillWalks the agent through connecting Kemory when something is not working.

The kemory skill is the standing instruction from Optimise your AIs, already written and kept current — with the plugin installed you do not need to paste it into CLAUDE.md yourself.

If you pasted that instruction into CLAUDE.md before the plugin shipped one, you can delete it; the plugin says so once a week until you do. Keeping both is not harmful, but the pasted copy asks the agent to open each session with kemory_list_namespaces and a recall, which the prompt-recall hook has already done by then.

The bundled instruction is injected on every session, including a brand-new vault and a session whose context call failed. It is short on purpose: recall and the write prompt are hooks now, so it says only what no hook can — what Kemory is, and the standard for writing to it.

Credentials

The bundled MCP entry launches a script that resolves a credential through the same function the hooks use, then serves: kemory mcp serve when the credential came from a browser login, and a bundled stdio-to-HTTP bridge when it came from the environment. So one entry covers every way of reaching Kemory, and the tools cannot end up authenticated differently from the hooks or pointed at a different host.

Resolution order is KEMORY_API_KEY, then KEMORY_TOKEN, then the stored browser login in ~/.kemory/credentials-<env>, against KEMORY_URL — defaulting to hosted Kemory. Any one of them turns on both halves. Stored tokens are refreshed automatically when they expire; if a refresh fails, /kemory:status says so rather than leaving the hooks quietly rejected.

With no credential the bundled server exits with that reason on stderr rather than starting. A server that starts and exposes nothing reads as connected in /mcp while every memory tool is missing, which is worse than a visible failure.

Two credentials, not one

The MCP tools and the hooks authenticate separately. This is the single most common source of confusion:

You haveToolsHooks
KEMORY_API_KEY in your environmentyesyes
/kemory:login or kemory login, nothing exportedyesyes
Connector or remote MCP, nothing elseyesno
A key inside an MCP config fileyesno — the hooks never read MCP config

That last row is worth stating twice: a key in .mcp.json or ~/.claude.json authenticates the tools and is invisible to the hooks. That is how you end up with working kemory_* tools and no context injection. /kemory:status detects the case and tells you; export the same key as KEMORY_API_KEY to turn the hooks on.

The plugin never writes credentials anywhere, never logs them, and refuses to send them to a URL that is not http:// or https://.

Run one server,
not two

Three routes each register an MCP server for Claude Code — a pasted pair-claim prompt, kemory mcp install, and this plugin — and they stack silently. Any two of them leave every tool duplicated in each request, with /mcp listing both without saying they are the same server twice.

So the bundled entry stands down when this machine already has a server for the same Kemory. It is the one that gives way: an entry in a host config was put there deliberately, and this one arrives with the plugin. The cost is only the duplicate — the hooks read credentials directly, so recall, context injection, rating and capture all keep working while the server stands aside, and the message says so, because "your tools moved" and "your memory stopped working" are very different sentences.

Loudly, never silently: it exits with the reason, names the offending entry and the file it is in, and gives the way back. KEMORY_ALLOW_DUPLICATE=1 runs both anyway.

Same endpoint, not same name

kemory mcp install pins the environment in its arguments precisely so production and staging can coexist as separate servers, so two entries pointing at different hosts are deliberate multi-environment work and are left alone. Each entry is resolved the way the thing that runs it would: an HTTP entry by its own URL, a kemory [--env X] mcp serve entry through the host in ~/.kemory/credentials-X. An entry whose endpoint cannot be worked out is skipped, never guessed at — failing to stand down costs duplicated tools, standing down wrongly costs you your tools entirely.

If you use the claude.ai connector, disable the bundled entry under /mcp; that is the one case the launcher cannot detect from a shell.

Configuration

Set these in the env block of ~/.claude/settings.json, or export them in your shell. Remember the rule above: an environment variable reaches both halves, a key in a config file reaches only the tools.

Credentials and target

VariableDefaultMeaning
KEMORY_API_KEYAPI key from the dashboard, sent as X-API-Key. Authenticates both the bundled tools and the hooks
KEMORY_TOKENBearer token, sent as Authorization: Bearer
KEMORY_URLhttps://api.kemory.s9n.aiOverride only for a self-hosted or Community Edition instance. No trailing slash, no path
KEMORY_ENVprodWhich credentials file to read
KEMORY_ALLOW_DUPLICATE01 starts the bundled server even when another one already serves the same Kemory

Context injection

VariableDefaultMeaning
KEMORY_CONTEXT10 disables session-start injection
KEMORY_CONTEXT_DEPTHl3Summary depth requested — l3, or l4 for a synthesised cross-namespace briefing
KEMORY_CONTEXT_MAX_CHARS4000Injection budget; summaries beyond it are dropped with a note (floor 500)
KEMORY_CONTEXT_NAMESPACESallComma-separated allowlist, e.g. user:preferences,shared
KEMORY_CONTEXT_TIMEOUT6Seconds to wait for the API before giving up
KEMORY_QUIET_SETUP01 suppresses the "not configured yet" notice

If Kemory is not configured, the hook prints one short setup notice and then stays quiet for 24 hours rather than nagging every session.

Prompt recall

VariableDefaultMeaning
KEMORY_PROMPT_RECALL10 stops the per-prompt vault search, and with it the only default-on transmission of your prompt text
KEMORY_PROMPT_RECALL_LIMIT5Maximum memories injected per prompt
KEMORY_PROMPT_RECALL_MIN_RELEVANCE0.55Raw-cosine relevance floor — not the blended min_score
KEMORY_PROMPT_RECALL_ITEM_CHARS600Per-memory truncation in the injected block
KEMORY_PROMPT_RECALL_NAMESPACEallRestrict recall to one namespace
KEMORY_PROMPT_RECALL_TIMEOUT3Seconds to wait for the API

Store nudge and session capture

VariableDefaultMeaning
KEMORY_STORE_NUDGE01 asks for a write when a turn settled something and stored nothing
KEMORY_STORE_NUDGE_SIGNALSExtra |-separated regexes that mark a turn as worth storing, added to the built-in set
KEMORY_AUTO_CAPTURE01 enables the redacted session digest
KEMORY_CAPTURE_NAMESPACEsharedNamespace digests are written to
KEMORY_CAPTURE_MAX_TURNS12Maximum user turns in a single stored memory
KEMORY_CAPTURE_MIN_NEW_TURNS3New turns required before a mid-session Stop stores anything; SessionEnd flushes any remainder
KEMORY_CAPTURE_SOURCEclaude-codeValue recorded in the memory's metadata.source

What leaves
your machine

Two hooks transmit anything at all.

  • Prompt recall is on by default and sends the text of each prompt to your Kemory instance as a search query. It skips prompts under 12 characters and anything starting with /, ! or #, so slash commands are never sent.
  • Session capture is off unless you set it, because it uploads your own turns.

Context injection sends only your credential. The recall-approval, rate-reminder and store-nudge hooks make no network calls at all. Separately, when a stored login has expired the hooks refresh it against the identity provider named in the credential file.

export KEMORY_PROMPT_RECALL=0   # stop sending prompt text
export KEMORY_AUTO_CAPTURE=1    # turn capture on (off by default)
export KEMORY_STORE_NUDGE=1     # turn the store nudge on (off by default)

Redaction

One set of rules, shared by both hooks that send text. It strips credential shapes — bearer tokens, api_key= and password= style assignments, sk-, gh*_, AWS access key ids, Slack xox* tokens, JWTs and PEM private-key headers — replacing each with [REDACTED]. A keyword only triggers when it is followed by an actual assignment and a value long enough to be a credential, so ordinary prose about tokens and secrets survives intact.

This is pattern-matching, not a guarantee. A novel or unusual secret format can pass through. Treat it as a safety net; if you work with sensitive material, leave capture off.

Local files

~/.kemory/.captured/ and ~/.kemory/.nudged/ hold per-session hashes used to avoid storing or asking twice; ~/.kemory/.setup-hint and ~/.kemory/.paste-hint hold timestamps that throttle one-off notices. None contains conversation content.

At session start the plugin also reads ~/.claude/CLAUDE.md and a CLAUDE.md in the current directory, looking only for a hand-pasted copy of the Kemory instruction so it can tell you the plugin now ships one. The file contents are never sent anywhere, never stored, and never edited.

Injected context is conversation content

Whatever the plugin injects becomes part of your Claude Code conversation, so it reaches Anthropic on the same terms as anything else you type there.

Storage and deletion

What you send is stored as memories in your own vault, scoped to your organisation and user. Encryption at rest is opt-in per account and off until you enable it. Memories persist until you remove them — there is no automatic expiry unless you set a TTL when storing.

Removal comes at two levels, and the difference matters:

ActionWhat it does
kemory_delete_memory, kemory_forgetSoft delete. The memory stops being active and stops coming back in recall, but the row remains.
DELETE /api/v1/user/memory-dataIrreversible erasure. Every memory for your user in that organisation, everything derived from them — session summaries, session digests, the consolidated namespace summary — and your memory encryption key along with it. The response tells you which of the two you got.

If your vault was encrypted, destroying that key makes any ciphertext surviving in a backup permanently unrecoverable; if it was never encrypted, that call is an ordinary hard delete.

Who else can see it

Memories default to user-private and are isolated per organisation; nothing crosses to another organisation. You can widen a memory to team or org-public yourself — see Scoping and sharing.

The hosted service builds the namespace summaries that context injection reads by sending memory content to an LLM sub-processor. Embeddings are computed with a local model and do not leave the service. On a self-hosted instance both are whatever you configured, and the plugin itself adds no sub-processor. The sub-processor list is the authoritative record and covers the whole platform, not just this plugin.

The service itself is governed by the SeKondBrain Privacy Policy.

Troubleshooting

The hooks fail quiet by design, so a broken setup looks like an idle one. Run /kemory:status first — it names which check failed, and the table below acts on what it says.

What you seeWhat it meansWhat to do
Unknown command: /kemory:loginThe plugin is installed but not loaded yet — not a failed installRun /reload-plugins
/plugin "isn't available in this environment"You are in the Claude Code Desktop app or an IDE extensionclaude plugin install kemory@kemory in a shell, then restart the app fully
No kemory_* tools at allThe bundled server did not start — usually no credential, or it stood down for a duplicate/kemory:status names which; then /kemory:login, or remove the other entry
Tools work, nothing at session startThe credential is in an MCP config file, which the hooks never readexport KEMORY_API_KEY="..." in your shell, then restart fully
Two copies of every toolTwo servers for the same KemoryDisable the bundled entry under /mcp, or remove the config-file entry
401 on every callThe stored login expired or was revoked, or the key was reissued/kemory:login, or mint a new key
Installed, signed in, still quietClaude Code was not restarted, or this is the session the credential arrived inQuit completely and reopen — injection starts with the next session
Recall returns nothing usefulThe relevance floor is above what your vault matchesLower KEMORY_PROMPT_RECALL_MIN_RELEVANCE, or raise KEMORY_PROMPT_RECALL_LIMIT
Unknown tool on an s9nmem_* nameA standing instruction or rules file written before the August 2026 renameChange those names to kemory_*; reconnecting will not fix it

A hook that quietly does nothing is not evidence of a healthy setup. If /kemory:status is green on every line and sessions still start blind, check /mcp to see which server Claude Code is actually talking to.

Source and contributing

Apache-2.0, and the whole client lives in one tree:

plugin/
├── .claude-plugin/plugin.json
├── .grok-plugin/plugin.json
├── .mcp.json                     bundled MCP entry → scripts/mcp.sh
├── hooks/hooks.json
├── commands/                     /kemory:login, /kemory:status
├── skills/                       kemory, kemory-setup
└── scripts/                      one script per hook, plus lib and redact

Three ground rules govern a change: a hook must never block or fail a session and exits 0 on every error path; the plugin must no-op safely with no credential and no server; and anything that sends data anywhere must be opt-in and documented. One deliberate exception to the second — the MCP launcher exits non-zero with a reason when it finds no credential, because a silent no-op there produces a server that looks connected and serves nothing.

./scripts/check.sh

Validates every manifest, shell syntax, executable bits, plugin source paths, hook script references, that the two host manifests have not drifted, and that capture stays off by default. CI runs the same script plus shellcheck.

RepositorySeKondBrainAILabs/kemory-plugin
ChangelogCHANGELOG.md
Server, MCP tools and CLISeKondBrainAILabs/kemory-community

This repository holds client-side integrations only. Server behaviour, MCP tool definitions and the CLI live in the community repository — and the Community Edition guide covers running the whole stack yourself.

Support

Dashboardkemory.sekondbrain.ai
Supportsupport@sekondbrain.ai
Privacy and data questionsprivacy@sekondbrain.ai
Vulnerabilitiessecurity@sekondbrain.ai — reported privately, acknowledged within 3 business days

The output of /kemory:status is the most useful thing to include in a support request: it says which step broke without exposing your memories or your credentials.