MCP server
binder mcp runs binder as a stdio Model Context Protocol
server, exposing seven MCP tools to an MCP-capable agent harness (Claude
Code, Cursor, Zed): binder’s additive verbs convert, validate, review,
lint and graph, plus the read-only graph tools list_graphs and
query_graph. Each report-producing tool returns the same deterministic
binder.report/v1 payload as the corresponding binder <cmd> --json: the
handlers reuse the same internal functions and the same JSON encoder, so there is
no second serialization path and no drift from the CLI.
It is a transport. It produces no report of its own and has no --json flag
(its outputs are the structured tool payloads). It serves over stdio until the
client disconnects.
Parity, in brief: each MCP tool mirrors its CLI verb one-to-one; the exact per-parameter parity and its output-routing exceptions are in the user guide.
Wire it into a harness (Claude Code):
claude mcp add binder -- binder mcp…or add an .mcp.json entry:
{ "mcpServers": { "binder": { "command": "binder", "args": ["mcp"] } } }Tools (for the five verbs with a CLI counterpart, each parameter mirrors the
corresponding CLI flag or positional argument 1:1, graph’s format default
excepted — dot on the CLI, json here; the MCP-only list_graphs and
query_graph have no CLI flags to mirror):
| Tool | Key params | Returns |
|---|---|---|
convert |
src (req), out (req unless dry_run), dry_run, default_type, type_map, fm_ref_keys, source_keys, map_citations, map_draft, status_map, canonicalize_status, stale_after_map, verified_by, workspace_root, external_root (repeatable), group_by_type, include_backlinks, include_graph, strict |
convert report envelope (dry_run:true → the ingestion-analysis preview, writes nothing) |
validate |
bundle (req), strict |
validate report envelope |
review |
bundle (req), entrypoints (array of concept id or path — the parity param for the repeatable --entrypoint), today, strict |
review report envelope |
lint |
src (req), entrypoints (array of concept id or path — the parity param for the repeatable --entrypoint), today, strict |
lint report envelope |
graph |
bundle (req), format (dot|json|graphml|html, default json), today |
raw export bytes — format:json is the raw {nodes,edges}, not the report envelope |
list_graphs |
bundle (req), today, id_key |
list_graphs report envelope — the LPG schema descriptor (graph name, node labels = concept types, the single LINKS edge label, each with counts + property declarations). Read-only introspection derived from the same projection as graph |
query_graph |
bundle (req), op (req: lookup|neighbors|neighborhood|pattern|path), today, id_key, id, label, direction (out|in|both, default out), rel, depth (1..5, required for neighborhood), to_label, where ({prop, eq}; prop ∈ type|tier|stale), from/to/max_depth (1..5, all required for path) |
query_graph report envelope — bounded read-only traversal of the same projection. additionalProperties: false |
query_graph details worth knowing before you call it. Every response echoes
a node_key object; id_key is accepted for parity with list_graphs only
and is never honored in this version, so the echo is always
{"strategy":"path","key":"…","honored":false} and traversal identity is always
the path-derived concept id. A query that matches nothing comes back as a
result (isError:false, not_found:true); an unknown op or an
out-of-range depth/max_depth is a tool error (isError:true, plain text
rather than the envelope). Every traversal is depth-bounded by construction.
The surface is deliberately additive (produce/validate) plus read-only graph
introspection and traversal. Source-mutating verbs (enrich, emit_concept) are
not exposed — authoring over MCP is a later concern — and neither is infer,
which is proposal-only and can call out to a model. General read/search over a
knowledge store remains out of scope; list_graphs and query_graph read the
bundle binder itself produced.
Invariants are preserved end to end: findings are returned in the
payload (a tool with findings is not an MCP error), verified_by is applied
only when explicitly passed (never auto-stamped; an invalid actor is a
usage error), and payloads honor SOURCE_DATE_EPOCH/today for determinism.
The okf-convert plugin also ships a
.mcp.json that registers this server, so a
plugin-aware host wires up binder mcp on install (the binder binary must be
on PATH).
See the user guide for the full tool schemas and examples.