mcpField
O
ov-memory-doctor

ov-memory-doctor

github.com/volcengineAgent 工作流41.1k52 次安装今天更新
代码仓库

关于 ov-memory-doctor

OpenViking Memory Doctor 是面向 Claude Code 中 OpenViking memory 插件用户的排障技能。它检查安装、配置、连接和本地服务器状态,并将发现对应到修复步骤。

主要功能

  1. 01检查插件注册与钩子
  2. 02解析配置来源和覆盖项
  3. 03探测服务器连接与就绪状态
  4. 04报告近期活动与故障
  5. 05提供检查结果及修复步骤

适用场景

  1. 01排查未运行的钩子
  2. 02查找格式错误或被覆盖的设置
  3. 03调查认证与连接错误
  4. 04检查本地 OpenViking 服务器就绪状态

MCP 相关

它会检查插件的 stdio MCP 代理,并提供验证 Claude Code 的 MCP 连接和 `/mcp` 端点的步骤。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/volcengine/openviking --skill ov-memory-doctor

安装后在 Claude Code 中输入/ov-memory-doctor确认已加载。

附带文件reference.md

详细介绍

OpenViking Memory Doctor

用于排查 OpenViking 记忆插件问题的客户端工具。该插件由三个部分组成,每个部分出错时都有各自的静默失败方式:

  • 安装 — 市场注册、插件启用、九个钩子、stdio MCP 代理。这些设置出错时,钩子永远不会运行,也不会有任何日志。
  • 配置 — ~/.openviking/ovcli.conf、~/.openviking/ov.conf 和 OPENVIKING_* 环境变量,按 env → ovcli.conf → ov.conf → 默认值的顺序解析。格式错误的文件会被视为“无配置”,从而静默禁用插件;多余的环境变量则会静默覆盖文件中的配置。
  • 连接 — 在可自托管的服务端,即使密钥无效,/health 也会返回 200,因此状态栏可能显示绿色,而每个实际请求都返回 401。在 OpenViking Cloud 上,网关也会对 /health 和 /ready 进行身份验证,因此同样的探测在没有密钥时会返回 401,无法说明 url 是否正确。

当解析出的 url 是环回地址时,服务端会在本机运行,doctor 会添加一个 服务端健康状况 部分:端口上是否有进程在监听、ov.conf 中会导致服务端拒绝启动的仅插件专用密钥(顶层块名称可以是任意一种宿主,例如:claude_code、codex、cursor、trae、trae_cn、zcode、opencode、dsh、pi,以及 server.url),以及 GET /ready——服务端对各子系统(agfs、vectordb、api keys、embedding、ollama)给出的判定。远程服务只会探测 /ready。服务端的其他所有检查——配置验证、实时 embedding 探测、原生引擎、磁盘——都由 openviking-server doctor 完成,并在服务端的 Python 环境中运行。

步骤 1 — 运行 doctor

node ${CLAUDE_PLUGIN_ROOT}/scripts/ov-memory-doctor.mjs

选项:--json(机器可读)、--offline(跳过网络探测)、--timeout <ms>(每项探测的超时时间,默认 5000)、--no-color。

报告包含六个部分——环境、插件安装、配置、连接、服务端健康状况、近期活动——以及列出每项 ✗/⚠ 并附有修复方法的摘要。 采取行动前,请阅读完整报告:同一个根本原因通常会出现在多个部分中(例如密钥错误会导致“api key rejected” + “system/status → 401” + turns_failed > 0)。

如果报告显示“此脚本并非从已注册的安装路径运行”,请从报告打印的路径重新运行——Claude Code 会从该副本执行钩子。

API 密钥不会完整显示。三段式密钥会显示为 account=<a> user=<u> secret=abcd…wxyz(前两段只是 base64url 格式的身份信息,解码后可以查看密钥所指向的账户/用户)。其他格式会显示为 abcd…wxyz (N chars, unsupported format)。向用户展示内容时,请始终遵循这一规则。

步骤 2 — 将发现的问题对应到原因

从上到下处理;先修复第一个 ✗,然后重新运行,再排查下一个。

