# BenchFit > BenchFit grades a codebase's fitness (A+..F, 0-100) across six dimensions — R Readability, C Changeability, O Operational, D Dependency, T Test Quality, X Change Risk — plus pass/fail architecture gates and a Big Ball of Mud (BBoM) risk index. Languages: Go, Rust, TypeScript/JavaScript, Python, Java, Kotlin, Swift, C/C++ (embedded-focused), C# — all GA — plus experimental PHP; polyglot repos supported. Deterministic static analysis — no LLM calls in scoring. ## Install - The CLI is issued per account, not published openly: it carries the scoring engine, so /download/{name} requires a live "Authorization: Bearer bf_…" key and refuses revoked ones. - Request a free Community key: https://bench.fit/waitlist - curl -fsSL https://bench.fit/install.sh | BENCHFIT_KEY=bf_live_… sh (macOS/Linux; env: BENCHFIT_KEY (required), BENCHFIT_INSTALL_DIR, BENCHFIT_BASE) ## The agent loop 1. `benchfit -format=json` — grade, score, dimensions, gates (schema_version 2) 2. `benchfit next -json` — top recommendation (`-all` for full list; `-dimension R|C|O|D|T|X` to focus) 3. `benchfit explain ` — what it measures, why it matters, how to fix (offline; the registry ships in the binary) 4. Make the smallest fix, re-scan, confirm score moved and no gate regressed; repeat. - `benchfit snooze [-days 1..30]` mutes a recommendation. Advisory-only: never changes scores, gates, JSON output, or exit codes; `next` always prints a footer while snoozes are active. - `benchfit quibble -m "..."` sends instrument feedback (requires `benchfit login`; payload prints before sending; carries no source, paths, or repo names). Never disable a gate or exclude files to raise the score — fix the cause. ## MCP server (the same loop, as tool calls) - `claude mcp add benchfit -- benchfit mcp` — registers the CLI as a stdio MCP server (any MCP client works; `benchfit mcp` speaks stdio JSON-RPC) - Tools: scan (local by default; cloud=true lands it on the user's dashboard) · next · explain · history · quibble · snooze - The calling agent is the LLM: BenchFit never invokes a model, and no tool call can alter scores — quibble is feedback, snooze is advisory-only - Local tools need no login; quibble and scan cloud=true need `benchfit login` once (run it in a terminal — device flow) ## CLI commands - benchfit [-dir path] [-format table|json] [-strict] [-min-score N] [-min-grade B+] [-language go|rust|typescript|python|cpp|java] [-domain embedded] [-cloud] [-no-history] [-no-color] - benchfit next [-json] [-all] [-dimension R|C|O|D|T|X] [-verbose] [-threshold N] - benchfit explain [-list] [-json] · benchfit snooze [-days N] | -list | -clear · benchfit quibble -m "msg" [-y] - benchfit context · plugin list · agent list · agent run [-format json] · login · web · mcp · version ## Exit codes - 0 success (scan completed; all thresholds passed) - 1 CI threshold tripped: -strict with a failed BLOCKING gate, -min-score, or -min-grade - 2 usage error or scan failure (bad flags, unknown explain ID, unreadable dir, scan error) ## Scan JSON top level (-format=json, schema_version 2) { schema_version, scoring_epoch, grade, score, dimensions:[{code,name,score,weight,metrics:[...],not_applicable?}], gates:[{id,name,passed,severity,violations,details,violation_details?,skipped?,suppressed?,domain?}], bbom:{raw_value,class,indicators}, scanned_at, duration, files_scanned, packages_scanned, git_data_available, computed_without_x?, agent_results?, languages:[per-language results], summary, context_summary, status, comparison? } ## next -json shape { current_score, current_grade, target_score?, recommendations:[{priority, category:"gate"|"dimension"|"metric", id, title, severity?, language?, impact, guidance, details, violation_details?}] } ## Explain pages (KEYED — not public) - The explain corpus is BenchFit's ontology: every gate and metric, what it measures, why it matters, how to fix it. It is issued per account, not published. - https://bench.fit/explain/ and https://bench.fit/explain/index.json both require `Authorization: Bearer bf_…` from a live, unrevoked key, and are rate-limited per account. A forged or revoked key gets 401. - Every CLI user already has the whole corpus offline: `benchfit explain ` reads the registry embedded in the binary and makes no network call. This is the intended path — the HTTP surface exists for convenience and linking, not as the source of truth. - Request a free Community key: https://bench.fit/waitlist - Agent finding IDs (CSFA-*) in agent_results are self-describing (message + suggestion inline) and are NOT part of the explain registry. ## Cloud API (base https://bench.fit) - Auth: Authorization: Bearer bf_ (get a key: `benchfit login`) - Signup: during invite-only beta phases (server-armed), NEW accounts need a single-use invite code — `benchfit login -invite bfi-...`; without one, signup answers 403 pointing at https://bench.fit/waitlist. Existing keys are unaffected. - POST /v1/scans — multipart: source = tar.gz WITHOUT .git; optional git_metrics (client-computed aggregates), project. Returns the scan JSON; scan id in X-Benchfit-Scan-Id. Errors: 401 bad key, 403 project cap, 413 too large, 422 scan failed, 429 rate limited (Retry-After), 503 at capacity, 507 storage full. - GET /v1/me — key name, plan, limits {scans_per_hour, max_projects, monitoring} - GET /v1/history [?project=&limit=] — stored scan aggregates - GET /v1/web/link — signed dashboard link · POST /v1/activity — improve-loop beacon (consent-gated; 202 carries your unread founder-reply notice) POST /v1/quibble — instrument feedback · GET /healthz — liveness (no auth) - Spec: https://bench.fit/openapi.yaml (OpenAPI 3.0) ## Plans and limits - Community (free, public handle): 30 scans/h (burst 10), 15 projects - Vibe (paid, anonymous): 60/h (burst 15), 50 projects · Vibe Pro: 120/h, 150 · Vibe Monitor: 240/h, 150 + CI monitoring headroom - Enterprise (required for ALL commercial/company use): 600+/h, 500+ projects, monitoring; the custom tier adds on-prem/self-hosted and compliance packs ## Privacy invariants - Cloud scans upload the tree WITHOUT .git; source is deleted the moment scoring finishes; only your report card — aggregate scores, gate results, and the file paths of findings — is retained, keyed by a pseudonymous account id - Git change-risk aggregates are computed client-side — commit contents and author identities never leave your machine - quibble payloads carry no file paths, no source, no repo/project names, and print before sending - Local scans (the default without -cloud) never upload anything ## More docs - The changelog and self-grade pages (/changelog, /self-grade) are keyed — they narrate gate IDs and scoring internals, so they require an account. - https://github.com/bench-fit/benchfit — README plus docs/ (gates.md, dimensions.md, ci-integration.md, interpreting-results.md, configuration.md, plugins.md, agents.md)