Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

purisev agent plugins

Plugins for Claude Code and Codex, published as one marketplace named purisev. An installed plugin has the same id under both hosts: <plugin>@purisev.

PluginWhat it does
openviking-memoryLong-term semantic memory backed by an OpenViking server, plus OpenViking’s tools for the agent.
ov-wikiAn agent-authored Markdown wiki stored in OpenViking.

Install

Linux and macOS:

curl -fsSL https://ai-plugins.purisev.com/install.sh | sh

Windows (PowerShell):

irm https://ai-plugins.purisev.com/install.ps1 | iex

The installer:

  1. checks for git and for Node.js 18 or newer, which openviking-memory runs on. When Node.js is missing it offers the official build, checksum-verified, under your home directory — no root or administrator rights, and nothing is installed without a yes;
  2. finds Claude Code and Codex on PATH, adds the purisev marketplace to each, and installs or updates the plugins;
  3. offers to create ~/.openviking/ovcli.conf when there is none, and leaves an existing one alone.

It is safe to run again: a second run updates what is there.

Look before you run

Piping a script into a shell means trusting the address it came from. To read it first:

curl -fsSL https://ai-plugins.purisev.com/install.sh -o install.sh
less install.sh
sh install.sh --dry-run    # prints every command, changes nothing
sh install.sh
irm https://ai-plugins.purisev.com/install.ps1 -OutFile install.ps1
.\install.ps1 -DryRun
.\install.ps1

Options

install.shinstall.ps1Meaning
--host claude-AgentHost claudeInstall into this host only (claude or codex). Repeatable.
--plugin openviking-memory-Plugin openviking-memoryInstall this plugin only. Repeatable.
--no-config-NoConfigDo not offer to create the connection file.
-y, --yes-YesAnswer yes to every question. Nothing is asked, so the connection file is not created.
--dry-run-DryRunPrint what would be done and change nothing.

Options after a pipe: curl -fsSL https://ai-plugins.purisev.com/install.sh | sh -s -- --dry-run, and & ([scriptblock]::Create((irm https://ai-plugins.purisev.com/install.ps1))) -DryRun.

Install by hand

Claude Code:

/plugin marketplace add purisev/agent-plugins
/plugin install ov-wiki@purisev

ov-wiki declares openviking-memory as a dependency, so Claude Code installs both.

Codex:

codex plugin marketplace add purisev/agent-plugins
codex plugin add openviking-memory@purisev
codex plugin add ov-wiki@purisev

Then start codex, run /hooks, and approve the hooks openviking-memory brings. Codex asks once, and again whenever a plugin update changes them.

After installing

Restart the host, then connect it to your OpenViking server. To check the result, ask the agent to run the ov-memory-doctor skill; Troubleshooting explains its report.

Connect to OpenViking

Both plugins talk to an OpenViking server you run or have access to. One file configures the connection for Claude Code and Codex alike:

~/.openviking/ovcli.conf

{
  "url": "https://openviking.example.com",
  "api_key": "<a user or admin key>"
}
  • url is the API root. It does not end in /api/v1 or /mcp.
  • api_key is a user or admin key. The server’s root key is refused on the data APIs the plugins use.
  • Keep the file private: chmod 600 ~/.openviking/ovcli.conf. The installer creates it that way.
  • account and user are for servers in trusted mode, where identity comes from headers. With an API-key server, leave them out: the key already carries the identity.

Where the connection comes from

First match wins:

  1. OPENVIKING_URL, OPENVIKING_API_KEY, OPENVIKING_ACCOUNT, OPENVIKING_USER in the environment that launches the host.
  2. Under Claude Code only: the answers to the prompts shown when the plugin is enabled (server URL, API key, account, user). Every answer is optional, and the key is kept in Claude Code’s credential store. Change them later in /plugin.
  3. ~/.openviking/ovcli.conf.
  4. Nothing configured: http://127.0.0.1:1933 without a key, which suits a server on the same machine.

If you use both hosts, leave the Claude Code prompts empty and keep everything in ovcli.conf. Otherwise the two hosts read the connection from different places, and a change to one does not reach the other.

Tuning

Behaviour settings go under plugin in the same file:

