Packages / MCP server / @opvs-ai/mcp
@opvs-ai/mcp
OPVS MCP server — the basics (search, read, call, install any marketplace skill), shortcuts for a card, docs, memory and mail, this machine's mail setup, and the vendor sandbox check. Every other OPVS capability is a marketplace skill reached through tool
npm install -g @opvs-ai/mcpOPVS MCP server for the on-demand model, for any MCP host (Claude Desktop,
Cursor, Antigravity, Windsurf, Claude Code). It lists the basics, a few
shortcuts, this machine's mail setup, and the vendor sandbox check. Every other OPVS capability is a
marketplace skill reached through tool_call, so one server serves every OPVS
service without crowding the model's tool list.
The basics
| Tool | Wraps | Purpose |
|---|---|---|
tool_search | registry /search | Semantic search by intent (absent/cold/warm/hot telemetry signal) |
tool_help | registry /packages/{vendor}/{name} | Methods + manifest on demand |
tool_read | registry /packages/{vendor}/{name}/skill-guide | Read any published skill's actual SKILL.md + references/ layers on-demand, nothing installed (path pulls one layer file) |
tool_call | /marketplace/runtime/{install_id}/{skill}/{method} | Universal proxy — manifest.skills[].id routing |
tool_pin | gateway skill_pin (see "tool_pin status") | Pin/unpin a skill into an OPVS agent's TOOLS.md |
tool_list_installed | /marketplace/installed | What this brand has |
tool_install | /marketplace/packages/{id}/install | Add a package with explicit consent |
tool_uninstall | DELETE /marketplace/installed/{id} | Remove a package |
whoami | /auth/me | Session probe — brand, agent, workspace, and what this door reaches only through tool_call |
Shortcuts
Each shortcut except memory_search is a tool_call with the skill and the
method filled in: the same install check, the same brand pinning, the same
answer. A brand without the skill gets the tool_call "not installed" answer.
| Tool | Same as | Purpose |
|---|---|---|
card_read | tool_call(@opvs-ai/agentboard, getTask) | Read one card in full |
card_update | tool_call(@opvs-ai/agentboard, updateTask) | Change fields on one card |
docs_search | tool_call(@opvs-ai/agentdocs, searchDocs) | Full-text search of the brand's docs |
memory_search | GET /memory/entries/search | Search typed memories; ten rows unless you ask for more |
mail_send | tool_call(@opvs-ai/opvs-protocol, send) | Send an OPVS mail message to an agent's address |
mail_inbox | tool_call(@opvs-ai/opvs-protocol, inbox) | Pull received messages (pulling does not mark them seen) |
mail_setup | opvs mail setup | Plan this machine's mail store setup; it writes and syncs only with confirm=true, and never mints or prints a key |
sandbox_chat | /marketplace/vendors/{vendor}/sandbox/chat | Vendor test mode: drive your sandbox agent through the real gateway |
Tool list and client sessions
This server never sends tools/list_changed. Its tool list is the fixed
TOOLS array the server hands back from tools/list — the same list on every
call, for the life of the process. Nothing registers a tool at runtime, so
there is no list change to announce. A client that waits for
tools/list_changed before using a tool will wait forever.
A skill installed with tool_install is usable at once. Installing adds a
skill to the brand's active installs; it does not add an MCP tool.
tool_call resolves the skill argument against those installs server-side
on every call, so the very next tool_call reaches the newly installed skill —
no reconnect, no new session, no restart.
Only a newly added MCP SERVER needs a new client session. This package's own tool list is fixed, so its own tools are stable across a session. If you add another MCP server to your client's config, that server may announce its own tools at connect time, and the client needs a fresh session to pick them up — that is client behaviour, and it is the only restart this server's contract asks for.
Reached through tool_call
Since 2.14.0 these are skill methods, not tools of this server. whoami lists
the same routes under not_on_this_door, so an agent can tell "this server has
no tool for it" from "OPVS cannot do it". A two-step job runs as two calls, the
first one's answer feeding the second.
| Capability | Skill | Methods |
|---|---|---|
| Code index: symbol search, tree, files, symbols, history, imports | @opvs-ai/code-index | searchContext before writing a symbol; callers: resolveNodes → callers with the live node ids |
| A board as one Markdown plan | @opvs-ai/agentboard | exportBoardMarkdown with detail=standard (the skill defaults to summary, the compact table) |
| Everything else on a board: boards, columns, create, claim, move, comments | @opvs-ai/agentboard | tool_help(@opvs-ai/agentboard) lists them |
| Memory context, lessons near code, writes | @opvs-ai/agentmemory | entryContext, entriesNear, entriesSimilar, anchorsLookup, createMemory |
| Pinning a memory | — | A person's act: ask a human curator to approve the pin in the AgentMemory dashboard |
| Fleet: every slot and the allowance | @opvs-ai/software-factory | listEnvironments → getEnvironmentAllowance |
| One slot and its onboarding checklist | @opvs-ai/software-factory | getEnvironment → getWorkstation with the id the first call returned (getWorkstation 404s a short env_… code) |
| Ship line status | @opvs-ai/software-factory | getProjectShipLine → getProjectShipLineConnection |
Approving a PR is the owner's act in the dashboard; no token can do it, so no tool offers it.
Upgrading from 2.13
2.14.0 drops the natives in the table above. An agent prompt or script that
names one (board_as_markdown, code_context, fleet_list, ship_status, …)
must call the skill method instead. @opvs-ai/code-index, agentmemory,
agentboard and opvs-protocol are installed on every brand by default;
tool_install adds any other (such as @opvs-ai/software-factory or
@opvs-ai/agentdocs), and tool_list_installed shows what this brand has.
npx caches the version it first ran. A host configured as
npx -y @opvs-ai/mcp can keep starting a cached 2.13.x after the publish. Pin
@opvs-ai/mcp@2.14.0 (or @latest) in the host config, or clear the npx cache
(~/.npm/_npx), and confirm with whoami or tools/list.
All tool names match ^[a-zA-Z0-9_-]+$ (the OpenAI tool-name regex; dots break Lola/Roni/planner on first call).
Install
This package is published to both public npm and OPVS's Verdaccio registry (npm.opvs.ai). A plain npm install -g @opvs-ai/mcp works from npmjs.com. Inside a repo whose .npmrc pins the @opvs-ai scope to Verdaccio, that pin wins over any --registry flag — including on reads, so verify with the scope override:
echo "@opvs-ai:registry=https://npm.opvs.ai/" >> ~/.npmrc
npm install -g @opvs-ai/mcp
Provides the opvs-mcp binary.
npm view @opvs-ai/mcp version --@opvs-ai:registry=https://registry.npmjs.org
Corrected 2026-08-18. This section used to say the npmjs publish was deferred and that the package was Verdaccio-only. That stopped being true when the 2.x line reached npmjs; the note outlived the condition it described. Read the registry, not this file.
Auth
Reads credentials from two sources, in this order (PC-249 / OD-327):
- Environment variables —
OPVS_TOKENandOPVS_API_URL. The mainstream way to inject credentials in containers, CI jobs and hosted MCP runners that have no writable home. ~/.opvs/config.json— the fileopvs auth requestwrites; shared with@opvs-ai/cli. A config file's stored token is overridden ifOPVS_TOKENis exported; the workspace slug, brand_id and brand_name come from the file and the server pins the brand from the PAT itself.
If neither source has a token, whoami returns a structured error with
code: "no_credentials_found" and guidance naming both sources — not a
"PAT may be missing or expired" message, which is the wrong fix for that
case.
# On a developer machine — file path
npm install -g @opvs-ai/cli @opvs-ai/mcp
opvs auth request -w <workspace-slug> -e <admin-email>
# (approve the email link)
opvs whoami # confirm brand pinned
# In a container / CI — env path (no config file needed)
OPVS_TOKEN=opvs_pat_xxx OPVS_API_URL=https://app.opvs.ai opvs-mcp
The brand is pinned server-side from the PAT — tool_call will refuse if the
PAT isn't brand-scoped. Env-only callers whose PAT was minted without a brand
will see a #audit.warn:brand=missing line in every whoami response.
MCP client config
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"opvs": {
"command": "opvs-mcp",
"env": { "NODE_NO_WARNINGS": "1" }
}
}
}
Restart Claude Desktop. tool_search, tool_help, tool_call, etc. appear in the tools menu.
Cursor
~/.cursor/mcp.json or via Settings → Cursor Settings → Features → MCP:
{
"mcpServers": {
"opvs": {
"command": "opvs-mcp",
"env": { "NODE_NO_WARNINGS": "1" }
}
}
}
Antigravity
Settings → MCP → Add server. NODE_NO_WARNINGS=1 is required — Antigravity rejects any stderr text before the JSON-RPC handshake (see antigravity-debrief memory for the 2026-04-26 incident).
{
"mcpServers": {
"opvs": {
"command": "opvs-mcp",
"env": { "NODE_NO_WARNINGS": "1" }
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"opvs": {
"command": "opvs-mcp",
"env": { "NODE_NO_WARNINGS": "1" }
}
}
}
Claude Code
claude mcp add opvs -- opvs-mcp
Worked example
You: Find restaurants near Aarhus and save the top 5 to a board.
Agent → tool_search({ intent: "find restaurants in Aarhus" })
← { items: [{ vendor: "@spideriq", name: "lead-gen-skills", ... }],
telemetry_signal: "warm",
_guidance: "#audit.ok ranked=1 best=@spideriq/lead-gen-skills #next:tool_call" }
Agent → tool_help({ name: "@spideriq/lead-gen-skills", section: "methods" })
← { methods: { search_maps: { ... }, submit_job: { ... } } }
Agent → tool_call({
skill: "@spideriq/lead-gen-skills",
method: "submit_job",
params: { type: "spiderMaps", payload: { query: "restaurants", location: "Aarhus" } }
})
← { job_id: "...", _guidance: "#audit.ok #next:poll getJobStatus every 5s" }
The agent never had to know all of SpiderIQ's 40+ methods upfront — discovery → describe → invoke flowed through 3 always-on tools (discover → describe → invoke).
Response contract
Every tool returns a single text-content block whose payload is JSON with:
- Flat sibling
_guidance: string— never a wrapper, never an array. - Optional flat sibling
_findings: [...]— only when the server emits one (e.g.audit_level=all). telemetry_signalin search results — closed enum:absent | cold | warm | hot.
The contract was locked with SpiderIQ on 2026-05-15 PM. See docs/planning/Marketplace/CLAUDE.md for the gateway-side semantics this MCP mirrors.
tool_pin status
tool_pin is a stub in 1.0.0. The W2.1 TOOLS.md persistence layer is live in the gateway's skills-meta plugin (PUT /api/v1/agents/{id}/tools-md via Management API + X-API-Key), but that surface isn't reachable from a PAT-authenticated MCP client. Calling tool_pin returns:
{
"action": "pin",
"skill": "@opvs-ai/agentboard",
"agent_id": "lola_001",
"changed": false,
"_guidance": "#audit.warn:not-supported-via-mcp — ..."
}
Until W2.MCP.PIN ships the PAT-gated passthrough, manage pins via the OPVS dashboard agent profile editor at /admin/agents/personas.
What was deprecated
This package was previously a 209-tool monolithic MCP exposing every public skill's full surface. That model didn't survive contact with MCP clients — every real client (Antigravity, Cursor, Claude Desktop, Windsurf) enforces a ~100-tool cap and the monolithic build was unusable in practice.
The on-demand model (the always-on set + tool_call indirection) reaches the same skills without paying the tool-budget cost.
Versions ≤ 0.7.4 are end-of-life. There is no @opvs-ai/mcp@0.x → 1.0 migration code path — replace the old install with a fresh one.
Development
cd ../core && npm install && npx tsc # REQUIRED FIRST — see below
cd ../mcp && npm install
npx vitest run # unit tests
npm run build && OPVS_TOKEN=smoke-test npm run list-tools
Two things bite from a clean checkout:
- Build
@opvs-ai/corefirst. Itsmainpoints atdist/, so without that step the suite dies at collection withFailed to resolve entry for package "@opvs-ai/core"— a missing build, not a broken suite. npm run list-toolsis a real gate, not a printout. It drives the actual stdio protocol against the built server and exits non-zero on a tool name that fails^[a-zA-Z0-9_-]+$(exit 2) or on going over the tool-count ceiling (exit 3). A unit test of theTOOLSarray cannot prove a tool is registered; this can. Both run in CI under TS Library Tests.
Counts move. Measure them at your SHA rather than citing a number from here.
Related packages
@opvs-ai/cli— terminal access (no MCP layer)@opvs-ai/skills— vendor CLI (publish/install/doctor)- Gateway plugin
skills-meta(source) — the in-platform counterpart of this package
License
MIT — see LICENSE.