Claude Code
Give Claude Code persistent, self-evolving memory through the first-party plugin (memory-powermem, under apps/claude-code-plugin/).
This page is the single source of truth for the Claude Code integration — the plugin's own README.md links here.
Fastest path — let Claude Code set itself up
Open Claude Code in your terminal and paste this one line:
Read and follow apps/claude-code-plugin/SETUP.md to set up PowerMem memory for Claude Code.
Claude Code reads apps/claude-code-plugin/SETUP.md — the canonical automated-setup prompt — which detects whether you are in the PowerMem source tree (developer) or anywhere else (pip user), asks you for the few required secrets, and wires everything up end-to-end.
Prefer to wire it by hand? The full plugin reference below covers every option.
Features
- Two connection modes (aligned with the PowerMem VS Code extension). HTTP mode is the default (standard): REST-only via hooks, no PowerMem MCP tools in chat. MCP mode is optional when you want
search_memories/add_memoryin the conversation. See Configuration. - HTTP mode (default): Root
.mcp.jsonships with emptymcpServers. Hooks usePOST /api/v1/memories(POWERMEM_BASE_URL, defaulthttp://localhost:8848). - MCP mode (optional): Copy
config/mcp-mode.mcp.jsonto.mcp.json(or runapply-connection-mode.sh mcp). Claude gets PowerMem tools over HTTP…/mcpor stdio. - Skills:
/memory-powermem:rememberand/memory-powermem:recall— effective in MCP mode; in default HTTP mode they cannot drive tools. - Seamless REST capture: Hooks run in both modes. Optional file poller — see watcher/README.md.
- Auto-retrieval (no MCP required, on by default): The
UserPromptSubmithook callsPOST /api/v1/memories/searchwith the user’s prompt and injects hits viaadditionalContext. SetPOWERMEM_PROMPT_SEARCH=0(orfalse/no/off) to disable — saves a search round-trip per turn. Works in HTTP and MCP modes.
Runtime requirements (end users)
| Piece | Needs Python? | Notes |
|---|---|---|
| Claude Code | No | |
| MCP tools | No | Off by default (HTTP mode). Run apply-connection-mode.sh mcp to enable. |
| Hooks (transcript / compact → HTTP API) | No | Native binaries under hooks/bin/ + run-hook.sh (macOS/Linux) or PowerShell on Windows. POWERMEM_BASE_URL defaults to http://localhost:8848. |
| Optional file poller | No | Same binary: sh hooks/run-hook.sh poll — see watcher/README.md. |
macOS / Linux: default hooks/hooks.json runs sh …/run-hook.sh. POSIX sh is always present.
Windows (native, no Git Bash): if sh is missing, merge the commands from hooks/hooks.windows.example.json into your Claude settings.json so hooks call powershell.exe -File …/run-hook.ps1. The zip includes hooks/bin/powermem-hook-windows-amd64.exe (add windows/arm64 to the build script if you need it).
Rebuilding binaries (developers / CI): Go 1.22+, then bash scripts/build-hook-binaries.sh or make build-claude-hook from the repo root. make package-claude-plugin builds them automatically before zipping.
Prerequisites
- PowerMem HTTP API reachable from the machine running Claude (e.g.
powermem-server --port 8848). Default hooks usehttp://localhost:8848— override withPOWERMEM_BASE_URLfor a remote server. - MCP mode only: additionally expose MCP (same host, usually
/mcp) or stdiopowermem-mcp, and switch.mcp.jsonviaconfig/mcp-mode.mcp.json. - Claude Code (VS Code extension or CLI) with plugin support.
Manual Installation
Set up the integration from source — this is HTTP mode (the default): hooks push transcripts to the REST API and inject search results per turn, with no in-chat tools.
Step 1 — Download the source
git clone https://github.com/oceanbase/powermem
cd powermem
Step 2 — Configure .env
Copy the template and set your LLM API key — the only required credential. Storage defaults to the embedded seekdb (no separate database), and the embedder to a local all-MiniLM-L6-v2 model (no API key, auto-downloaded on first use).
cp .env.example .env
# then edit .env and set at least:
# LLM_PROVIDER=anthropic # or openai / qwen / ...
# LLM_API_KEY=sk-...
# LLM_MODEL=claude-3-5-sonnet-latest
Every available setting is documented under Configuration; pmem config init can also generate .env interactively.
Step 3 — Install PowerMem and build the hook binaries
pip install -e '.[server,seekdb]' provides the powermem-server and pmem commands plus the zero-config local seekdb path; make build-claude-hook compiles the native Go hook binaries (requires Go 1.22+):
pip install -e '.[server,seekdb]'
make build-claude-hook # outputs apps/claude-code-plugin/hooks/bin/
Step 4 — Start the HTTP API server
Hooks default to http://localhost:8848. Leave this running (or start it as a background service):
powermem-server --host 0.0.0.0 --port 8848
Step 5 — Load the plugin into Claude Code
claude --plugin-dir "$(pwd)/apps/claude-code-plugin"
Step 6 — Verify
End the session (or run /compact), then look for POST /api/v1/memories in the server log; run /hooks inside Claude Code to confirm the entries are registered. See Troubleshooting if nothing shows up.
Other ways to load the plugin
Option A: Load from directory (development)
claude --plugin-dir /path/to/powermem/apps/claude-code-plugin
Option B: Install from marketplace
When the PowerMem marketplace entry is available, install it with:
/plugin marketplace add oceanbase/powermem
/plugin install memory-powermem@powermem
/reload-plugins
/memory-powermem:init
The marketplace step installs the Claude Code plugin connector. The
/memory-powermem:init step prepares the PowerMem backend in a plugin-local venv
and installs powermem from PyPI by default. The PyPI release must include the
backend features required by the plugin, including the default local embedding
dependencies. For branch testing before release, install the marketplace from a
branch and run init with POWERMEM_INIT_PACKAGE pointing at the same Git branch
or commit:
/plugin marketplace add owner/powermem@<branch>
/plugin install memory-powermem@powermem
/reload-plugins
POWERMEM_INIT_PACKAGE='powermem @ git+https://github.com/oceanbase/powermem.git@<branch-or-sha>' \
sh "$CLAUDE_PLUGIN_ROOT/scripts/init.sh"
Option C: Pack and copy to another machine (offline / internal)
From the powermem repo root:
make package-claude-plugin
Or run the script directly:
bash apps/claude-code-plugin/scripts/package-plugin.sh
This writes apps/claude-code-plugin/dist/powermem-claude-code-plugin-<version>.zip. Share that zip (USB, internal artifact server, etc.).
On the other computer:
-
Unzip → you get a folder
powermem-claude-code-plugin/containing.claude-plugin/,hooks/,skills/,.mcp.json, etc. -
Point Claude Code at that folder (absolute path recommended):
# Optional: hooks default to http://localhost:8848 if POWERMEM_BASE_URL is unset
export POWERMEM_BASE_URL=https://your-team-powermem.example.com # team server only
claude --plugin-dir /path/to/powermem-claude-code-plugin -
Requirements on that machine: no Python; use macOS/Linux
shor follow Windows PowerShell hooks above. HTTP API must be reachable for hooks (and/mcptoo if you enable MCP mode).
To publish a zip with MCP enabled by default, replace root .mcp.json with config/mcp-mode.mcp.json before make package-claude-plugin, or document that users run apply-connection-mode.sh mcp.
Uninstall and update
Uninstall
How you remove the plugin depends on how you enabled it:
| How you installed | What to do |
|---|---|
claude --plugin-dir /path/to/... | Stop passing --plugin-dir (remove it from shell aliases, scripts, or IDE task). Optionally delete the plugin folder. Nothing is left in ~/.claude unless you also changed global settings (see below). |
| Zip / copied folder | Delete the unzipped directory. Stop using --plugin-dir pointing at it. |
| Git clone / repo path | Stop using --plugin-dir for that path; remove the clone if you no longer need it. |
| Marketplace / built-in plugin UI | Run /plugin uninstall memory-powermem@powermem, then /reload-plugins. To remove the marketplace entry as well, run /plugin marketplace remove powermem. |
You merged hooks/hooks.windows.example.json into settings.json | Edit ~/.claude/settings.json or .claude/settings.json in the project and remove the UserPromptSubmit / SessionEnd / PostCompact hook entries that call run-hook.ps1 (or restore a backup). Otherwise hooks keep running even after the plugin folder is deleted. |
The hook binary only writes to your PowerMem server; it does not install a system daemon. No separate “service uninstall” is required.
Update
| Install style | Update steps |
|---|---|
| Zip | Download the new .zip, replace the old folder (delete the previous powermem-claude-code-plugin tree, unzip the new one to the same or a new path), then start Claude with --plugin-dir pointing at the new folder. |
Repo / git | git pull (or fetch the release you want), run make package-claude-plugin or bash scripts/package-plugin.sh if you need a fresh zip, then restart Claude Code. |
| Marketplace | Run /plugin uninstall memory-powermem@powermem, reinstall from the marketplace, then run /reload-plugins. If the backend package changed, re-run /memory-powermem:init so the plugin-local venv installs the new PyPI release. |
After updating, restart the Claude Code session (or the whole app) so MCP config, skills, and hooks reload.
Configuration
Two PowerMem modes (HTTP default, MCP optional)
Same MCP / HTTP split as elsewhere in PowerMem. Standard shipping = HTTP mode: root .mcp.json has mcpServers: {}. Hooks always use REST in both modes.
| Mode | Plugin root .mcp.json | Claude in-chat | Silent capture (hooks → REST) |
|---|---|---|---|
| HTTP mode (default) | Empty mcpServers — same as config/http-mode.mcp.json | No PowerMem MCP tools | Yes (POWERMEM_BASE_URL, default http://localhost:8848) |
| MCP mode | Includes powermem — config/mcp-mode.mcp.json | Yes — search_memories, add_memory, … | Yes |
Switch mode (from the plugin directory):
bash scripts/apply-connection-mode.sh http # restore standard (default) HTTP-only mode
bash scripts/apply-connection-mode.sh mcp # enable in-chat PowerMem tools
Restart Claude Code after changing .mcp.json. See config/README.md.
Naming note: In MCP mode, transport: "http" means “connect to the MCP endpoint over HTTP” (https://host/mcp), not “replace MCP with REST.” HTTP mode means “no MCP entry for PowerMem”; REST is still used by hooks.
MCP mode: team or local URL
After apply-connection-mode.sh mcp, edit .mcp.json or config/mcp-mode.mcp.json before copying. Same host as your REST API, MCP path is usually /mcp:
{
"mcpServers": {
"powermem": {
"transport": "http",
"url": "https://powermem.example.com/mcp"
}
}
}
stdio MCP (local powermem-mcp process) — in MCP mode, replace the powermem block with:
{
"mcpServers": {
"powermem": {
"transport": "stdio",
"command": "powermem-mcp",
"args": ["stdio"]
}
}
}
Ensure PowerMem is installed (pip install "powermem[mcp,seekdb]") and a .env is available when using stdio.
HTTP mode: REST only (standard)
This is the default root .mcp.json. Claude has no PowerMem MCP tools; skills that reference those tools have nothing to call. Hooks still send transcripts / compact summaries to POST /api/v1/memories. To reset after trying MCP: bash scripts/apply-connection-mode.sh http.
Seamless recording (hooks + HTTP API)
The plugin ships hooks/hooks.json, hooks/run-hook.sh, and native hooks/bin/powermem-hook-* (built from cmd/powermem-hook). When the plugin is enabled, Claude Code merges these hooks:
| Hook | What happens |
|---|---|
UserPromptSubmit | By default, POST …/api/v1/memories/search with the submitted prompt; top results are injected as additional context for that turn (Claude Code hooks). Set POWERMEM_PROMPT_SEARCH=0 (or false / no / off) to skip search (hook still registered; overhead is small when disabled). |
SessionEnd | Full transcript from transcript_path (parsed JSONL: user/assistant/summary lines) → POST …/api/v1/memories. |
PostCompact | The compact_summary field after /compact or auto-compact → POST …/api/v1/memories. |
Write hooks use POST {POWERMEM_BASE_URL}/api/v1/memories. Prompt search uses POST {POWERMEM_BASE_URL}/api/v1/memories/search. Neither path requires MCP.
Optional environment variables (where you launch Claude Code):
| Variable | Required | Description |
|---|---|---|
POWERMEM_BASE_URL | No | Defaults to http://localhost:8848 (same host as default .mcp.json, without /mcp). Set for a team gateway, e.g. https://powermem.example.com. |
POWERMEM_API_KEY | If server uses auth | Sent as X-API-Key |
POWERMEM_USER_ID | No | Defaults to OS login name |
POWERMEM_AGENT_ID | No | Optional agent_id on memories |
POWERMEM_HOOK_MAX_CHARS | No | Transcript cap (default 120000) |
POWERMEM_INFER_TRANSCRIPT | No | Set 1 to enable server-side infer on large transcripts (default off) |
POWERMEM_INFER_COMPACT | No | Set 0 to disable infer on compact summaries (default on) |
POWERMEM_PROMPT_SEARCH | No | Default: on — injects semantic search results on every user prompt via UserPromptSubmit. Set 0 / false / no / off to disable. |
POWERMEM_PROMPT_SEARCH_LIMIT | No | Max memories returned per prompt (default 8, cap 30). |
POWERMEM_PROMPT_SEARCH_MAX_CHARS | No | Cap on injected context string (default 24000). |
SessionEnd timeout: Claude Code defaults to a short timeout for SessionEnd hooks. The hook returns immediately and uploads in a detached worker process, so large transcripts still upload without blocking exit. If you ever switch to a synchronous upload inside the hook, raise CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS (see Claude Code hooks – SessionEnd).
Troubleshooting: “no requests” while vibe-coding
What you see is often expected:
- Default HTTP mode — There are no PowerMem MCP tools during chat, so Claude does not call
/mcpon each message.POST /api/v1/memories(writes) still come fromSessionEnd/PostCompact, not every reply. By default,POST /api/v1/memories/searchruns on each user message viaUserPromptSubmit; setPOWERMEM_PROMPT_SEARCH=0to turn that off. - Not every hook is per-turn —
SessionEndruns when the session ends (quit,/clear,/resumeswitch, etc.).PostCompactruns after manual or auto compact, not after every reply. - Those GETs (
/system/status,/memories/stats, …) usually come from another client (e.g. PowerMem VS Code extension dashboard), not from Claude Code hooks.
How to verify hooks:
- End the Claude Code session (exit the CLI session that used
--plugin-dir), then check server logs forPOST /api/v1/memories(the worker runs shortly after exit). - Or trigger
/compact(or wait for auto-compact) and look for a compact-summary write. - In Claude Code, type
/hooksand confirmUserPromptSubmit(if present) /SessionEnd/PostCompactlist this plugin’s command (see hooks menu).
If you want traffic during the conversation:
POWERMEM_PROMPT_SEARCHis on by default, so each user message triggersPOST /api/v1/memories/searchand retrieved memories are injected automatically (no MCP tools needed). SetPOWERMEM_PROMPT_SEARCH=0to turn that off.- Or switch to MCP mode (
bash scripts/apply-connection-mode.sh mcp) so Claude can call memory tools when it chooses — traffic goes to/mcp, not necessarily the same paths as the dashboard GETs. - Or rely on VS Code extension save capture /
sh hooks/run-hook.sh pollfor file-based writes.
Optional: workspace file watcher (CLI / no VS Code)
If engineers use Claude Code without the PowerMem VS Code extension (which already auto-captures on save against powermem.backendUrl), run the native poller:
export POWERMEM_BASE_URL=https://powermem.example.com
export POWERMEM_API_KEY=... # if required
export POWERMEM_WATCH_ROOT=/path/to/repo
sh hooks/run-hook.sh poll
See watcher/README.md for environment variables.
Usage
- Default (HTTP mode): Hooks capture to REST automatically; no PowerMem tools in chat. Per-prompt semantic retrieval is on by default (see Seamless recording); set
POWERMEM_PROMPT_SEARCH=0to disable. - MCP mode: Run
apply-connection-mode.sh mcp, then PowerMem tools appear; use /memory-powermem:remember / recall with real tool backing. Per-prompt injection stays on by default; setPOWERMEM_PROMPT_SEARCH=0if you only want explicit MCP tool use. - In both modes, transcript/compact hooks write to REST (
POWERMEM_BASE_URL, defaulthttp://localhost:8848) without the model calling tools.