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": "ovecc", "args": ["mcp"] } } }

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 -- 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": "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.1.0" },
"instructions": "Deterministic, offline architecture intelligence. Call ovecc_capabilities first for the full contract (commands, metrics, rules, exit codes). Run ovecc_index once before querying a repository. Every tool accepts an optional `repo` path."
}

Tool catalog

All 27 tools. Every tool takes an optional repo; * marks required arguments.

ToolMaps toKey arguments
ovecc_capabilitiescapabilities— (call first: the full contract)
ovecc_initinitforce
ovecc_indexindexpath
ovecc_summarysummary
ovecc_reportreport
ovecc_violationsviolationsseverity, baseline
ovecc_securitysecurityseverity
ovecc_auditaudit
ovecc_healthhealth
ovecc_deadcodedeadcode
ovecc_dupesdupesmin_tokens
ovecc_fixfixapply (write; default dry-run), rule
ovecc_diagnosediagnosetarget, severity
ovecc_adviseadvisetarget*
ovecc_metricsmetricstarget
ovecc_explainexplaintarget*
ovecc_impactimpacttarget*, direction, max_depth
ovecc_queryqueryquery* (e.g. cycles, deps billing)
ovecc_contextexport contexttarget*
ovecc_export_graphexport graphhtml
ovecc_hotspotshotspotslimit
ovecc_conventionsconventions
ovecc_reviewreviewbase, head, fail_on (lead with this for PR review)
ovecc_gategatebase, head, fail_on
ovecc_diffdiffbase, head, fail_on
ovecc_driftdriftsince
ovecc_historyhistorymetric, limit

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.

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 27 tools. 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.