PowerMem

June 23, 2026 · View on GitHub

This file is a setup checklist for humans and a prompt for AI coding agents. Use it for Claude Desktop, Cline, Codex, OpenCode, Roo Code, Goose, or any other MCP-compatible client. Codex and OpenCode belong here (not the VS Code extension flow); see ../../docs/integrations/codex.md and ../../docs/integrations/opencode.md.

If you are asking an AI coding agent to help, say:

Read and follow apps/mcp-client/SETUP.md to set up PowerMem for my MCP client end-to-end with no manual steps.

First clone the repo and enter it (skip if you are already in the PowerMem checkout):

git clone https://github.com/oceanbase/powermem
cd powermem

The procedure is idempotent: re-running it should reuse an existing healthy powermem-mcp server and update the target client's powermem MCP entry instead of duplicating it.


AI agents: complete Section 0 in full. Do not ask the user to manually edit JSON, reload MCP servers, or restart the client unless automation failed and you are falling back to the human steps in Sections 1-5.

Humans: use Section 0 if an agent is available; otherwise follow Sections 1-5.

Set up PowerMem for one target MCP client on this machine. Use powermem-mcp directly, prefer SSE on port 8848, and fall back to streamable HTTP or local stdio only when the target client requires it. Ask the user before editing secrets, API keys, or unrelated client config files.

0. Fully automated setup (AI agents)

Run subsections in order (0.1 -> 0.6).

Goal: PowerMem is reachable from the target MCP client as server name powermem, and tools such as add_memory and search_memories are visible after the client reloads.

0.1 — Detect target client and paths

Ask the user once which MCP client to configure if it is not obvious from the current IDE or request.

SignalLikely client
User runs Codex or ~/.codex/context.json existsCodex
User runs OpenCode or opencode.json / ~/.config/opencode/ existsOpenCode
Claude Desktop appClaude Desktop
Cline extension in VS CodeCline
OtherwiseAsk once

Common config locations:

ClientMCP configConfig key
Claude Desktop$HOME/Library/Application Support/Claude/claude_desktop_config.json (macOS)mcpServers.powermem
Codex~/.codex/context.jsonmcpServers.powermem
OpenCode~/.config/opencode/opencode.json, opencode.json, or .opencode/opencode.jsonmcp.powermem
Cline / Roo CodeMCP settings JSON managed by the extensionmcpServers.powermem
Generic clientThe client's documented MCP JSON fileUsually mcpServers.powermem

Set POWERMEM_TARGET_CLIENT to codex, opencode, or generic before running the merge helper in Section 0.4. Use only the selected target client unless the user explicitly asks to configure multiple clients.

Do not use apps/vscode-extension/SETUP.md for Codex or OpenCode — that path is for VS Code compatible IDEs (Cursor, VS Code, Windsurf, GitHub Copilot, Qoder).

0.2 - Prepare repo, environment, and package

Run from this repository:

export REPO_ROOT="$(pwd)"
export POWERMEM_MCP_URL="http://localhost:8848/mcp"
test -f "$REPO_ROOT/.env" || { echo "Missing $REPO_ROOT/.env"; exit 1; }
grep -qE '^LLM_PROVIDER=.+' "$REPO_ROOT/.env" || exit 1
grep -qE '^LLM_MODEL=.+' "$REPO_ROOT/.env" || exit 1

If .env is missing or incomplete, stop and ask the user for the provider/model/API key details needed by PowerMem. Do not invent secrets or overwrite existing keys.

Install PowerMem locally when commands are missing:

cd "$REPO_ROOT"
[ -d .venv ] || python3 -m venv .venv
source .venv/bin/activate
if command -v uv >/dev/null 2>&1; then
  uv pip install -e ".[server,cli]"
else
  python -m pip install -U pip setuptools wheel
  python -m pip install -e ".[server,cli]"
fi

0.3 - Prefer reusable powermem-mcp SSE

Probe port 8848 before starting or killing anything:

probe_powermem_mcp_sse() {
  curl -sf -m 5 -H 'Accept: text/event-stream' "$POWERMEM_MCP_URL" >/dev/null || return 1
}

if probe_powermem_mcp_sse; then
  echo "Existing powermem-mcp SSE server is healthy."
  export POWERMEM_MCP_MODE="sse"
else
  export POWERMEM_MCP_MODE=""
fi

If the probe fails, start or replace the MCP server on the same port. Keep one PowerMem MCP process on 8848; embedded storage allows one process at a time.