{
  "url": "https://openviking.example.com",
  "api_key": "<key>",
  "plugin": {
    "recallLimit": 10,
    "codex": { "captureTimeoutMs": 25000 },
    "claude_code": { "debug": true }
  }
}

Keys directly under plugin apply to both hosts. plugin.codex applies under Codex only and plugin.claude_code under Claude Code only; each overrides the shared value. The openviking-memory README lists the keys.

A repository can carry its own settings in .openviking/config.json; see the same README.

Check it

Ask the agent to run the ov-memory-doctor skill. Its Configuration section names the source of every value (← ~/.openviking/ovcli.conf, ← env, ← Claude Code plugin option) and its Connection section proves the key against the server: /health answers 200 even with a wrong key, so reachability alone proves nothing.

Plugins

openviking-memory

Repository: purisev/openviking-memory

Gives the agent a memory that outlives the session, kept on your OpenViking server.

  • Session start — injects your profile and an index of stored preferences and entities.
  • Every prompt — recalls memories relevant to it and adds them to the turn.
  • Every turn end — appends the new messages to a server-side session.
  • Session end and before compaction — commits the session, and the server extracts durable memories from it.
  • Tools — a local MCP proxy exposes the server’s tools to the agent: search, find, read, list, tree, glob, grep, write, edit, remember, forget, add_resource, list_watches, cancel_watch, health.

Needs Node.js 18 or newer on the PATH of the environment that launches the host: the hooks and the proxy run the bare node command. At session start a small sh check tells the agent when node is missing or too old, so it can offer to install it.

Skills: openviking-memory (how and when to use the tools), ov-experience-memory, and ov-memory-doctor (diagnostics).

ov-wiki

Repository: purisev/openviking-wiki. The plugin was called openviking-wiki until 0.3.0; the repository keeps that name.

