The ovecc MCP server
ovecc mcp runs a Model Context Protocol server over stdio, exposing every
ovecc command as a tool a coding agent can call — so your agent can ask "is this
export used?", "what's the blast radius of billing?", or "what did this change
introduce?" live, against the deterministic model, instead of guessing from file
contents.
{ "mcpServers": { "ovecc": { "command": "npx", "args": ["-y", "ovecc", "mcp"] } } }
With the binary already on PATH, "command": "ovecc" and "args": ["mcp"] start it
without the npm lookup.
How it works (read this first)
The server is not a long-running service with its own logic. It is a thin wrapper that re-invokes the ovecc binary for each tool call:
- Transport: newline-delimited JSON-RPC 2.0 over stdin/stdout. No HTTP, no port,
no daemon. The client launches
ovecc mcpas a child process and ends it by closing stdin. - Tools = the CLI: a
tools/callrunsovecc --repo <path> --format json <subcommand>and returns its stdout. Every tool maps 1:1 onto a CLI command described bycapabilities. No analysis lives only in the server. - Stateless between calls: each call is a fresh subprocess; all state lives on
disk in the repo's
.ovecc/database, written byindex. This is why you index before querying. - Deterministic: identical inputs produce byte-identical tool output.
- Tool results automatically omit the repetitive
metablock (--no-meta) to keep payloads small; agents read the definitions once fromovecc_capabilities.
Setup
1. Have the binary and an indexed repo
ovecc --repo /path/to/your-repo index
(Or let the agent do it later via the ovecc_index tool.)
2. Register with your client
Claude Code (CLI):
claude mcp add ovecc -- npx -y ovecc mcp
# or, with the binary already installed:
claude mcp add ovecc -- ovecc mcp
# or with an explicit binary path:
claude mcp add ovecc -- "C:\tools\ovecc\ovecc.exe" mcp
claude mcp list should then show ovecc, and the tools appear as ovecc_*.
Claude Desktop / generic JSON config (claude_desktop_config.json, or a project
.mcp.json):
{
"mcpServers": {
"ovecc": {
"command": "npx",
"args": ["-y", "ovecc", "mcp"]
}
}
}
Or point at a binary directly:
{
"mcpServers": {
"ovecc": {
"command": "C:\\tools\\ovecc\\ovecc.exe",
"args": ["mcp"]
}
}
}
Cursor and other clients: any client that launches a stdio MCP server works —
command = the ovecc binary path, args = ["mcp"].
Every tool accepts an optional repo argument; when omitted it defaults to the
server's working directory. Either set the client's working directory to the repo
you analyze most, or have the agent pass repo explicitly. Windows paths in JSON
need escaped backslashes (\\) — forward slashes also work.
3. What the agent sees
On initialize, the server introduces itself and instructs the agent:
{
"serverInfo": { "name": "ovecc", "version": "0.2.4" },
"instructions": "Deterministic, offline architecture intelligence over a local index. Search with ovecc_grep and read one symbol with ovecc_read instead of scanning files; trace relationships with ovecc_query (rdeps/deps) and ovecc_impact. The database persists at .ovecc/graph.db: run ovecc_index only when it is absent or files changed. Every tool accepts an optional `repo` path. Set OVECC_MCP_PROFILE=full for the complete command surface."
}
Tool profiles
tools/list advertises 11 tools by default, not the whole surface. A ~30-tool menu
dilutes the pick, and list order decides ties when two descriptions are close, so the
default agent profile is a small ordered set aimed at interactive coding agents.
OVECC_MCP_PROFILE=full ovecc mcp # advertise all 32 tools
tools/call dispatches every tool under either profile. A scripted CI caller naming
ovecc_gate keeps working even though the agent profile does not list it.
The agent profile, in the order it is advertised:
ovecc_grep, ovecc_read, ovecc_query, ovecc_impact, ovecc_context,
ovecc_advise, ovecc_architecture, ovecc_review, ovecc_summary,
ovecc_capabilities, ovecc_index.
grep and read lead because they carry the two impulses every agent session starts from
— search the code, read a file — and the first listed tool wins ties under positional
bias. Setup trails, since the initialize instructions already point at it.
LSP-vocabulary aliases (opt-in)
OVECC_MCP_LSP_ALIASES=on ovecc mcp
Adds find_references, get_call_hierarchy, and workspace_symbol as aliases over the
existing commands, on the theory that a name the model already knows from language servers
attracts calls a proprietary name misses. Additive and off by default, so the two namings
can be compared.
Tool catalog
All 32 tools. Every tool takes an optional repo; * marks required arguments.
Bold rows are in the default agent profile.
| Tool | Maps to | Key arguments |
|---|---|---|
ovecc_grep | grep | pattern*, path, limit |
ovecc_read | read | target*, limit |
ovecc_query | query | query* (e.g. cycles, deps billing), depth |
ovecc_impact | impact | target*, direction, max_depth |
ovecc_context | export context | target* |
ovecc_advise | advise | target* |
ovecc_architecture | architecture show | paths |
ovecc_review | review | base, head, fail_on (lead with this for PR review) |
ovecc_summary | summary | — |
ovecc_capabilities | capabilities | — (the full contract) |
ovecc_index | index | path |
ovecc_init | init | force |
ovecc_report | report | — |
ovecc_violations | violations | severity, baseline, changed_since |
ovecc_security | security | severity |
ovecc_audit | audit | fetch (network, opt-in) |
ovecc_health | health | — |
ovecc_deadcode | deadcode | changed_since |
ovecc_dupes | dupes | min_tokens |
ovecc_fix | fix | apply (write; default dry-run), rule |
ovecc_diagnose | diagnose | target, severity |
ovecc_metrics | metrics | target |
ovecc_components | components | target |
ovecc_coupling | coupling | limit |
ovecc_explain | explain | target* |
ovecc_export_graph | export graph | html |
ovecc_hotspots | hotspots | limit |
ovecc_conventions | conventions | — |
ovecc_gate | gate | base, head, fail_on |
ovecc_diff | diff | base, head, fail_on |
ovecc_drift | drift | since |
ovecc_history | history | metric, limit |
selfcheck is CLI-only; it grades the rules rather
than the repository, so it is not an agent tool.
Typical agent workflows
Audit a repository:
ovecc_capabilities— learn the commands, metrics, rules, exit codes.ovecc_index— build.ovecc/(once).ovecc_summary/ovecc_report— overall health.ovecc_violations,ovecc_security,ovecc_audit,ovecc_deadcode,ovecc_health— specific findings.ovecc_impact/ovecc_query— blast radius and dependency questions.
Detect what a change introduced (the regression loop):
ovecc_indexon the base — first snapshot.- Make the change;
ovecc_indexagain — second snapshot. ovecc_review— the named new defects, cycles with witness edges, added duplication. This is what the agent reports.ovecc_gatefor a bare verdict;ovecc_difffor the structural deltas behind it.
Before editing a file: ovecc_advise with the file path — every finding touching it,
each with the established fix — and ovecc_architecture with the same path, which answers
"what am I allowed to import here?" straight from
the contract, with no index required.
Instead of scanning files: ovecc_grep to find the symbol, then ovecc_read with the
file:start-end span it returns. That reads one function instead of the file around it.
Verify by hand (no agent required)
Pipe JSON-RPC frames straight into the server:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| ovecc mcp
You should get the initialize result (serverInfo ovecc) followed by a
tools/list result enumerating the 11 agent-profile tools — or all 32 with
OVECC_MCP_PROFILE=full. To exercise a real tool against an indexed repo:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ovecc_summary","arguments":{"repo":"/path/to/your-repo"}}}' \
| ovecc mcp
The result's content[0].text is the standard
JSON envelope:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [{
"type": "text",
"text": "{\n \"schema_version\": 1,\n \"tool\": { \"name\": \"ovecc\", ... },\n \"command\": \"summary\",\n \"data\": { \"files\": 11, \"modules\": 5, \"circular_dependencies\": 1, ... }"
}],
"isError": false
}
}
Error semantics
Tool failures are reported in-band, per MCP convention:
| Underlying CLI exit | MCP result |
|---|---|
0 (clean) | normal result, isError: false |
1 (a --fail-on/gate threshold crossed — a signal, not a crash) | normal result, isError: false — a failing gate still returns its verdict payload for the agent to read |
≥ 2 (usage, repo/config, DB, parser, internal) | isError: true with the stderr message |
| Unknown tool / missing required argument | isError: true (the agent can recover without a protocol failure) |
Unparseable JSON-RPC frames are ignored; unknown methods return a JSON-RPC error. Diagnostics go to stderr, never corrupting the protocol stream.
Example — querying a repo that doesn't exist:
{
"result": {
"content": [{ "type": "text", "text": "ovecc exited with code 3: ovecc: repository or configuration error: failed to resolve repository root ..." }],
"isError": true
}
}
Troubleshooting
could not resolve base snapshot 'previous'(fromovecc_gate/ovecc_diff/ovecc_drift): fewer than two snapshots exist. Runovecc_indexagain, or pass an explicitbase/since.- Empty or stale results: the repo was never indexed, or changed since the last
index. Re-run
ovecc_index. isErrorwith little detail: run the CLI directly (ovecc --repo <path> --format json <subcommand>) to see the full error; the server forwards it.- Client shows no tools: confirm the
commandpath is absolute and correct, and thatovecc mcpruns from a terminal (it blocks waiting on stdin — that's expected). - Agent skips indexing: the server's
initializeinstructions say to callovecc_capabilitiesfirst andovecc_indexonce; if your client ignoresinstructions, prompt the agent explicitly.