examples/opencode-memory-plugin/README.md
OpenCode plugin example that exposes OpenViking memories as explicit tools and automatically syncs conversation sessions into OpenViking.
Chinese install guide: INSTALL-ZH.md
This example uses OpenCode's tool mechanism to expose OpenViking capabilities as explicit agent-callable tools.
In practice, that means:
memcommitThis example focuses on explicit memory access, filesystem-style browsing, and session-to-memory synchronization inside OpenCode.
memsearchmemreadmembrowsememcommitcommit tasks to avoid repeated synchronous timeout failuresThis example contains:
openviking-memory.ts: the plugin implementation used by OpenCodeopenviking-config.example.json: template config.gitignore: ignores local runtime files after you copy the example into a workspaceStart the server first if it is not already running:
openviking-server --config ~/.openviking/ov.conf
Recommended location from the OpenCode docs:
~/.config/opencode/plugins
Install with:
mkdir -p ~/.config/opencode/plugins
cp examples/opencode-memory-plugin/openviking-memory.ts ~/.config/opencode/plugins/openviking-memory.ts
cp examples/opencode-memory-plugin/openviking-config.example.json ~/.config/opencode/plugins/openviking-config.json
cp examples/opencode-memory-plugin/.gitignore ~/.config/opencode/plugins/.gitignore
Then edit ~/.config/opencode/plugins/openviking-config.json.
OpenCode auto-discovers first-level *.ts and *.js files under ~/.config/opencode/plugins, so no explicit plugin entry is required in ~/.config/opencode/opencode.json.
This plugin also works if you intentionally place it in a workspace-local plugin directory, because it stores config and runtime files next to the plugin file itself.
Recommended: provide the API key via environment variable instead of writing it into the config file:
export OPENVIKING_API_KEY="your-api-key-here"
Example config:
{
"endpoint": "http://localhost:1933",
"apiKey": "",
"enabled": true,
"timeoutMs": 30000,
"autoCommit": {
"enabled": true,
"intervalMinutes": 10
}
}
The environment variable OPENVIKING_API_KEY takes precedence over the config file.
After installation, the plugin creates these local files next to the plugin file:
openviking-config.jsonopenviking-memory.logopenviking-session-map.jsonThese are runtime artifacts and should not be committed.
memsearchUnified search across memories, resources, and skills.
Parameters:
query: search querytarget_uri?: narrow search to a URI prefix such as viking://user/memories/mode?: auto | fast | deeplimit?: max resultsscore_threshold?: optional minimum scorememreadRead content from a specific viking:// URI.
Parameters:
uri: target URIlevel?: auto | abstract | overview | readmembrowseBrowse the OpenViking filesystem layout.
Parameters:
uri: target URIview?: list | tree | statrecursive?: only for view: "list"simple?: only for view: "list"memcommitTrigger immediate memory extraction for the current session.
Parameters:
session_id?: optional explicit OpenViking session IDReturns background task progress or completion details, including task_id, per-category memories_extracted, and archived.
Search and then read:
const results = await memsearch({
query: "user coding preferences",
target_uri: "viking://user/memories/",
mode: "auto"
})
const content = await memread({
uri: results[0].uri,
level: "auto"
})
Browse first:
const tree = await membrowse({
uri: "viking://resources/",
view: "tree"
})
Force a mid-session commit:
const result = await memcommit({})
The plugin can automatically search OpenViking memories and inject relevant context into each user message before it reaches the LLM. This uses OpenCode's experimental.chat.messages.transform hook.
Note: This feature relies on an experimental OpenCode API. The hook signature or behavior may change in future OpenCode versions.
<relevant-memories> XML blockIf OpenViking is unavailable or the search times out, the message is passed through unchanged.
Add an autoRecall block to your openviking-config.json to customize recall behavior:
enabled: boolean (default: true) — enable or disable automatic memory recalllimit: number (default: 6) — maximum number of memories to inject (1–50)scoreThreshold: number (default: 0.15) — minimum relevance score for a memory to be included (0–1)maxContentChars: number (default: 500) — maximum characters per individual memory contentpreferAbstract: boolean (default: true) — prefer abstract (L0) content over full (L2) content when availabletokenBudget: number (default: 2000) — approximate total token budget for injected memories (100–10000, estimated at 4 chars per token){
"endpoint": "http://localhost:1933",
"apiKey": "",
"enabled": true,
"timeoutMs": 30000,
"autoCommit": {
"enabled": true,
"intervalMinutes": 10
},
"autoRecall": {
"enabled": true,
"limit": 6,
"scoreThreshold": 0.15,
"maxContentChars": 500,
"preferAbstract": true,
"tokenBudget": 2000
}
}
To disable recall, set "autoRecall": { "enabled": false }.
*.ts file in the OpenCode plugins directory~/.config/opencode/plugins/openviking-memory.tsopenviking-server is running and reachable at the configured endpointOPENVIKING_API_KEY or openviking-config.jsonvlm and embedding configuration