Maintains a Markdown wiki that the agent writes and keeps consistent, stored in OpenViking: source summaries, entity and concept pages, an index and a log. The wiki is private to your user by default (viking://user/<you>/resources/wiki); a shared one (viking://resources/wiki) is used only when you say so.

CommandDoes
/wiki-initCreates the wiki’s schema, index and log.
/wiki-ingestReads a source and files it into the wiki.
/wiki-queryAnswers from the wiki, with citations.
/wiki-lintChecks structure, links and index coverage.
/wiki-recoverFinishes or rolls forward an interrupted multi-page update.

It registers no tools of its own and uses the OpenViking tools of openviking-memory. Claude Code installs that plugin automatically as a declared dependency; under Codex install it yourself.

Two offline helpers, wiki_validate.py and wiki_plan.py, are optional. They need Python 3 with PyYAML; uv run resolves that from the scripts’ headers. Without them the agent runs the same checks through the tools.

Platforms

LinuxmacOSWindows
Installertested, including the Node.js downloadsame script; run in CIinstall.ps1; run in CI
Plugins under Claude Codetestedexpected to workhooks need sh, which Git for Windows provides
Plugins under Codexinstall, hooks and MCP wiring testedexpected to worknot tested

“Expected to work” means nothing platform-specific is known to be in the way, and nobody has checked.

Troubleshooting

Start with the doctor. Ask the agent to run the ov-memory-doctor skill, or run it yourself from the installed copy:

# Claude Code
node "$(claude plugin list --json | node -p 'JSON.parse(require("fs").readFileSync(0,"utf8")).find((p) => p.id.startsWith("openviking-memory@") && p.enabled).installPath')/scripts/ov-memory-doctor.mjs"

# Codex
node "$(ls -d ~/.codex/plugins/cache/purisev/openviking-memory/*/ | sort -V | tail -1)scripts/ov-memory-doctor.mjs"

It only reads. The report has sections for the environment, the plugin install, the configuration, the connection, the server’s health and recent activity, and ends with every failure and warning next to its fix. Fix the first failure and run it again: one cause often shows up in several sections.

Nothing happens at all

No recalled context, no tools, nothing logged.

  • node is not on PATH for the environment that launched the host. The hooks and the MCP proxy cannot start. Under Claude Code the /plugin Errors tab shows Executable not found in $PATH. Install Node.js 18 or newer — the installer offers to — and restart the host. A shell profile that adds node to PATH does not help a host started from a desktop launcher.
  • Codex: the hooks were never approved. Run /hooks and approve them. An update that changes the hooks needs approval again; the doctor lists the hooks that have no trust record.
  • Claude Code: disableAllHooks is set in a settings file. The doctor names the file.
  • The plugin is disabled, or Claude Code disabled it over a missing dependency. claude plugin list shows the state and the reason.

Every hook runs twice

The same plugin is enabled from two marketplaces — typically openviking-memory@purisev next to an earlier openviking-memory@openviking-memory. The doctor reports “more than one copy”. Remove the old one:

claude plugin uninstall openviking-memory@openviking-memory
claude plugin marketplace remove openviking-memory

Recall is empty, captures do not land

  • The key is wrong. /health answers 200 regardless, so look at the doctor’s “credentials accepted” line, not at reachability.
  • The root key is in use. It is refused on the data APIs. Use a user or admin key.
  • A stray OPENVIKING_* variable overrides ovcli.conf. The doctor marks such values ← env.
  • Settings sit under the other host’s section. plugin.codex does not apply under Claude Code, nor plugin.claude_code under Codex. Put shared settings directly under plugin.
  • The server cannot reach its embedding provider. The doctor’s Server health section shows /ready per subsystem; the fix is on the server.

The doctor says “no usable config” but memory works

Under Claude Code the connection may have been entered at the plugin’s prompts. Claude Code hands those answers to hooks and MCP servers, not to a shell, and keeps the key in its own credential store. The doctor reads the non-sensitive answers from Claude Code’s settings and says so; for its authenticated checks, run it with OPENVIKING_API_KEY set in that shell.

404 on profile.md, preferences, entities in the server log

Expected for a new user. At session start the plugin looks for your profile and memory indexes, and the server creates those only when it first extracts something to put there. The plugin treats the 404 as “no profile yet”; the requests turn into 200 once the first memories exist.

POST /mcp with API type unknown in the server log

That is the MCP proxy. Each host session opens with three requests (initialize, its confirmation and tools/list), then one per tool call, and a DELETE on close. The proxy polls nothing. “unknown” is the server’s label for a path outside /api/v1.

Logs

With OPENVIKING_DEBUG=1 in the host’s environment, or "debug": true in the plugin settings, hooks and the proxy write JSON lines to ~/.openviking/logs/cc-hooks.log (Claude Code) or ~/.openviking/logs/codex-hooks.log (Codex). An unchanged log after a full turn means the hooks were never started: look at node, approval and enablement, not at the server.

Adding a plugin

Each plugin lives in its own repository, which holds its code, reference documentation and issues. purisev/agent-plugins holds the two catalogs, the installer and this site.

  1. Give the plugin repository a .claude-plugin/plugin.json with a name and a version, and check it with claude plugin validate <checkout>/.claude-plugin/plugin.json. For Codex it also needs a .codex-plugin/plugin.json.
  2. Add an entry with the same name to both catalogs:
    • .claude-plugin/marketplace.json — a github source;
    • .agents/plugins/marketplace.json — a url source for the same repository, and a policy. Codex has no github source type and lists nothing from the first file.
  3. A plugin that needs another plugin from this catalog lists it under dependencies in its .claude-plugin/plugin.json. A bare name resolves inside this marketplace, so Claude Code installs it automatically.
  4. Add the plugin to ALL_PLUGINS in docs/install.sh and to $AllPlugins and the -Plugin ValidateSet in docs/install.ps1, and give it a section in docs/plugins.md.
  5. Run the checks and open a pull request.

Do not give a plugin repository a marketplace.json of its own. The same plugin reachable through two marketplaces can be enabled twice, and its hooks then run twice.

Claude Code tells plugin versions apart by version in plugin.json, so raise it with every release. Hooks shared by both hosts use ${CLAUDE_PLUGIN_ROOT} in their commands: Claude Code expands only that token, and Codex provides it next to its own ${PLUGIN_ROOT}.

Checks

node --test
claude plugin validate .
codex plugin marketplace add . && codex plugin list
mdbook build

node --test needs no network. It guards both catalogs and that they agree, and runs both installers against stand-ins for claude, codex, git and node, so nothing is installed. The install.ps1 cases are skipped where pwsh is missing.

The marketplace name purisev is part of every installed plugin’s id and of users’ settings. Renaming it would orphan those installs.