Skip to content
becwright

Guides

MCP & JSON output

Machine-readable results for AI agents via check --json and the MCP server.

Last updated

Who is this page for? People wiring becwright into an AI tool or a script. The normal install already guards your commits on its own — this page is about the next layer: letting an AI agent (or any other program) read becwright’s results and act on them. If that’s where you’re headed, everything you need is below.

becwright exposes its results in machine-readable form two ways: a JSON output for scripts, and an MCP server for AI agents. (MCP — Model Context Protocol — is a standard plug for giving AI tools extra abilities.)

becwright check --json

Same as becwright check, but prints a JSON summary instead of colored text and is consumable without parsing. Exit code is unchanged (1 if a blocking rule failed, else 0).

{
  "rule_count": 3,
  "checked_files": 1,
  "blocked": true,
  "results": [
    {
      "id": "no-debugger-js",
      "severity": "blocking",
      "passed": false,
      "intent": "Do not leave 'debugger;' in JavaScript/TypeScript code.",
      "why_it_matters": "A forgotten 'debugger' halts execution ...",
      "output": "app.js:1\n      > function f(){ debugger; }"
    }
  ]
}

This needs no extra dependency and works from the standalone binary too.

How should an agent read this output?

The two top-level fields to branch on are blocked and results. blocked mirrors the exit code: it is true exactly when at least one blocking rule failed, so a script can gate on either signal. rule_count and checked_files are context — how many rules ran and over how many files.

Each entry in results describes one rule. passed and severity give the verdict (failures with severity: "warning" never block); intent states what the rule demands; why_it_matters explains the reasoning behind it; and output is the check’s own stdout, which points at the offending file and line. An agent working the loop reads intent and why_it_matters, fixes the code, and calls check again until blocked comes back false — see AI agents for that loop end to end.

MCP server

becwright mcp runs a Model Context Protocol server over stdio, so any MCP-capable agent (Claude, Cursor, Windsurf, …) gets becwright as structured tools.

It requires the optional mcp extra:

pipx install "becwright[mcp]"     # or: pip install "becwright[mcp]"

Tools

ToolArgumentsReturns
checkall_files (bool), path (optional repo dir)the same summary as check --json
list_checksthe built-in checks as {name, description}
list_rulespath (optional repo dir)the repo’s rules as decision records (id, severity, intent, why_it_matters, rejected_alternatives, paths, check)
preview_rulecheck, paths, exclude (optional), all_files, path{matched_files, passed, output, note} — a dry-run without writing the rule
propose_rules_from_claude_mdpath (optional repo dir){rules, unmapped_hint} — the rules becwright can derive from the repo’s CLAUDE.md
add_ruleid, check, paths, intent, why_it_matters, severity, exclude, confirm, pathwrites a rule to .bec/rules.yaml — preview unless confirm=true

check and list_checks are the read side an agent uses to work a failing commit. The remaining four are the authoring side — reading the decisions a repo already enforces, then drafting new ones safely.

list_rules is the decision memory: it returns every rule with its intent, the reason behind it and the check that enforces it, so an agent can read the decisions it must not violate before writing code — the same data check surfaces on failure, but available up front. It mirrors the CLI becwright why --json.

propose_rules_from_claude_md returns the rules becwright can derive deterministically from the prose (each with the phrase that triggered it) — the agent’s starting point. preview_rule lets the agent validate a rule before writing it: given a candidate check and paths, it runs the check against the repo and reports how many files the globs select, whether the rule would pass, and what it flags — catching a rule that matches nothing or names an unknown check.

add_rule persists a validated rule. It never writes blindly: with confirm=false (the default) it returns a preview of exactly what would be written; only confirm=true commits it. For safety it accepts built-in checks only (becwright run <name>) — a rule with an arbitrary shell command runs on every commit, so route those through the CLI becwright import, which shows the code to a human first.

Together they define the division of labor: becwright guarantees the execution; the agent does the translation, starting from propose_rules_from_claude_md, using list_checks as its vocabulary, extending with rules for prohibitions the extractor missed, using preview_rule to check each one, and add_rule (confirmed) to persist. Judgment-based guidance stays in CLAUDE.md.

Client configuration

Point your agent’s MCP config at the command:

{
  "mcpServers": {
    "becwright": {
      "command": "becwright",
      "args": ["mcp"]
    }
  }
}

The MCP server ships only with the Python package (it is not in the npm binary). For CLI/hook usage without Python, keep using the npm install.

When should you use MCP vs check --json?

Both return the same summary, so the choice is about the client, not the data:

  • Use check --json when the agent (or script) can run shell commands. It needs no extra dependency, works from the standalone npm binary without Python, and fits CI jobs and one-off scripts.
  • Use the MCP server when the client is MCP-native — Cursor or Windsurf, for example — and you want becwright to show up as discoverable, structured tools instead of a command the agent has to know to type. It requires the Python package with the mcp extra.
  • Claude Code can use either, but the dedicated plugin is the more comfortable path — it wraps the CLI in a skill and a /becwright command.

For per-agent setup, see the Claude Code and Cursor integration guides.