if [ -z "$POWERMEM_MCP_MODE" ]; then
  lsof -ti:8848 | xargs kill -9 2>/dev/null || true
  pkill -f 'powermem-mcp.*8848' 2>/dev/null || true
  sleep 2

  cd "$REPO_ROOT"
  source .venv/bin/activate
  export PMEM_MCP="$(command -v powermem-mcp || echo "$REPO_ROOT/.venv/bin/powermem-mcp")"

  if [ "$(uname -s)" = "Darwin" ] && command -v launchctl >/dev/null 2>&1; then
    launchctl remove ai.powermem.mcp 2>/dev/null || true
    launchctl submit -l ai.powermem.mcp \
      -o /tmp/powermem-mcp.launchd.log \
      -e /tmp/powermem-mcp.launchd.err \
      -- /bin/zsh -lc "cd '$REPO_ROOT' && export POWERMEM_ENV_FILE='$REPO_ROOT/.env' && exec '$PMEM_MCP' sse 8848"
  else
    POWERMEM_ENV_FILE="$REPO_ROOT/.env" nohup "$PMEM_MCP" sse 8848 \
      >> /tmp/powermem-mcp.log 2>&1 &
  fi

  for i in $(seq 1 90); do
    probe_powermem_mcp_sse && { export POWERMEM_MCP_MODE="sse"; break; }
    sleep 2
  done
fi

If SSE cannot be used by the target client, choose one fallback:

  • Use streamable HTTP when the client needs remote MCP but does not support SSE.
  • Use local stdio when the client can launch a command and does not need a long-running HTTP server.
# Optional streamable HTTP fallback:
# export POWERMEM_MCP_MODE="streamable-http"
# POWERMEM_ENV_FILE="$REPO_ROOT/.env" "$PMEM_MCP" streamable-http 8848

# Optional stdio fallback:
# export POWERMEM_MCP_MODE="stdio"

0.4 - Write the target MCP config

Use server name powermem.

For SSE (preferred):

{
  "mcpServers": {
    "powermem": {
      "url": "http://localhost:8848/mcp"
    }
  }
}

For streamable HTTP fallback, use the same URL shape after starting powermem-mcp streamable-http 8848.

For local stdio:

{
  "mcpServers": {
    "powermem": {
      "command": "powermem-mcp",
      "args": ["stdio"],
      "env": {
        "POWERMEM_ENV_FILE": "/absolute/path/to/powermem/.env"
      }
    }
  }
}

When editing JSON, preserve unrelated servers and replace only mcpServers.powermem. For OpenCode, preserve unrelated entries and replace only mcp.powermem instead:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "powermem": {
      "type": "remote",
      "url": "http://localhost:8848/mcp",
      "enabled": true
    }
  }
}

Client-aware merge helper (set MCP_PATH, POWERMEM_TARGET_CLIENT, and REPO_ROOT first):

# Codex example:
export MCP_PATH="$HOME/.codex/context.json"
export POWERMEM_TARGET_CLIENT="codex"

# OpenCode example (global config):
export MCP_PATH="$HOME/.config/opencode/opencode.json"
export POWERMEM_TARGET_CLIENT="opencode"

python3 <<'PY'
import json
import os
from pathlib import Path

mcp_path = Path(os.path.expanduser(os.environ["MCP_PATH"]))
target = os.environ.get("POWERMEM_TARGET_CLIENT", "generic")
mode = os.environ.get("POWERMEM_MCP_MODE", "sse")
repo_root = os.environ.get("REPO_ROOT", "")
mcp_url = "http://localhost:8848/mcp"

mcp_path.parent.mkdir(parents=True, exist_ok=True)
data = {}
if mcp_path.is_file():
    data = json.loads(mcp_path.read_text())

if target == "opencode":
    mcp = data.setdefault("mcp", {})
    if mode in {"sse", "streamable-http"}:
        mcp["powermem"] = {
            "type": "remote",
            "url": mcp_url,
            "enabled": True,
        }
    else:
        mcp["powermem"] = {
            "type": "local",
            "command": ["powermem-mcp", "stdio"],
            "enabled": True,
        }
        if repo_root:
            mcp["powermem"]["environment"] = {"POWERMEM_ENV_FILE": f"{repo_root}/.env"}
else:
    servers = data.setdefault("mcpServers", {})
    if mode in {"sse", "streamable-http"}:
        servers["powermem"] = {"url": mcp_url}
    else:
        entry = {
            "command": "powermem-mcp",
            "args": ["stdio"],
        }
        if repo_root:
            entry["env"] = {"POWERMEM_ENV_FILE": f"{repo_root}/.env"}
        servers["powermem"] = entry

mcp_path.write_text(json.dumps(data, indent=4) + "\n")
print(f"Updated {mcp_path} for {target} (mode={mode})")
PY

