Skip to main content

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 (PyPI/MCP 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_memory in the conversation. See Configuration.
  • HTTP mode (default): Root .mcp.json ships with empty mcpServers. Hooks use POST /api/v1/memories (POWERMEM_BASE_URL, default http://localhost:8848).
  • MCP mode (optional): Copy config/mcp-mode.mcp.json to .mcp.json (or run apply-connection-mode.sh mcp). Claude gets PowerMem tools over HTTP …/mcp or stdio.
  • Skills: /memory-powermem:remember and /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 UserPromptSubmit hook calls POST /api/v1/memories/search with the user’s prompt and injects hits via additionalContext. Set POWERMEM_PROMPT_SEARCH=0 (or false / no / off) to disable — saves a search round-trip per turn. Works in HTTP and MCP modes.

Runtime requirements (end users)​

PieceNeeds Python?Notes
Claude CodeNo
MCP toolsNoOff by default (HTTP mode). Run apply-connection-mode.sh mcp to enable.
Hooks (event-driven writes/search → HTTP API)NoGit/marketplace installs and release plugin zips include native binaries under hooks/bin/ + run-hook.sh (macOS/Linux) or PowerShell on Windows. POWERMEM_BASE_URL defaults to http://localhost:8848.
Optional file pollerNoSame 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. Git/marketplace installs and release zips include 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 make build-claude-hook or bash apps/claude-code-plugin/scripts/build-hook-binaries.sh from the repo root. Commit refreshed hooks/bin/powermem-hook-* binaries when hook code changes so Git/marketplace installs remain runnable. make package-claude-plugin also rebuilds them automatically before zipping.

Prerequisites​

  1. PowerMem HTTP API reachable from the machine running Claude (e.g. powermem-server --port 8848). Default hooks use http://localhost:8848 — override with POWERMEM_BASE_URL for a remote server.
  2. MCP mode only: additionally expose MCP (same host, usually /mcp) or stdio powermem-mcp, and switch .mcp.json via config/mcp-mode.mcp.json.
  3. 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 send event-driven writes/search 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 Anthropic credential. For direct Anthropic API access use LLM_API_KEY; for a Claude Code-style bearer-token gateway use LLM_AUTH_TOKEN together with ANTHROPIC_LLM_BASE_URL. Storage defaults to a local SQLite database (no separate service), and the embedder to a local sentence-transformers/all-MiniLM-L6-v2 model (no API key, auto-downloaded on first use). Set DATABASE_PROVIDER=oceanbase / the OceanBase settings when you want the embedded seekdb path instead.

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
#
# or for an Anthropic-compatible gateway:
# LLM_PROVIDER=anthropic
# LLM_AUTH_TOKEN=...
# ANTHROPIC_LLM_BASE_URL=https://your-gateway.example.com
# LLM_MODEL=anthropic/claude-sonnet-4.6

Every available setting is documented under Configuration; pmem config init can also generate .env interactively.

Step 3 — Install uv​

PowerMem uses uv for Python environment creation and package installation. Install it once:

# Non-CN networks
curl -LsSf https://astral.sh/uv/install.sh | sh

# CN networks
export UV_DOWNLOAD_URL=https://mirrors.ustc.edu.cn/github-release/astral-sh/uv/LatestRelease/
curl -sL https://mirrors.ustc.edu.cn/github-release/astral-sh/uv/LatestRelease/uv-installer.sh | sh

export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
uv --version

Step 4 — Install PowerMem​

uv pip install -e '.[server,extras]' provides the powermem-server and pmem commands plus the zero-config local SQLite path and local embedder. Git/marketplace installs include native hook binaries under apps/claude-code-plugin/hooks/bin/, so Go is only needed when refreshing those binaries from hook source changes:

uv venv venv --python python3.11
source venv/bin/activate
uv pip install --python "$VIRTUAL_ENV/bin/python" -e '.[server,extras]'
# Optional after hook source changes:
# make build-claude-hook # refreshes apps/claude-code-plugin/hooks/bin/

Step 5 — 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 6 — Load the plugin into Claude Code​

claude --plugin-dir "$(pwd)/apps/claude-code-plugin"

Step 7 — 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 by ensuring uv, then starts it with the uvx-style launcher. The package spec depends on the storage backend: the default SQLite path uses powermem[server,extras] (pulls sentence-transformers for the local huggingface embedder), while the OceanBase/seekdb path uses powermem[server,seekdb]. The PyPI release must include the backend features required by the plugin, including the default local embedding dependencies. If uv is missing, init installs it automatically: non-CN networks use the official Astral installer, while CN networks use the USTC mirror at https://mirrors.ustc.edu.cn/github-release/astral-sh/uv/LatestRelease/. CN package resolution uses --default-index https://pypi.tuna.tsinghua.edu.cn/simple. 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; init passes it to uvx --from:

/plugin marketplace add https://github.com/owner/powermem.git#<branch>
/plugin install memory-powermem@powermem
/reload-plugins
# Default SQLite path
POWERMEM_INIT_PACKAGE='powermem[server,extras] @ git+https://github.com/oceanbase/powermem.git@<branch-or-sha>' \
sh "$CLAUDE_PLUGIN_ROOT/scripts/init.sh"
# OceanBase/seekdb path
POWERMEM_INIT_PACKAGE='powermem[server,seekdb] @ git+https://github.com/oceanbase/powermem.git@<branch-or-sha>' \
POWERMEM_INIT_DATABASE_PROVIDER=oceanbase \
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:

  1. Unzip → you get a folder powermem-claude-code-plugin/ containing .claude-plugin/, hooks/, skills/, .mcp.json, etc.

  2. 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
  3. Requirements on that machine: no Python; use macOS/Linux sh or follow Windows PowerShell hooks above. HTTP API must be reachable for hooks (and /mcp too 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 installedWhat 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 folderDelete the unzipped directory. Stop using --plugin-dir pointing at it.
Git clone / repo pathStop using --plugin-dir for that path; remove the clone if you no longer need it.
Marketplace / built-in plugin UIRun /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.jsonEdit ~/.claude/settings.json or .claude/settings.json in the project and remove every PowerMem hook entry that calls 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 styleUpdate steps
ZipDownload 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 / gitgit pull (or fetch the release you want), run make package-claude-plugin or bash apps/claude-code-plugin/scripts/package-plugin.sh if you need a fresh zip, then restart Claude Code.
MarketplaceRun /plugin uninstall memory-powermem@powermem, reinstall from the marketplace, then run /reload-plugins. If the backend package changed, re-run /memory-powermem:init so uvx resolves 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.

ModePlugin root .mcp.jsonClaude in-chatSilent capture (hooks → REST)
HTTP mode (default)Empty mcpServers — same as config/http-mode.mcp.jsonNo PowerMem MCP toolsYes (POWERMEM_BASE_URL, default http://localhost:8848)
MCP modeIncludes powermem — config/mcp-mode.mcp.jsonYes — 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 (uv pip install --python "$VIRTUAL_ENV/bin/python" "powermem[server,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 event-driven writes such as session transcripts, compact snapshots, tool outcomes, and lifecycle events 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-* binaries built from cmd/powermem-hook. When the plugin is enabled, Claude Code merges these hooks:

HookWhat happens
SessionStartBy default, POST …/api/v1/memories/search with bounded session metadata such as cwd, session_title, source, and agent_type; hits are injected as additional context before the first turn. Set POWERMEM_SESSION_START_SEARCH=0 to disable.
UserPromptSubmitBy 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).
SessionEndFull transcript from transcript_path (parsed JSONL: user/assistant/summary lines) → POST …/api/v1/memories.
PostCompactThe compact_summary field after /compact or auto-compact → POST …/api/v1/memories.
PreCompactBounded tail snapshot from transcript_path before compaction → POST …/api/v1/memories, with transcript fingerprint and byte offsets for auditability.
PostToolUseStructured summaries for high-signal successful tools (Write, Edit, MultiEdit, Bash, Agent, ExitPlanMode by default) → POST …/api/v1/memories. Content and metadata are scrubbed, and deterministic event IDs are included when session_id and tool_use_id are available.
PostToolUseFailureStructured summaries for failed tools → POST …/api/v1/memories with success=false, error metadata, bounded scrubbed summaries, and interrupts skipped by default.
StopOptional lightweight per-turn rollup after the main agent finishes responding → POST …/api/v1/memories. Disabled by default because it can run frequently; set POWERMEM_CAPTURE_STOP_ROLLUP=1 to enable.
SubagentStart / SubagentStopLifecycle observations keyed by the hook event name, not by transcript_path; metadata keeps bounded allowlisted link fields, not the full raw lifecycle payload.
TaskCreated / TaskCompletedTask lifecycle observations keyed by the hook event name, with link fields such as session_id, task_id, and tool_use_id when present.

Write hooks use POST {POWERMEM_BASE_URL}/api/v1/memories. Prompt and session-start search use POST {POWERMEM_BASE_URL}/api/v1/memories/search. Neither path requires MCP.

Optional environment variables (where you launch Claude Code):

VariableRequiredDescription
POWERMEM_BASE_URLNoDefaults 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_KEYIf server uses authSent as X-API-Key
POWERMEM_USER_IDNoDefaults to OS login name
POWERMEM_AGENT_IDNoOptional agent_id on memories
POWERMEM_HOOK_MAX_CHARSNoTranscript cap (default 120000)
POWERMEM_HOOK_SCRUBNoDeterministic local scrubber for hook payloads. Default 1; set 0 / false / no / off only if you want raw hook data sent to the configured server.
POWERMEM_HOOK_PRIVACY_LEVELNostandard (default) redacts high-confidence credential patterns; strict also redacts common emails and phone numbers.
POWERMEM_HOOK_SECRET_ACTIONNoredact (default) replaces matched values; block skips the memory write successfully when a high-confidence credential is found.
POWERMEM_HOOK_PATH_PRIVACYNoPath handling for content and metadata: home (default; home paths become ~/..., other absolute paths keep only the basename), basename, omit, or full.
POWERMEM_HOOK_SEARCH_SECRET_POLICYNoPrompt-search handling for high-confidence credential patterns: skip (default), redact, or off (disables only the search secret skip/redact policy; path privacy and strict PII scrubbing still apply when hook scrubbing is enabled).
POWERMEM_INFER_TRANSCRIPTNoSet 1 to enable server-side infer on large transcripts (default off)
POWERMEM_INFER_COMPACTNoSet 0 to disable infer on compact summaries (default on)
POWERMEM_PROMPT_SEARCHNoDefault: on — injects semantic search results on every user prompt via UserPromptSubmit. Set 0 / false / no / off to disable.
POWERMEM_PROMPT_SEARCH_LIMITNoMax memories returned per prompt (default 8, cap 30).
POWERMEM_PROMPT_SEARCH_MAX_CHARSNoCap on injected context string (default 24000).
POWERMEM_SESSION_START_SEARCHNoDefault: on — injects semantic search results at SessionStart using bounded session metadata. Set 0 / false / no / off to disable.
POWERMEM_SESSION_START_LIMITNoMax memories returned for SessionStart search (default 6, cap 30).
POWERMEM_SESSION_START_MAX_CHARSNoCap on SessionStart injected context string (default 16000).
POWERMEM_CAPTURE_PRECOMPACTNoSet 0 / false / no / off to disable PreCompact snapshots (default on).
POWERMEM_PRECOMPACT_MAX_CHARSNoMax transcript tail characters for PreCompact snapshots (default 120000).
POWERMEM_PRECOMPACT_TAIL_LINESNoMax transcript tail lines for PreCompact snapshots (default 200).
POWERMEM_INFER_PRECOMPACTNoSet 1 to enable server-side infer for PreCompact snapshots (default off).
POWERMEM_CAPTURE_TOOL_SUCCESSNoSet 0 / false / no / off to disable PostToolUse capture (default on).
POWERMEM_TOOL_SUCCESS_INCLUDENoComma-separated allowed tool names. Defaults to Write,Edit,MultiEdit,Bash,Agent,ExitPlanMode; * allows all tools.
POWERMEM_TOOL_SUCCESS_EXCLUDENoComma-separated denied tool names. Exclude wins over include; * disables all tool success capture.
POWERMEM_TOOL_EVENT_MAX_CHARSNoMax characters for a structured tool event memory (default 6000).
POWERMEM_INFER_TOOL_EVENTSNoSet 1 to enable server-side infer for tool event memories (default off).
POWERMEM_CAPTURE_TOOL_FAILURESNoSet 0 / false / no / off to disable PostToolUseFailure capture (default on).
POWERMEM_CAPTURE_INTERRUPTSNoSet 1 to capture interrupted tool events; interrupts are skipped by default.
POWERMEM_TOOL_FAILURE_MAX_CHARSNoMax characters for a structured tool failure memory (default 6000).
POWERMEM_INFER_TOOL_FAILURESNoSet 1 to enable server-side infer for failed tool memories (default off).
POWERMEM_CAPTURE_STOP_ROLLUPNoSet 1 to enable lightweight Stop rollup capture (default off).
POWERMEM_STOP_MAX_CHARSNoMax characters for the Stop final-message preview (default 3000).
POWERMEM_INFER_STOPNoSet 1 to enable server-side infer for Stop rollups (default off).
POWERMEM_CAPTURE_SUBAGENTSNoSet 0 / false / no / off to disable subagent lifecycle capture (default on).
POWERMEM_CAPTURE_TASKSNoSet 0 / false / no / off to disable task lifecycle capture (default on).
POWERMEM_INFER_LIFECYCLE_EVENTSNoSet 1 to enable server-side infer for all lifecycle events (default off).
POWERMEM_INFER_SUBAGENT_STOPNoSet 1 to enable infer for SubagentStop when the generic lifecycle infer flag is off.
POWERMEM_INFER_TASK_COMPLETEDNoSet 1 to enable infer for TaskCompleted when the generic lifecycle infer flag is off.

The hook scrubber runs before hook writes/searches, including session, compact, tool, stop, lifecycle, prompt-search, workspace-file, and detached-worker handoff paths. Write metadata includes a privacy object with the active level, path mode, action, and redaction counts; original matched values are not recorded there.

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:

  1. Default HTTP mode — There are no PowerMem MCP tools during chat, so Claude does not call /mcp on each message. POST /api/v1/memories/search runs on each user message via UserPromptSubmit by default; set POWERMEM_PROMPT_SEARCH=0 to turn that off.
  2. Write hooks are event-driven — POST /api/v1/memories writes can come from SessionEnd, PostCompact, PreCompact, default-on tool success/failure captures, and default-on subagent/task lifecycle events. They still do not run after every assistant reply unless you opt into Stop rollups with POWERMEM_CAPTURE_STOP_ROLLUP=1.
  3. 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 for a SessionEnd POST /api/v1/memories write (the worker runs shortly after exit).
  • Or trigger /compact (or wait for auto-compact) and look for PreCompact / PostCompact writes.
  • Run a high-signal tool such as Bash, Write, or Edit and look for PostToolUse or PostToolUseFailure writes.
  • In Claude Code, type /hooks and confirm the hook events in the table above list this plugin’s command (see hooks menu).

If you want traffic during the conversation:

  • POWERMEM_PROMPT_SEARCH is on by default, so each user message triggers POST /api/v1/memories/search and retrieved memories are injected automatically (no MCP tools needed). Set POWERMEM_PROMPT_SEARCH=0 to 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 poll for 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=0 to 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; set POWERMEM_PROMPT_SEARCH=0 if you only want explicit MCP tool use.
  • In both modes, event-driven write hooks send session, compact, tool, and lifecycle memories to REST (POWERMEM_BASE_URL, default http://localhost:8848) without the model calling tools.