Skip to main content

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 mcp as a child process and ends it by closing stdin.
  • Tools = the CLI: a tools/call runs ovecc --repo <path> --format json <subcommand> and returns its stdout. Every tool maps 1:1 onto a CLI command described by capabilities. 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 by index. This is why you index before querying.
  • Deterministic: identical inputs produce byte-identical tool output.
  • Tool results automatically omit the repetitive meta block (--no-meta) to keep payloads small; agents read the definitions once from ovecc_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"].

tip

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
The profile only controls discovery

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.

ToolMaps toKey arguments
ovecc_grepgreppattern*, path, limit
ovecc_readreadtarget*, limit
ovecc_queryqueryquery* (e.g. cycles, deps billing), depth
ovecc_impactimpacttarget*, direction, max_depth
ovecc_contextexport contexttarget*
ovecc_adviseadvisetarget*
ovecc_architecturearchitecture showpaths
ovecc_reviewreviewbase, head, fail_on (lead with this for PR review)
ovecc_summarysummary
ovecc_capabilitiescapabilities— (the full contract)
ovecc_indexindexpath
ovecc_initinitforce
ovecc_reportreport
ovecc_violationsviolationsseverity, baseline, changed_since
ovecc_securitysecurityseverity
ovecc_auditauditfetch (network, opt-in)
ovecc_healthhealth
ovecc_deadcodedeadcodechanged_since
ovecc_dupesdupesmin_tokens
ovecc_fixfixapply (write; default dry-run), rule
ovecc_diagnosediagnosetarget, severity
ovecc_metricsmetricstarget
ovecc_componentscomponentstarget
ovecc_couplingcouplinglimit
ovecc_explainexplaintarget*
ovecc_export_graphexport graphhtml
ovecc_hotspotshotspotslimit
ovecc_conventionsconventions
ovecc_gategatebase, head, fail_on
ovecc_diffdiffbase, head, fail_on
ovecc_driftdriftsince
ovecc_historyhistorymetric, 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:

  1. ovecc_capabilities — learn the commands, metrics, rules, exit codes.
  2. ovecc_index — build .ovecc/ (once).
  3. ovecc_summary / ovecc_report — overall health.
  4. ovecc_violations, ovecc_security, ovecc_audit, ovecc_deadcode, ovecc_health — specific findings.
  5. ovecc_impact / ovecc_query — blast radius and dependency questions.

Detect what a change introduced (the regression loop):

  1. ovecc_index on the base — first snapshot.
  2. Make the change; ovecc_index again — second snapshot.
  3. ovecc_review — the named new defects, cycles with witness edges, added duplication. This is what the agent reports.
  4. ovecc_gate for a bare verdict; ovecc_diff for 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 exitMCP 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 argumentisError: 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' (from ovecc_gate / ovecc_diff / ovecc_drift): fewer than two snapshots exist. Run ovecc_index again, or pass an explicit base / since.
  • Empty or stale results: the repo was never indexed, or changed since the last index. Re-run ovecc_index.
  • isError with 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 command path is absolute and correct, and that ovecc mcp runs from a terminal (it blocks waiting on stdin — that's expected).
  • Agent skips indexing: the server's initialize instructions say to call ovecc_capabilities first and ovecc_index once; if your client ignores instructions, prompt the agent explicitly.