Target client: Codex

  1. Set MCP_PATH=~/.codex/context.json and POWERMEM_TARGET_CLIENT=codex.
  2. Run the merge helper above (remote URL preferred when SSE/streamable HTTP is healthy).
  3. Restart Codex so it reloads ~/.codex/context.json.
  4. Probe: add memory PowerMem Codex probe: dragonfruit-zx9, then search for dragonfruit-zx9.

Manual reference: ../../docs/integrations/codex.md.

Target client: OpenCode

  1. Pick the config file the user actually uses (~/.config/opencode/opencode.json for global setup).
  2. Set POWERMEM_TARGET_CLIENT=opencode and run the merge helper.
  3. Restart OpenCode or reload MCP servers.
  4. Probe: add memory PowerMem OpenCode probe: dragonfruit-zx9, then search for dragonfruit-zx9.

For local-only OpenCode, prefer stdio (type: local) when remote MCP is unavailable. Manual reference: ../../docs/integrations/opencode.md.

0.5 - Verify

Verify the MCP server process is listening:

lsof -i:8848 2>/dev/null

(The SSE transport keeps the connection open, so curl will hang rather than report success. A listening socket on 8848 confirmed by lsof is the correct health signal.)

Then reload or restart only the target MCP client and confirm:

  1. The powermem server is connected.
  2. Tools are visible: add_memory, search_memories, get_memory_by_id, update_memory, delete_memory, delete_all_memories, list_memories.
  3. A probe memory can be added and searched from the client.

0.6 - Agent completion message

Report only:

  1. Target client and config path updated.
  2. MCP mode: SSE, streamable HTTP, or stdio.
  3. MCP URL or stdio command.
  4. Whether a client reload/restart is still needed.

1. Prerequisites

  • PowerMem repository is available locally.
  • .env contains real LLM provider, model, and API key values.
  • The selected MCP client supports SSE, streamable HTTP, or local stdio MCP.

2. Choose Transport

Prefer SSE on port 8848:

powermem-mcp sse 8848

Use the standard URL shape in the MCP client:

{
  "mcpServers": {
    "powermem": {
      "url": "http://localhost:8848/mcp"
    }
  }
}

Use stdio when the client launches local commands:

powermem-mcp stdio

Use streamable HTTP when the client expects that transport instead of SSE:

powermem-mcp streamable-http 8848

3. Configure Client

Add or replace only the powermem entry. Most clients use mcpServers.powermem; OpenCode uses mcp.powermem.

Codex (~/.codex/context.json)

Remote MCP (preferred when powermem-mcp is on port 8848):

{
  "mcpServers": {
    "powermem": {
      "url": "http://localhost:8848/mcp"
    }
  }
}

Local stdio fallback:

{
  "mcpServers": {
    "powermem": {
      "command": "powermem-mcp",
      "args": ["stdio"],
      "env": {
        "POWERMEM_ENV_FILE": "/absolute/path/to/powermem/.env"
      }
    }
  }
}

OpenCode (opencode.json)

Remote MCP:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "powermem": {
      "type": "remote",
      "url": "http://localhost:8848/mcp",
      "enabled": true
    }
  }
}

Local stdio:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "powermem": {
      "type": "local",
      "command": ["powermem-mcp", "stdio"],
      "enabled": true,
      "environment": {
        "POWERMEM_ENV_FILE": "/absolute/path/to/powermem/.env"
      }
    }
  }
}

Other MCP clients (mcpServers)

SSE or streamable HTTP:

{
  "mcpServers": {
    "powermem": {
      "url": "http://localhost:8848/mcp"
    }
  }
}

Stdio:

{
  "mcpServers": {
    "powermem": {
      "command": "powermem-mcp",
      "args": ["stdio"]
    }
  }
}

4. Verify

Reload the MCP client, confirm the powermem server connects, and verify the memory tools are listed.

5. Troubleshooting

  • If SSE fails, run powermem-mcp sse 8848 in a terminal and inspect stderr.
  • If streamable HTTP fails, run powermem-mcp streamable-http 8848 and confirm the client URL matches the port.
  • If stdio fails, run powermem-mcp stdio in a terminal and inspect stderr.
  • If memory operations fail, check .env, provider credentials, embedding configuration, and /tmp/powermem-mcp.log or /tmp/powermem-mcp.launchd.err.
  • If port 8848 is busy, do not start a second PowerMem MCP process against the same data directory. Reuse or replace the existing process.
  • Codex: validate ~/.codex/context.json is valid JSON and contains mcpServers.powermem; restart Codex after edits.
  • OpenCode: validate the mcp.powermem block (not mcpServers); use type: remote + URL or type: local + command per OpenCode MCP docs.

Uninstall

To remove PowerMem from the target MCP client, follow UNINSTALL.md.