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.mdto 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.
| Signal | Likely client |
|---|---|
User runs Codex or ~/.codex/context.json exists | Codex |
User runs OpenCode or opencode.json / ~/.config/opencode/ exists | OpenCode |
| Claude Desktop app | Claude Desktop |
| Cline extension in VS Code | Cline |
| Otherwise | Ask once |
Common config locations:
| Client | MCP config | Config key |
|---|---|---|
| Claude Desktop | $HOME/Library/Application Support/Claude/claude_desktop_config.json (macOS) | mcpServers.powermem |
| Codex | ~/.codex/context.json | mcpServers.powermem |
| OpenCode | ~/.config/opencode/opencode.json, opencode.json, or .opencode/opencode.json | mcp.powermem |
| Cline / Roo Code | MCP settings JSON managed by the extension | mcpServers.powermem |
| Generic client | The client's documented MCP JSON file | Usually 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
- Set
MCP_PATH=~/.codex/context.jsonandPOWERMEM_TARGET_CLIENT=codex. - Run the merge helper above (remote URL preferred when SSE/streamable HTTP is healthy).
- Restart Codex so it reloads
~/.codex/context.json. - Probe: add memory
PowerMem Codex probe: dragonfruit-zx9, then search fordragonfruit-zx9.
Manual reference: ../../docs/integrations/codex.md.
Target client: OpenCode
- Pick the config file the user actually uses (
~/.config/opencode/opencode.jsonfor global setup). - Set
POWERMEM_TARGET_CLIENT=opencodeand run the merge helper. - Restart OpenCode or reload MCP servers.
- Probe: add memory
PowerMem OpenCode probe: dragonfruit-zx9, then search fordragonfruit-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:
- The
powermemserver is connected. - Tools are visible:
add_memory,search_memories,get_memory_by_id,update_memory,delete_memory,delete_all_memories,list_memories. - A probe memory can be added and searched from the client.
0.6 - Agent completion message
Report only:
- Target client and config path updated.
- MCP mode: SSE, streamable HTTP, or stdio.
- MCP URL or stdio command.
- Whether a client reload/restart is still needed.
1. Prerequisites
- PowerMem repository is available locally.
.envcontains 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 8848in a terminal and inspect stderr. - If streamable HTTP fails, run
powermem-mcp streamable-http 8848and confirm the client URL matches the port. - If stdio fails, run
powermem-mcp stdioin a terminal and inspect stderr. - If memory operations fail, check
.env, provider credentials, embedding configuration, and/tmp/powermem-mcp.logor/tmp/powermem-mcp.launchd.err. - If port
8848is busy, do not start a second PowerMem MCP process against the same data directory. Reuse or replace the existing process. - Codex: validate
~/.codex/context.jsonis valid JSON and containsmcpServers.powermem; restart Codex after edits. - OpenCode: validate the
mcp.powermemblock (notmcpServers); usetype: remote+ URL ortype: local+ command per OpenCode MCP docs.
Uninstall
To remove PowerMem from the target MCP client, follow UNINSTALL.md.