OpenViking OpenCode 统一插件安装与使用指南:MCP 工具、长期记忆与生命周期同步
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
OpenViking 为 AI Agent 提供了自进化的上下文数据库,而 OpenCode 用户可以通过仓库中唯一持续维护的 examples/opencode-plugin 示例,把 OpenViking 的 memory、resources 与 code context 能力以 stdio MCP proxy 的方式接入 OpenCode。读完本文,你将掌握该插件的两种安装方式(发布包与源码)、完整配置项语义、底层生命周期 hooks 工作原理、全部openviking_*MCP 工具的使用建议,以及常见故障的排查路径。
插件定位与能力概览
这是当前仓库中唯一继续维护的 OpenCode 插件示例,它取代了以往"索引仓库提示注入 + 长期记忆"分开的两个示例。与旧方案的关键差异在于:该插件不再安装skills/openviking/SKILL.md,也不要求 agent 使用ov命令——模型工具面完全由与 Claude Code、Codex 记忆插件同款的 stdio MCP proxy 提供。
从 README.md 与 index.mjs 的声明可以看到,插件提供以下核心能力:
- 向 system prompt 注入已索引的
viking://resources/仓库上下文; - 暴露与 Claude Code / Codex 记忆插件一致的 OpenViking MCP 工具集;
- 将每个 OpenCode session 映射为一个 OpenViking session;
- 捕获 user/assistant 文本消息写入 OpenViking;
- 在生命周期边界(session 删除、压缩、插件退出)执行 commit,触发记忆提取;
- 自动 recall 相关记忆并以隐藏的 synthetic context 注入当前用户消息;
- 拦截 agent 误用 OpenCode 本地
read/glob/grep访问viking://URI 的行为,引导其改用 MCP 工具。
值得注意的是,插件的工具面来自 OpenViking 的 MCP endpoint,目录下有意不提供skills/openviking/SKILL.md(见 README.md)。
前置条件
安装前需要准备:
- OpenCode(插件目标宿主)
- OpenViking HTTP Server(数据面与 MCP 后端)
- Node.js 18+
- 如果服务端启用了认证,需要可用的OpenViking API Key
建议先启动 OpenViking 服务端:
openviking-server --config ~/.openviking/ov.conf然后检查服务健康状态:
curl http://localhost:1933/health插件默认连接的 endpoint 为http://127.0.0.1:1933(见 lib/config.mjs 的DEFAULT_CONFIG)。README 还额外提示:该插件要求 OpenViking server 支持viking://~home-alias,recall 通过viking://~/memories与viking://~/skills定位调用者自身上下文空间,新版 server 会拒绝无 uid 的viking://user/memories简写。
安装方式一:发布包安装
普通用户推荐通过 OpenCode 的 package plugin 机制启用。npm 发布包名为@openviking/opencode-plugin(当前示例仓库内版本为0.2.4,见 package.json),发布前可通过npm view @openviking/opencode-plugin version核对版本。
在 OpenCode 的配置(~/.config/opencode/opencode.json)中声明插件:
{ "plugin": ["@openviking/opencode-plugin"] }npm 包方式安装时,插件会通过package.json直接加载index.mjs,无需额外 wrapper。
安装方式二:源码安装
用于开发调试或 PR 测试。OpenCode 推荐插件目录为:
~/.config/opencode/plugins在仓库根目录执行以下复制命令:
mkdir -p ~/.config/opencode/plugins/openviking cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/ cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/ cp -r examples/opencode-plugin/servers ~/.config/opencode/plugins/openviking/安装后的目录结构应类似:
~/.config/opencode/plugins/ ├── openviking.js └── openviking/ ├── index.mjs ├── package.json ├── lib/ └── servers/顶层openviking.js只负责把 OpenCode 能发现的一级.js入口转发到插件目录:
export { OpenVikingPlugin, default } from "./openviking/index.mjs"这个 wrapper 仅用于上述源码安装目录结构。npm 包安装会通过package.json直接加载index.mjs。源码安装请使用.jswrapper,因为 OpenCode 的本地插件扫描器会扫描 JavaScript/TypeScript 插件文件。
如果你使用 npm 包方式安装,也可以把examples/opencode-plugin整体当作一个普通 OpenCode 插件包来使用。
配置
创建用户级配置文件:
~/.config/opencode/openviking-config.json示例配置:
{ "enabled": true, "mcp": { "enabled": true }, "timeoutMs": 30000, "repoContext": { "enabled": true, "cacheTtlMs": 60000 }, "autoRecall": { "enabled": true, "limit": 6, "scoreThreshold": 0.35, "maxContentChars": 500, "preferAbstract": true, "tokenBudget": 2000, "minQueryLength": 3 }, "commitTokenThreshold": 20000, "commitKeepRecentCount": 10, "profileTokenBudget": 10000, "resumeContextBudget": 32000 }关键配置项语义与默认值
结合 lib/config.mjs 的DEFAULT_CONFIG与normalizeConfig,各配置项的真实默认值与取值边界如下:
| 配置项 | 默认值 | 归一化范围 | 说明 |
|---|---|---|---|
endpoint | http://127.0.0.1:1933 | — | OpenViking 服务地址,尾部斜杠会被去除 |
timeoutMs | 30000 | 1000~300000 | HTTP 请求超时(毫秒) |
mcp.enabled | true | — | 是否注册附带的 MCP server |
repoContext.enabled | true | — | 是否注入已索引仓库提示 |
repoContext.cacheTtlMs | 60000 | 1000~3600000 | 仓库列表缓存 TTL |
autoRecall.enabled | true | — | 是否自动 recall 并注入上下文 |
autoRecall.limit | 10 | 1~50 | 配额缩放输入(见下文说明) |
autoRecall.scoreThreshold | 0.35 | 0~1 | 召回相似度阈值 |
autoRecall.maxContentChars | 500 | 100~5000 | 每条召回内容最大字符数 |
autoRecall.tokenBudget | 2000 | 200~50000 | recall 注入 token 预算 |
autoRecall.minQueryLength | 3 | 1~64 | 触发 recall 的最小查询长度 |
captureMode | semantic | semantic/keyword | 消息捕获模式 |
captureMaxLength | 24000 | 200~100000 | 捕获文本最大长度 |
captureAssistantTurns | true | — | 是否捕获 assistant 回合 |
commitTokenThreshold | 20000 | ≥1000 | pending token 达到该值触发 commit |
commitKeepRecentCount | 10 | ≥0 | commit 时保留的最近消息数 |
profileTokenBudget | 10000 | ≥500 | 用户画像注入 token 预算 |
resumeContextBudget | 32000 | ≥1024 | session 归档恢复上下文预算 |
runtime.dataDir | ~/.config/opencode/openviking/ | — | 运行时文件目录 |
关于autoRecall.limit有一个重要细节:它是遗留的配额缩放输入,不是最终结果上限。显式设置为 1 到 5 时,有效总配额仍为 6,因为六个 coding 分类会各保留一个检索槽位。如需精确的类别配额上限,应直接使用服务端 Context 的quotas参数。
认证与身份配置
推荐通过环境变量提供 API Key,而不是写入配置文件:
export OPENVIKING_API_KEY="your-api-key-here"API Key 会从环境变量或~/.openviking/ovcli.conf读取,并由 hooks 和 MCP proxy 作为Authorization: Bearer ...头发送。account和user是 trusted mode 身份头,会作为X-OpenViking-Account、X-OpenViking-User发送;使用 user/admin API key 的 API_KEY mode 时应留空。peerId会作为X-OpenViking-Actor-Peer用于数据面的 memory/resource 请求;捕获 session message 时仍写入 bodypeer_id,需要 peer 维度路由时请显式配置。
OPENVIKING_API_KEY、OPENVIKING_ACCOUNT、OPENVIKING_USER、OPENVIKING_PEER_ID的优先级高于openviking-config.json中的同名配置(见 lib/config.mjs 的loadConfig:环境变量在文件配置之后应用)。高级场景可以用OPENVIKING_PLUGIN_CONFIG指向其他配置文件路径,该变量优先级最高。
配置查找路径与 peer 推导
从 lib/config.mjs 的getConfigPaths可以看出,配置文件按以下顺序查找(第一个存在的生效):
OPENVIKING_PLUGIN_CONFIG指向的路径;- 项目目录下的
.opencode/openviking-config.json; ~/.config/opencode/openviking-config.json;- 插件目录下的
openviking-config.json。
默认情况下插件会从项目目录的 git 身份推导 peer:优先使用归一化的originURL,否则使用仓库根路径。例如git@github.com:volcengine/OpenViking.git会变成github.com-volcengine-openviking;路径回退则遵循"非字母数字字符替换为-"的旧规则。推导直接读取.git目录,因此不需要安装 git 二进制。插件不读取工作区的.openviking/config.json,其中的peer.id不生效。可通过配置peerId或OPENVIKING_PEER_ID覆盖推导结果,或设置workspacePeer=false/OPENVIKING_WORKSPACE_PEER=0完全不发送 peer。
仅 Hooks 模式
如果其他 MCP server 已经提供 OpenViking,可以关闭本插件附带的 MCP 注册,同时保留生命周期 hooks:
{ "mcp": { "enabled": false } }repository context、自动 recall、消息 capture 和生命周期 commit 会继续工作,也不会添加或覆盖 OpenCode 的mcp.openviking配置。从 index.mjs 的confighook 实现可以看到,当mcp.enabled为 false 时会跳过injectOpenVikingMcpConfig,仅记录 "hook-only mode"。
插件工作原理:OpenCode hooks 与 MCP 注册
理解插件的底层机制有助于排查问题。插件入口 index.mjs 导出一个OpenVikingPlugin({ client, directory })工厂函数,返回一组 OpenCode hooks:
| Hook | 作用 |
|---|---|
config | 向 OpenCode 配置注入mcp.openviking条目,指向本地 stdio MCP proxy |
event | 处理session.created等生命周期事件,并刷新仓库上下文缓存 |
tool.execute.before | viking-uri-guard:拦截本地文件系统工具对viking://URI 的访问 |
experimental.chat.system.transform | 把已索引的 OpenViking 仓库列表追加到 system prompt |
chat.message | 注入 session 上下文与自动 recall 的 synthetic context |
experimental.session.compacting | session 压缩时 flush 并 commit |
dispose | 插件退出时 flush 所有 session 并 commit |
MCP proxy:stdio 到 streamable-HTTP
OpenCode 将插件视为本地 MCP server,通过node servers/mcp-proxy.mjs启动(见 lib/mcp-config.mjs 的createOpenVikingMcpConfig,默认timeout: 15000)。servers/mcp-proxy.mjs 是一个stdio → streamable-HTTP 代理:它读取与 hooks 相同的 OpenViking 凭据来源,将 JSON-RPC 请求转发到服务端的/mcpendpoint,并保持 stdout 协议纯净(避免日志污染 MCP 通道)。
Session 映射与持久化
lib/memory-session.mjs 实现 session 生命周期管理:
- 每个 OpenCode session 通过
deriveHarnessSessionId("oc-", opencodeSessionId)派生出稳定的 OpenViking session id(子 agent 会话带__subagent-标记); - session 状态持久化到
openviking-session-state.json(v2 格式),写入采用临时文件 + rename 的原子方式,并通过 promise 队列串行化,避免并发保存竞态; - 消息捕获支持
semantic与keyword两种模式,捕获前会依据captureMaxLength、captureToolMaxChars、captureAssistantTurns等约束过滤; - 发送失败时消息进入 pending queue(lib/shared/pending-queue.mjs),服务恢复后自动重放(
replayPending),失败重试遵循retryable判定; - commit 触发时机包括:生命周期边界(session 删除/错误/压缩、插件 dispose)、
pending_tokens超过commitTokenThreshold阈值、显式工具调用。
自动 recall 与 session 注入
lib/memory-recall.mjs 在chat.message时执行:提取当前用户文本(过滤 synthetic/ignored 部分),若长度低于minQueryLength则跳过;先探测/health,再通过服务端 context face(/api/v1/search/search且mode="context")构建 recall 块,以synthetic: true的 text part 前置注入输出。recall 请求携带映射后的 OpenViking session id——正是这个映射 session 开启了服务端 query expansion 与跨轮次去重台账。
lib/session-inject.mjs 则在 session 开始时注入两类上下文:用户画像块(受profileTokenBudget约束)与最新 session 归档概览(/api/v1/sessions/{id}/context?token_budget=...,受resumeContextBudget约束)。两者都以<openviking-context>标记包裹,注入逻辑仅在首个消息执行一次。
仓库上下文注入
lib/repo-context.mjs 调用/api/v1/fs/ls?uri=viking://resources/&recursive=false&simple=false获取已索引仓库列表,按cacheTtlMs缓存,并通过experimental.chat.system.transform将格式化的仓库清单(含 abstract/overview)追加到 system prompt,指导 agent 优先使用openviking_*工具回答仓库相关问题。
验证
修改插件或 OpenViking 配置后,需要重启 OpenCode。
进入新的 OpenCode session 后,可以让 agent 浏览 OpenViking memory,或搜索一个已索引的资源。插件应暴露 OpenViking MCP server,OpenCode 中的工具名会带openviking_前缀:
openviking_search、openviking_findopenviking_read、openviking_list、openviking_tree、openviking_grep、openviking_globopenviking_remember、openviking_write、openviking_edit、openviking_add_resourceopenviking_list_watches、openviking_cancel_watch、openviking_forget、openviking_health
如果行为异常,先查看运行时文件:
ls ~/.config/opencode/openviking/ tail -n 100 ~/.config/opencode/openviking/openviking-memory.log如果使用本地 server,也确认 OpenViking 可访问:
curl http://localhost:1933/health可用 MCP 工具
插件会通过 OpenCode config 注册 OpenViking stdio MCP proxy。服务端实际返回的tools/list是最终工具清单——proxy 透传服务端真实工具列表,插件本身不维护独立的原生工具清单(见 README.md)。当前 OpenViking server 暴露:
| 工具 | 功能 |
|---|---|
openviking_search | 跨 memories/resources/skills 的深度语义检索;使用mode="context"获取面向当前任务、可直接注入的平衡上下文 |
openviking_find | 快速语义检索 |
openviking_remember | 存储重要事实或决策,供记忆提取 |
openviking_read | 读取一个或多个viking://文件 |
openviking_list | 列出viking://目录 |
openviking_tree | 展示viking://目录树 |
openviking_grep | 精确文本或正则搜索 |
openviking_glob | glob 文件匹配 |
openviking_write | 创建、覆盖或追加viking://文件 |
openviking_edit | 对viking://文件做精确字符串替换 |
openviking_add_resource | 添加 URL、本地文件、sitemap 或 feed |
openviking_forget | 在用户明确确认后删除viking://URI |
openviking_list_watches/openviking_cancel_watch | 查看或取消资源 watch |
openviking_health | 检查 OpenViking server 健康状态 |
使用建议:
- 概念性问题用
openviking_search; - 精确符号、函数名、类名、报错字符串用
openviking_grep; - 枚举文件用
openviking_glob; - 读取内容用
openviking_read; - 探索目录结构用
openviking_list; - 删除前必须先获得用户明确确认,再调用
openviking_forget; - 如果 agent 误用 OpenCode 本地
read、glob、grep工具访问viking://URI,插件会阻止这次本地文件系统调用,并提示改用 MCP 工具(这就是viking-uri-guard的职责,见 lib/viking-uri-guard.mjs)。
openviking_add_resource本地文件
openviking_add_resource支持三类输入:
- 远端
http(s)URL:直接调用/api/v1/resources; - 本地文件路径:先调用
/api/v1/resources/temp_upload,再用返回的temp_file_id添加资源; file://URL:按本地文件处理。
相对路径会按 OpenCode 当前项目目录解析。示例:
openviking_add_resource(path="https://example.com/spec.md", to="viking://resources/spec") openviking_add_resource(path="./docs/notes.md", to="viking://resources/notes.md") openviking_add_resource(path="file:///home/alice/project/notes.md", description="project notes")当前仍不支持本地目录自动打 zip 上传;传入目录时会返回明确错误。
运行时文件
插件默认会把运行时文件写入:
~/.config/opencode/openviking/可能包含:
openviking-memory.log:日志文件;openviking-session-state.json:session 映射与捕获状态(v2 格式)。
可以通过配置里的runtime.dataDir修改这个目录(见 lib/config.mjs 的resolveDataDir)。这些是本地运行时文件,不建议提交到版本库。
故障排查
| 问题 | 排查方向 |
|---|---|
| 插件没有加载 | package 安装检查~/.config/opencode/opencode.json是否包含@openviking/opencode-plugin;源码安装检查~/.config/opencode/plugins/openviking.js是否存在 |
| MCP tools 连到了错误的 server | 检查~/.openviking/ovcli.conf,或用OPENVIKING_*环境变量 /OPENVIKING_PLUGIN_CONFIG指向正确配置 |
| OpenViking 返回 401 / 403 | 检查OPENVIKING_API_KEY;trusted-mode 部署还要检查OPENVIKING_ACCOUNT和OPENVIKING_USER |
| recall 为空 | 确认 OpenViking 中已有 memories/resources,并且autoRecall.enabled为true;同时检查查询长度是否低于minQueryLength,或 server 的/health是否可达 |
本地openviking_add_resource失败 | 传入文件路径而不是目录;目前还不支持自动上传本地目录 |
| 依赖凭据字段提示 deprecated | 运行node scripts/setup.mjs迁移到ovcli.conf(插件启动时若检测到遗留凭据会通过 toast 提示,见 index.mjs) |
测试与进一步阅读
插件自带完整的 Node 测试套件(tests/ 与 servers/mcp-proxy.test.mjs),覆盖配置加载、MCP 配置注入、自动 recall、session 生命周期、日志与viking://URI 拦截等行为,可在仓库内通过npm test运行。如需深入源码,建议按以下顺序阅读:
- index.mjs:插件入口与 hooks 注册;
- lib/config.mjs:默认配置、归一化范围与环境变量;
- lib/memory-session.mjs:session 映射、捕获、pending 队列与 commit 策略;
- lib/memory-recall.mjs:自动 recall 与 synthetic context 注入;
- servers/mcp-proxy.mjs:stdio → streamable-HTTP MCP 代理。
英文原版文档见 INSTALL.md,功能综述见 README.md。
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考