# Read-only MCP queries Brick exposes a thin Model Context Protocol server over an existing Brick JSON artifact: ```sh cargo run -- mcp brick.json ``` The server uses MCP protocol `2025-06-18` over newline-delimited JSON-RPC 2.0 on standard input/output. Standard output contains protocol messages only. The client must complete `initialize` and `notifications/initialized` before listing or calling tools. The server does not scan source, import reports, render HTML, or alter the artifact. Versioned Brick JSON remains the product boundary. ## Compatibility and result contract Every query result has `query_schema_version: 1`, the input `building_schema_version`, `query`, `root`, the sole `repository_id`, and the exact scan `scope`. The server rejects artifacts unless they satisfy the current schema-v4 contract. It also rejects duplicate node or edge IDs, node/edge ID collisions, edges with missing endpoints, and edges without an evidence record. All returned nodes and edges are complete canonical records. Edge evidence therefore retains every lane, backend, producer-local confidence value, provenance string, and attribute. Queries never promote Syntactic, Heuristic, or Imported evidence to Symbolic evidence. Request envelopes require JSON-RPC 2.0, a string method, a string or integer request ID when present, and object-valued params when present. Malformed requests receive JSON-RPC Invalid Request; malformed notifications produce no response. Tool arguments reject unknown fields. A malformed call is a JSON-RPC invalid params error. A well-formed query for a missing entity is a normal MCP tool result with `isError: true`. ## Tools ### `brick_impact` Required input: `node_id`. Optional `direction` is `dependents` (default) or `dependencies`; optional `max_depth` is a non-negative integer (default 1). Traversal uses only `calls`, `imports`, and `inherits` edges. The result returns the complete start node, impacted nodes, and traversed dependency edges. Containment, definition, finding, renderer, and layout relationships are not impact evidence. ### `brick_cycles` No input fields. Returns deterministic strongly connected components over `calls`, `imports`, and `inherits`, including self-loops. Each cycle has a stable query-local ID plus complete member nodes and internal edges. These are structural observations, not runtime or verifier proofs. ### `brick_bridges` No input fields. Returns dependency edges whose removal disconnects their endpoints in the weak undirected dependency graph. Parallel or reverse relationships prevent either individual edge from being labeled a bridge. The result declares `graph_semantics: weak-undirected-dependency` and includes each complete edge and endpoint node. ### `brick_evidence` Required input: `entity_id`. An edge lookup returns the complete edge and both endpoint nodes. A node lookup returns the complete node and all incident edges in stable-ID order. ### `brick_callers` Required input: `node_id` (a function). Optional `assume_closed_world` (default false). Returns `report` with the complete function node, `status`, `basis`, `reasons`, and complete resolved caller edges, plus the language's `metrics.resolution` coverage and a fixed `caveat`. - `resolved`: at least one resolved caller edge in any lane. - `unknown`: no resolved caller, but the model records why one may exist: `unresolved-call-sites` (same-name unresolved sites, with counts by `source.unresolved-reason` and example provenance; sites on foreign-typed receivers and macros are excluded), `referenced-by-name` (callback or address-taken candidate), `virtual`, `trait-impl`, `external-base`, `framework-attribute`, `implicit-invocation`, `outside-class-member`, `parse-incomplete`, `entry-point`, `test-code`, and, unless `assume_closed_world`, `exported` or `external-linkage`. - `unreferenced`: neither. This is a review candidate, not proof of dead code. `basis` is `compiler` only when Imported call evidence covers the function's file; otherwise `heuristic`. ### `brick_uncalled` Optional `language`, `assume_closed_world` (default false), `include_unknown` (default false), and `limit` (default 100). Returns per-language status counts, `unreferenced_total`, and `unreferenced` reports ordered by path, line, and ID; with `include_unknown`, also `unknown_total` and `unknown` reports. Use `assume_closed_world: true` only when the scan covers the complete program. ## Determinism and limits Nodes, edges, cycles, and bridges are ordered by stable identity, independent of input node/edge ordering. The bridge query is intentionally simple and can be quadratic in the number of dependency edges; it is an inspection surface, not a replacement for offline metrics. The server keeps one validated model in memory and provides no write, filesystem, source-scan, renderer, or policy mutation tool.