Doctor 检查结果含义操作
plugin disabled — every hook exits immediately没有可解析的配置、OPENVIKING_MEMORY_ENABLED=0,或 ov.conf 中 claude_code.enabled: false修复其指出的原因。全新机器:创建 ~/.openviking/ovcli.conf,包含 url + api_key(chmod 600)。
ovcli.conf cannot be parsed结尾多了逗号/注释;插件将该文件视为不存在修复 JSON。这是最常见的“已安装但毫无反应”。
not registered in installed_plugins.json / claude plugin list does not show …插件从未安装,或以旧 id 安装重新运行一行安装命令(curl -fsSL https://openviking.ai/install | bash -s -- --harness claude)。
plugin is disabled in ~/.claude/settings.json已安装,但 enabledPlugins 为 false/缺失claude plugin enable openviking-memory@openviking,重启 Claude Code。
marketplace 'openviking' … missing directory / registered as a filecheckout/归档文件被移动,或是文件类型的 marketplace(marketplace update 会以 EISDIR 失败)claude plugin marketplace remove openviking,然后重新运行安装命令。
no skills/ directory in this plugin copy / registered version behind the repo版本键控的缓存已过期;当版本字符串未变化时,claude plugin update 是空操作claude plugin marketplace update openviking && claude plugin uninstall openviking-memory@openviking && claude plugin install openviking-memory@openviking。
legacy openviking hooks … settings.json / extra plugin ids / user-scope MCP openviking2.0 之前的安装残留;每个 hook 触发两次,MCP 服务注册两次从 ~/.claude/settings.json 的 .hooks 中移除 openviking 条目(先备份),claude plugin uninstall <stale id>,claude mcp remove openviking -s user。
node is not on PATH / node < 18Hook 和 .mcp.json 运行裸命令 node;GUI/IDE 启动时常常缺少 nvm/volta shim将 node 放入启动环境的 PATH,或在 ~/.claude/settings.json 的 env 块中设置 PATH。
server unreachable(refused / dns / timeout / tls)url/端口错误、服务未运行、DNS/VPN、私有 CA用 curl -sS <url>/health 对比。curl 正常但 doctor 失败 ⇒ 代理或 CA 问题(见 Step 3)。
base URL ends with /api/v1 或 /mcp、无 scheme、GET /health → 404url 形式错误(路径是直接拼接的);Cloud 需要 /openviking 前缀将 url 修正为 API 根地址。
/health is authenticated at this deployment(info)/ api key rejected on /health → 401OpenViking Cloud 在网关处对 /health 和 /ready 做鉴权,因此不带 key 的探测会返回 401,且无法反映 url 是否正常该 info 行无需修复——报告改为带 key 读取 /health。✗ 表示网关拒绝了此 key:请使用为该部署签发的 key(Cloud key 来自火山引擎控制台)。
api key rejected(/health 返回 200 但无身份)然后是 system/status → 401 Invalid API KeyKey 无效/已吊销/属于其他部署。用于不存在账号的 3 段式 key 看起来完全相同。重新签发 key;检查没有环境变量覆盖 ovcli.conf(Configuration 一节中的“← env”)。
using the ROOT api key / 403 ROOT API keys cannot access tenant-scoped data APIsapi_key 回退到了 ov.conf server.root_api_key,或用户粘贴了 root key创建用户 key(用 root key 调用 POST /api/v1/admin/accounts/<account>/users)并放入 ovcli.conf。
server is in trusted mode and needs account + user / 400 Trusted mode requests must include…服务身份来自 header在 ovcli.conf 中设置 account 和 user。
configured account/user differ from the key's identity在 api_key 模式下,服务会忽略 X-OpenViking-Account/User;数据会落在 key 的身份下移除它们,或使用该身份对应的 key。这解释了“我改了 account 但什么都没变”。
request/capture timeout exceeds the hook budgetClaude Code 在请求完成前就杀掉了 hook调低 OPENVIKING_TIMEOUT_MS / OPENVIKING_CAPTURE_TIMEOUT_MS。
POST /mcp tools/list → 404/406/502/504,但 /health 正常反向代理未转发 /mcp、重写了 Accept,或缓冲了 SSE修复代理(proxy_buffering off、转发 /mcp、传递 Authorization)。
proxy variables set + curl 正常但 doctor/hook 失败Node 的 fetch 忽略 HTTP(S)_PROXY;插件未内置代理/CA 处理在启动 Claude Code 的环境中设置 NODE_USE_ENV_PROXY=1 或 NODE_EXTRA_CA_CERTS=<ca.pem>(~/.claude/settings.json 的 env 块)。
last auto-recall … reason=offline/bypass/disabled/short_queryHook 运行了,但选择不注入offline → 连接问题;bypass → OPENVIKING_BYPASS_SESSION*;short_query → 提示词短于 minQueryLength;只有 no_results/filtered_out 才表示搜索真正执行了。注意,搜索调用返回 401 也会显示为 no_results。
turns_failed > 0 / capture payload(s) waiting写入被拒绝(401/403/404 会被丢弃而非排队),或服务当时不可用(已排队,下次 SessionStart 时重放)修复凭据/连接;OPENVIKING_WRITE_PATH_ASYNC=0 会让错误显示在 stderr 上。
MCP proxy last started against <other url>代理是长驻进程;更改 url 只有在重启后才生效重启 Claude Code 或 /mcp → reconnect。如果磁盘上的 ovcli.conf 已更改,key 轮换会在 401 后自愈。
recall is pinned to the legacy /search/recall endpoint任何提到“mode”的 4xx 会将 recall 固定 6 小时rm ~/.openviking/state/context-face.json。
no hook log … debug is on but no hook has runHook 根本没有被启动注册/启用/node 问题,不是服务问题。
ov.conf has a top-level '<harness>' block / server.url is rejected服务器的自有配置中出现了仅属于插件的键——任何以 harness 命名的顶层块(claude_code、codex、cursor、trae、trae_cn、zcode、opencode、dsh、pi)加上 server.url;服务在下次重启时会拒绝启动(Unknown config field / Extra inputs are not permitted)将它们移到 ovcli.conf(plugin.<harness>、url),并从 ov.conf 中删除。仅当此 ov.conf 从不启动服务时才可以忽略。
nothing listens on port … — the server is not running服务未运行或从未启动;.openviking.lock 是否存在并不表示服务是否在运行在终端中启动它(openviking-server;首次为 openviking-server init)并查看启动输出。重启用户自己运行的服务前先询问。
/ready: embedding → error …正在运行的服务无法调用其 embedding 提供方:recall 搜索不到任何内容,commit 提取不到任何内容修复 ov.conf 中的 embedding.*(api_key/api_base/model)并重启;openviking-server doctor 会打印提供方的回复。
/ready: vectordb → … / /ready: agfs → …存储损坏:磁盘满、同一 workspace 上运行两个服务、索引损坏查看服务日志;停止重复的服务;释放磁盘。
server is still initializing (503 /ready)首次启动会下载本地 embedding 模型,或初始化较慢等待并重新运行;如果始终无法完成,查看服务日志。
docker container is up but has no ov.conf官方镜像启动时未挂载配置(每个请求都返回 503)将 ~/.openviking 挂载到 /app/.openviking,或执行 docker exec -it openviking openviking-server init。
更多症状、准确的错误字符串和日志阶段名称:reference.md。

第 3 步 — 针对性检查(仅在报告尚无定论时)

证明钩子确实在运行。OPENVIKING_DEBUG=1 必须到达 Claude Code 自身的进程 — shell 导出做不到,而 ~/.claude/settings.json 中的 env 块可以。然后在新会话中发送一条提示词,并读取 ~/.openviking/logs/cc-hooks.log(JSONL;grep "error" 和 "hook":"mcp-proxy","stage":"start")。subagent-stop transcript_read ENOENT 这一行是无害的噪音。

手动验证密钥和身份(Bearer 区分大小写,且中间恰好有一个空格):

URL=<url>; KEY=<key>
curl -sS "$URL/health"                                  # reachability, version, auth_mode (401 on Cloud: the gateway gates /health)
curl -sS -H "Authorization: Bearer $KEY" "$URL/health"  # 200 without account_id/user_id/role ⇒ key invalid
curl -sS -w '\n%{http_code}\n' -H "Authorization: Bearer $KEY" "$URL/api/v1/system/status"  # real 401/403

直接验证 /mcp(无状态 — 无需 initialize):

curl -sS -o /dev/null -w '%{http_code}\n' -X POST "$URL/mcp" \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -H "Authorization: Bearer $KEY" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

验证 Claude Code 的 MCP 接线:claude mcp list(较慢,30–60s)必须显示 plugin:openviking-memory:openviking: node <installPath>/servers/mcp-proxy.mjs - ✔ Connected;claude mcp get 'plugin:openviking-memory:openviking' 需要完整的带引号名称。会话内的 /mcp 会重新连接代理。

证明一次捕获已落地:从 ~/.openviking/state/last-capture.json 中取出 ov_session_id,然后 GET $URL/api/v1/sessions/<id>(或 ov session get <id>);total_message_count 应 ≥ 捕获的轮次,commit_count > 0 证明提取已运行。

来自命令行的第二意见:ov health 和 ov config validate 读取同一个 ~/.openviking/ovcli.conf(它们会显示该密钥对应的账户/用户/角色)。ov config list 会揭示是否用 ov config switch 切换到了另一个 profile — 这同样会改变插件的目标。

服务端(仅当服务运行在本机时才有意义):

curl -sS "$URL/ready"                       # agfs / vectordb / api_key_manager / embedding (live probe, ≤10s) / ollama
openviking-server doctor                    # in the server's own environment: config, native engine, embedding probe, VLM key, disk
lsof -nP -iTCP:1933 -sTCP:LISTEN            # who owns the port
docker logs --tail 100 openviking           # container deployments

log.output 默认为 stdout,因此服务日志就是它运行所在的终端/tmux 窗格、nohup 文件、journalctl -u openviking 或 docker logs;设置为 "file" 时则为 <storage.workspace>/log/openviking.log。启动时退出的服务会直接在那里打印原因 — 在前台运行 openviking-server 是查看它的最快方式。它是用户的进程:在停止或重启之前先征得同意。

修复

  • 仅在用户同意的情况下编辑 ~/.openviking/ovcli.conf;展示更改内容,保留未知键,保持 0600 权限,切勿回显密钥。
  • 对于机器级覆盖,优先使用 ~/.claude/settings.json 的 env 块中的环境变量;shell rc 导出只能到达从该 shell 启动的会话,并且会在所有地方静默地覆盖该文件。
  • 更改 url、安装或更新插件后:重启 Claude Code。钩子每次调用都会重新读取配置,MCP 代理则不会。
  • 更新:GitHub 安装 → claude plugin marketplace update openviking && claude plugin update openviking-memory@openviking;在 Claude Code 2.1.224+ 上,TOS 安装(一个 url marketplace)会在后台自动更新,或用 claude plugin update openviking-memory@openviking 按需更新;更早的 TOS、归档和 dev-checkout 安装 → 重新运行安装程序。
  • 通过重新运行 doctor,然后观察下一条提示词上出现的 <openviking-context> 块来确认修复。

文档

  • 源码和 issue:https://github.com/volcengine/OpenViking — 插件代码位于 examples/ 下,共享安装程序位于 examples/memory-plugin-shared/ 下。
  • 文档索引(对 LLM 友好):https://docs.openviking.ai/llms.txt;其下的 harness 集成页面涵盖安装路径、配置键和已知限制。
  • https://api.vikingdb.cn-beijing.volces.com/openviking 是火山引擎托管的 OpenViking Service(OpenViking Cloud):路径前缀是 base url 的一部分,它只接受 Authorization: Bearer,其密钥由火山引擎控制台签发,而非由自托管管理员签发。

规则

  • 绝不打印完整 API key 或 ovcli.conf 的原始内容;doctor 的脱敏形式就是底线。
  • scripts/setup.mjs 需要 TTY,并且在旧版插件上需要已有的 ovcli.conf;在全新机器上直接写入该文件,或重新运行安装程序。
  • 绝不将 claude plugin list 通过管道传给 grep -q;先捕获输出(在 pipefail 下提前退出会被读作"未安装")。
  • /health 返回 200 只能证明可达性。认证需通过带 key 的身份字段,或通过 /api/v1/system/status 来证明。
  • ov doctor 就是 openviking-server doctor:它在服务自身的 Python 环境中验证服务自身的配置和 provider,发起一次实时 embedding 调用,并且对本插件只字不提。在遇到 provider 级故障时运行它,而不是首选运行。
  • doctor 只读取。未经询问,绝不停止、重启或 kill 用户的服务,也绝不编辑 ov.conf。
  • 旧版代理会说"检查 'ov serve' 是否在运行"——不存在这样的命令;服务是通过 openviking-server 启动的。
  • OPENVIKING_MEMORY_ENABLED=0 会禁用 hooks,但不会禁用 MCP 工具;OPENVIKING_MCP_URL 对本插件没有影响。

评论

支持 Markdown