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.
| Plugin | What it does |
|---|---|
openviking-memory | Long-term semantic memory backed by an OpenViking server, plus OpenViking’s tools for the agent. |
ov-wiki | An 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:
- checks for
gitand for Node.js 18 or newer, whichopenviking-memoryruns 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; - finds Claude Code and Codex on
PATH, adds thepurisevmarketplace to each, and installs or updates the plugins; - offers to create
~/.openviking/ovcli.confwhen 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.sh | install.ps1 | Meaning |
|---|---|---|
--host claude | -AgentHost claude | Install into this host only (claude or codex). Repeatable. |
--plugin openviking-memory | -Plugin openviking-memory | Install this plugin only. Repeatable. |
--no-config | -NoConfig | Do not offer to create the connection file. |
-y, --yes | -Yes | Answer yes to every question. Nothing is asked, so the connection file is not created. |
--dry-run | -DryRun | Print 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>"
}
urlis the API root. It does not end in/api/v1or/mcp.api_keyis 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. accountanduserare 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:
OPENVIKING_URL,OPENVIKING_API_KEY,OPENVIKING_ACCOUNT,OPENVIKING_USERin the environment that launches the host.- 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. ~/.openviking/ovcli.conf.- Nothing configured:
http://127.0.0.1:1933without 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.
| Command | Does |
|---|---|
/wiki-init | Creates the wiki’s schema, index and log. |
/wiki-ingest | Reads a source and files it into the wiki. |
/wiki-query | Answers from the wiki, with citations. |
/wiki-lint | Checks structure, links and index coverage. |
/wiki-recover | Finishes 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
| Linux | macOS | Windows | |
|---|---|---|---|
| Installer | tested, including the Node.js download | same script; run in CI | install.ps1; run in CI |
| Plugins under Claude Code | tested | expected to work | hooks need sh, which Git for Windows provides |
| Plugins under Codex | install, hooks and MCP wiring tested | expected to work | not 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.
nodeis not onPATHfor the environment that launched the host. The hooks and the MCP proxy cannot start. Under Claude Code the/pluginErrors tab showsExecutable not found in $PATH. Install Node.js 18 or newer — the installer offers to — and restart the host. A shell profile that addsnodetoPATHdoes not help a host started from a desktop launcher.- Codex: the hooks were never approved. Run
/hooksand approve them. An update that changes the hooks needs approval again; the doctor lists the hooks that have no trust record. - Claude Code:
disableAllHooksis 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 listshows 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.
/healthanswers 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 overridesovcli.conf. The doctor marks such values← env. - Settings sit under the other host’s section.
plugin.codexdoes not apply under Claude Code, norplugin.claude_codeunder Codex. Put shared settings directly underplugin. - The server cannot reach its embedding provider. The doctor’s Server health section shows
/readyper 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.
- Give the plugin repository a
.claude-plugin/plugin.jsonwith anameand aversion, and check it withclaude plugin validate <checkout>/.claude-plugin/plugin.json. For Codex it also needs a.codex-plugin/plugin.json. - Add an entry with the same
nameto both catalogs:.claude-plugin/marketplace.json— agithubsource;.agents/plugins/marketplace.json— aurlsource for the same repository, and apolicy. Codex has nogithubsource type and lists nothing from the first file.
- A plugin that needs another plugin from this catalog lists it under
dependenciesin its.claude-plugin/plugin.json. A bare name resolves inside this marketplace, so Claude Code installs it automatically. - Add the plugin to
ALL_PLUGINSindocs/install.shand to$AllPluginsand the-PluginValidateSetindocs/install.ps1, and give it a section indocs/plugins.md. - 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.