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:
- the agent sees concrete tools and decides when to call them
- OpenViking data is fetched on demand through tool execution instead of being pre-injected into every prompt
- the plugin also keeps an OpenViking session in sync with the OpenCode conversation and triggers background memory extraction with
memcommit
This example focuses on explicit memory access, filesystem-style browsing, and session-to-memory synchronization inside OpenCode.
- Exposes four memory tools for OpenCode agents:
memsearchmemreadmembrowsememcommit
- Automatically maps each OpenCode session to an OpenViking session
- Streams user and assistant messages into OpenViking
- Uses background
committasks to avoid repeated synchronous timeout failures - Persists local runtime state for reconnect and recovery
This 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 workspace
- OpenCode
- OpenViking HTTP Server
- A valid OpenViking API key if your server requires authentication
Start the server first if it is not already running:
openviking-server --config ~/.openviking/ov.confRecommended location from the OpenCode docs:
~/.config/opencode/pluginsInstall 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/.gitignoreThen 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.json
These are runtime artifacts and should not be committed.
Unified search across memories, resources, and skills.
Parameters:
query: search querytarget_uri?: narrow search to a URI prefix such asviking://user/memories/mode?:auto | fast | deeplimit?: max resultsscore_threshold?: optional minimum score
Read content from a specific viking:// URI.
Parameters:
uri: target URIlevel?:auto | abstract | overview | read
Browse the OpenViking filesystem layout.
Parameters:
uri: target URIview?:list | tree | statrecursive?: only forview: "list"simple?: only forview: "list"
Trigger immediate memory extraction for the current session.
Parameters:
session_id?: optional explicit OpenViking session ID
Returns 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.
- On every user message, the plugin extracts the latest user text
- Searches OpenViking using semantic search (5-second timeout)
- Ranks results using multi-factor scoring (base score + leaf boost + temporal boost + preference boost + lexical overlap)
- Deduplicates results (abstract-based for regular memories, URI-based for events/cases)
- Formats matching memories as a
<relevant-memories>XML block - Appends the block to the user message's text part
If 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 }.
- The plugin is designed to run as a first-level
*.tsfile in the OpenCode plugins directory - It intentionally keeps runtime config, logs, and session maps outside the repository example
- It uses OpenViking background commit tasks to avoid repeated timeout/retry loops during long memory extraction
- Plugin not loading: confirm the file exists at
~/.config/opencode/plugins/openviking-memory.ts - Service unavailable: confirm
openviking-serveris running and reachable at the configured endpoint - Authentication failed: check
OPENVIKING_API_KEYoropenviking-config.json - No memories extracted: check that your OpenViking server has working
vlmandembeddingconfiguration