OpenCode Memory
Automatic long-term memory for OpenCode: one plugin line in your config auto-installs opencode-memorysync, which injects recalled context into the system prompt per session, captures every exchange as it happens, registers the MemorySync MCP servers and three slash commands — and is incapable of breaking a session by contract.
What the plugin provides
| Layer | What it does |
|---|---|
| Recall (system transform) | OpenCode’s chat.system.transform hook injects your profile and this project’s context into the system prompt — recalled once per session, replayed identically on every LLM call from a bounded per-session cache. |
| Capture (message hooks) | chat.message persists your message, text.complete persists the reply — fire-and-forget with content-hash seeds, so retries and repeated events converge on one stored row. |
| Config registration | The config hook registers the MemorySync MCP server (API key or OAuth) plus the zero-auth docs server, and three slash commands — never overwriting anything you configured yourself. |
| Compaction | When OpenCode compacts a session, memory context is re-supplied so continuity survives the squeeze. |
| Mem0 | Supermemory | Zep | MemorySync | |
|---|---|---|---|---|
| OpenCode plugin exists | ✓ | ✓ | ✗ nothing (404) | ✓ |
| Recall guaranteed per session | ✓ injected | △ model decides — can silently skip | ✗ | ✓ injected, cached per session |
| Auth for individuals | ✓ API key | △ OAuth-first | ✗ | ✓ API key or OAuth |
| Respects your existing config | ❌ undocumented | ❌ undocumented | — | ✓ non-destructive, frozen-config safe, tested |
| Hook failure can break a session | ❌ undocumented | ❌ undocumented | — | ✓ impossible: every hook swallows every failure, tested |
Install
# 0. Get an API key at https://app.memorysync.io, then:# macOS/Linux: export MEMORYSYNC_API_KEY=ms_...# Windows: setx MEMORYSYNC_API_KEY ms_...# A. Full plugin — add one line to ~/.config/opencode/opencode.json# (or .opencode.json in a project); OpenCode installs it on next start:# { "plugin": ["opencode-memorysync"] }# B. MCP only, one command:npx memorysync-mcp-install --client opencode# C. MCP only, by hand in opencode.json:# { "mcp": { "memorysync": { "type": "remote",# "url": "https://mcp.memorysync.io/mcp", "enabled": true } } }
With MEMORYSYNC_API_KEY set, the plugin authenticates the MCP server with your key and disables the OAuth prompt; without it, OpenCode’s own OAuth flow signs you in on first tool use (opencode mcp auth). Set MEMORYSYNC_DISABLE=1 to switch the plugin off without uninstalling.
What runs when
| Moment | What happens |
|---|---|
| First LLM call of a session | Recall runs once — profile plus project context — and lands in the system prompt. Every later call in that session replays the identical block from cache (no per-call latency, no drift mid-session). |
| You send a message | The text parts persist with a human@opencode::<project> seed. Slash-command template expansions are recognised and skipped. |
| The reply completes | The assistant text persists the same way. A failed persist forgets its seed so the next event can retry. |
| Session compaction | Memory context is added to what survives the compact. |
| Any failure — no key, network down, quota exhausted | Silent skip; the session continues untouched. Every hook is wrapped: a thrown hook would break OpenCode, so none can throw. |
# Same operation as the plugin performs, shown as the raw MemorySync REST call(s).## Turns store under the opencode:: transcript scope — separate from your# Claude Code, Cursor and Codex transcripts, same shared memories.curl --request POST https://api.memorysync.io/v1/memory/add_turn \--header "X-API-Key: $MEMORYSYNC_API_KEY" \--header "Content-Type: application/json" \--data '{"tenant_id":"acme","user_id":"rafay","source":"opencode","text":"human: switch the dashboard to teal","speaker":"human@opencode::github.com/acme/web-app#h<content-hash>","metadata":{"session_id":"opencode::github.com/acme/web-app","project":"github.com/acme/web-app"}}'
Identity and scope resolve like every MemorySync agent surface: MEMORYSYNC_USER_ID (default: OS username), project from the git remote — worktree-aware — with MEMORYSYNC_PROJECT override.
Slash commands
| Command | What it does |
|---|---|
/memorysync-recall <query> | Searches long-term memory and answers from what comes back. |
/memorysync-remember <fact> | Saves a durable fact through the MCP add_memory tool. |
/memorysync-status | Checks connectivity and reports what MemorySync knows in this project. |
The commands ride the same MCP tools the model can call on its own — they are shortcuts, not a separate pathway. Your own command or MCP entries with the same names are never overwritten.
Supported versions
| Surface | Requires | Verified on |
|---|---|---|
opencode-memorysync 1.0.0 | OpenCode with plugin support (@opencode-ai/plugin 1.x), Node.js 18+ | Plugin contract suite 15/15 — loaded exactly as OpenCode loads plugins, driven against documented hook shapes |
CI loads the plugin the way OpenCode does and drives every hook on every push: non-destructive registration (including frozen config objects), injection caching, capture convergence, both monthly-quota server modes, and the never-throw discipline.