Adding memory to opencode

its own sessions are not the same thing as memory

opencode keeps its own sessions in a local database and can reopen one. What it cannot do is start a new session already knowing what you worked out last month — and it certainly cannot read what you did in Claude Code, Codex or Cursor on the same machine. This page is about closing both.

AGENTS.md, and what it cannot hold

opencode reads AGENTS.md from the project and from its global config directory, and that is its memory: instructions you maintain, read on every session. Useful for how this repository is built and tested; wrong for the session where you worked out why the build was failing.

What opencode already has

Sessions live in ~/.local/share/opencode/opencode.db (or under XDG_DATA_HOME), and the picker reopens them. That is history you can revisit, not memory the agent uses: nothing reads yesterday's session when you ask today's question, and the database holds opencode's sessions only.

Two ways to add recall

The plugin

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-deja"]
}

That is opencode 1.x. opencode 2.x reads the list under plugins:

{"plugins": ["opencode-deja"]}

opencode installs the package on start. It needs the deja binary, which does the indexing — the plugin is the seam, not the engine:

brew install deja-vu
# or
curl -fsSL https://raw.githubusercontent.com/vshulcz/deja-vu/main/install.sh | sh

The CLI

deja install opencode-auto

Writes the MCP server into opencode.json and a plugin file of its own into ~/.config/opencode/plugins/. Shorter if you already have the binary, and it wires every other agent on the machine in the same pass with deja install --auto.

Having both is fine. The package reads what the installer wrote — the MCP entry, the plugin file — and contributes only what is missing, so nothing is registered or recalled twice.

What arrives, and when

Six tools the model can call — recall past sessions, read one in full, see what a file's history says, ask what fixed an error, ask how a command is really run here, store a decision — and four moments where memory arrives without being asked:

  • Once per session, the project's recent history is folded into the start of opencode's first system message, with a one-time toast so you know it happened (1.x only: a 2.x server plugin has no channel to the TUI). It joins that message rather than adding a second one, because some backends — vLLM or SGLang serving Qwen — reject a request with two.
  • Per prompt, a relevance pass on what you just typed. Silent when nothing matches, which is the common case.
  • Before compaction, the working transcript is indexed, so the session survives the window collapsing — see what compaction drops.
  • After a file is read and after a command runs, one line about what this machine already knows: what the sessions that touched the file decided, or the error this command hit here before. On opencode it arrives after the action rather than before it, because the plugin API gives no seam that reaches the model first — tool.execute.before can only rewrite a tool's arguments, and a permission hook answers allow or deny with no text. So a command that was always going to fail still runs once.

An injection is capped: 1,536 bytes per prompt, about 4 KB for a tool call. What memory costs has the measured numbers against replaying or grepping instead.

The part that is not opencode-specific

The index covers every agent's transcripts on the machine, not opencode's alone — forty-one of them today, each in its own format. So a fix you found in Claude Code in March answers a question you ask in opencode in August, and the reverse. That is the whole reason to index rather than to capture: the history is already written, including the months before any of this was installed.

Turning parts off

{"plugin": [["opencode-deja", {"autoRecall": false, "tools": true}]]}

On 2.x the same options go in an object:

{"plugins": [{"package": "opencode-deja", "options": {"autoRecall": false, "tools": true}}]}

autoRecall: false keeps the tools and drops the unasked injections; tools: false does the reverse. The tools also stand down on their own when the MCP server is already wired, so you are not given the same six answers under two names.

What it does not do

It does not write memories or summarise anything, so there is nothing to hallucinate into your history. It does not reach the network: indexing and search are local, and credentials are stripped as the index is built (privacy). And it does not make opencode's own session list any better — it makes the sessions searchable, which is a different thing.

Getting started · Switching between agents · The opencode session format · The plugin source

Found this useful? Star deja-vu on GitHub.