Content

# codefit
[](https://github.com/codefit-cli/codefit/actions/workflows/ci.yml)
[](LICENSE)
> **The MCP-first auditor for AI-generated code — codefit maps, the agent reasons.**
codefit is an open-source tool, written in Go, that audits software written
(partly or fully) by AI. It detects what a developer **never sees** during normal
development: security vulnerabilities, algorithmic complexity that scales badly,
structural database problems, regression risk, and quality issues that only
surface under deep review. Its guiding principle: *codefit audits what the
developer is never going to see* — if a dimension is visible during normal
development, it is out of scope.
## How it works — a collaborative loop, not a linter dump
codefit is not a tool that prints a list of findings. It is one side of a loop
between you, your agent, and codefit — each with a distinct job. **codefit reads
and analyzes (no LLM, never edits code); your agent reasons with its own LLM; you
decide.**
**The three roles — who does what.** Each color marks a role; you will see the
same colors again in the loop below.
```mermaid
flowchart LR
DEV["DEVELOPER<br/>talks & decides"]
AGENT["AGENT<br/>orchestrates & reasons<br/>(its own LLM)"]
CF["CODEFIT<br/>static analysis · NO LLM<br/>never edits code"]
BL[("baseline<br/>audit memory")]
DEV -->|"'audit this project / these endpoints / this function'"| AGENT
AGENT -->|calls MCP tools| CF
CF -->|"structural FACTS<br/>3 buckets + delta"| AGENT
AGENT -->|"buckets + project context"| DEV
CF <-.->|reads/writes| BL
DEV -.->|"fix code → re-audit"| AGENT
AGENT -.->|accept / prune| BL
style DEV stroke:#c89a4a,stroke-width:3px
style AGENT stroke:#5a8cd8,stroke-width:3px
style CF stroke:#2d9e54,stroke-width:3px
```
The boundary is the whole point: **codefit never calls an LLM.** It runs the
deterministic layers (patterns + AST), maps the structural *surface* of the
classes that need reasoning, and returns **facts** ("reads `params.id`", "no known
authz helper in the body") — never a verdict. The agent you already use supplies
the intelligence, reasoning each item with the project's context. That is what
democratizes auditing: anyone already coding with AI can audit without extra API
keys or infrastructure.
**One full pass through the loop.** Same actors, same order as above — the
developer asks, the agent orchestrates, codefit reports facts, the developer
decides, and a fix re-enters the loop.
```mermaid
sequenceDiagram
actor Dev as Developer
participant Agent as Agent (its own LLM)
participant CF as codefit (NO LLM)
participant BL as baseline
Dev->>Agent: "audit this project / these endpoints / this function"
Agent->>CF: calls MCP tools
CF->>BL: reads code + baseline
CF-->>Agent: structural FACTS — 3 buckets + delta
Note over CF: never judges, never edits code
Agent->>Agent: reasons buckets WITH project context
Agent-->>Dev: findings + recommendation
Dev->>Agent: decides — false positive / fix / resolved
Agent->>BL: accept / prune
Note over Dev,BL: fix code → re-audit (loop repeats)
```
## What problem it solves (and what it is NOT)
The agent generates code that **passes the tests** and **meets the visible
criteria**. Nobody sees the rest: a missing ownership check on an endpoint, a model
serialized with every column to the client, a hash that is weak for security, an
index that only hurts at scale. codefit audits exactly that invisible layer.
It **complements** linters and type-checkers — it does not replace them. An unused
`any`, a style nit, an obvious type error are visible during normal development, so
a linter already catches them and they are **out of scope**. codefit is the
independent audit layer that validates AI-generated code is secure and correct
**before** it merges.
## Status — Phase 2 (the database dimension), OLAP still open
**Works today, on `main`, validated in real use against real backends:**
- **Providers:** TypeScript (gotreesitter, pure Go) and Go (`go/ast`, used for the
CI self-audit).
- **Deterministic security rules (TypeScript)** — five categories, each a fact at
certainty 1.0 (see [COVERAGE.md](COVERAGE.md)).
- **Surface mapping** — three categories (IDOR, broken authorization,
over-fetching) for Next.js (App Router + Server Actions), **Express, Fastify, and
NestJS**, enumerated completely for the agent to reason. Resource access in another
file is signalled (`indirect_access`), not followed across files.
- **`scan-all` three-bucket synthesis** + on-demand `scan-endpoint` detail.
- **Baseline** — a committed, content-addressed memory of the audited surface, with
`baseline-list` / `-accept` / `-prune`, so a re-scan only surfaces what changed.
- **`codefit init`** — detects the stack, writes `.codefit.yaml`, and installs
codefit's own thin skill for each detected agent.
- **MCP stdio server** (official MCP Go SDK), single static binary, `CGO_ENABLED=0`.
- **Database-dimension auditing** — a neutral schema model with two schema parsers,
**Prisma** (`schema.prisma`) and **SQL-DDL** (Flyway migrations, reconstructed
incrementally), the latter supporting **PostgreSQL, MySQL, and SQL Server (T-SQL)**
dialects selected by `database.type` in `.codefit.yaml` (`postgresql` | `mysql` |
`sqlserver`; `sqlite` returns an explicit "not supported yet" note). It audits, all
dialect-agnostic over the neutral schema: the schema's **structural quality** (keys,
indexes, column shape, name-heuristic smells), **view** sensitive-column exposure,
the **routine bodies** of stored procedures, functions, and triggers (dynamic SQL,
missing exception handling, cross-table cascades, external-effecting calls), and
**code×schema crosses** that check whether the columns the code actually filters on
are backed by an index. One structural fact is affirmed (a table with no primary
key); everything else is surface the agent reasons. Run it standalone with
`codefit-scan-db`; it also runs inside `scan-all` as its own section with a
per-dimension score. The rule inventory lives in [COVERAGE.md](COVERAGE.md).
Dogfooded on real Prisma and SQL-DDL (Postgres/MySQL/T-SQL) backends.
**On the roadmap (not yet in `main`):** the HTTP/SSE transport; OLAP / data-warehouse
DB rules; **literal values in the query model** — carrying the WHERE's literals so the
cross can infer cardinality from usage (a `String` used as an enum, a `DateTime` used
as a flag) and tell an equality filter from a range, the two field-observed limits of
the index-vs-query cross; Phase 3 code review / best practices / tests; Phase 4
knowledge packs + `update`.
See the [PRD](docs/PRD-codefit-v1.4.md) §25 and [VERSIONING.md](VERSIONING.md).
## What codefit covers today
Concretely, on `main` — so you know exactly what to expect without reading
[COVERAGE.md](COVERAGE.md) in full:
- **Languages.** TypeScript / TSX (full rules + surface) and Go (the CI self-audit).
- **Deterministic rules (TypeScript, certainty 1.0).** Hardcoded secrets, weak
crypto (MD5/SHA-1, insecure `Math.random` for tokens), dangerous
`eval`/`new Function`, inline SQL injection, and inline XSS via
`dangerouslySetInnerHTML` (React-specific by its pattern). These run on **any**
`.ts`/`.tsx` file — no framework gate; which ones fire depends on the code, not the
framework.
- **Surface mapping — the agent reasons.** IDOR, broken authorization, and
over-fetching, for **Next.js** (App Router route handlers + Server Actions),
**Express**, **Fastify**, and **NestJS**. Handlers are found by structural shape,
never by path or name. When a handler reaches a resource through a service in
another file, codefit flags it (`indirect_access`) and names the call — it does not
follow it across files; the agent does.
- **Dependency CVEs.** `codefit-check-cves` checks dependencies against
[OSV.dev](https://osv.dev) (free, no API key) using the **exact** versions from
`package-lock.json` / `go.mod` — never guessed from `package.json` ranges (no
lockfile → an honest note, not a guess). codefit keeps no vuln DB of its own and
surfaces OSV's severity rather than recomputing CVSS.
- **Database dimension — the agent reasons the surface.** Read from
`database.schema_paths` (a Prisma `schema.prisma` or a directory of SQL-DDL / Flyway
migrations reconstructed to the final schema). SQL-DDL parsing supports **three
dialects**, selected by `database.type` in `.codefit.yaml`:
```yaml
database:
type: postgresql # postgresql | mysql | sqlserver (sqlite: not supported yet)
schema_paths:
- db/migrations
```
codefit audits the schema's **structural quality** (keys, indexes, column shape, and
name-heuristic smells), **view** sensitive-column exposure, the **routine bodies** of
stored procedures, functions, and triggers (dynamic SQL, missing exception handling,
cross-table cascades, external-effecting calls), and — in `scan-all` — **crosses the
code's Prisma queries against the schema** to see whether the columns the code filters
on are backed by an index. One structural fact is affirmed (a table with no primary
key); everything else is surface the agent judges, all dialect-agnostic over the
reconstructed neutral schema. OLAP is **not** audited yet — declared, not silent. See
[COVERAGE.md](COVERAGE.md) for the full rule inventory and the declared SQL-DDL dialect
limits.
- **Not covered (declared, not silent).** JS server frameworks beyond
Next.js/Express/Fastify/NestJS; deep taint analysis; business-logic correctness;
architectural and race-condition classes. An Express/Fastify handler passed by
reference (not inline) is not enumerated. Full list and limits in
[COVERAGE.md](COVERAGE.md).
## Install
Two ways to install. **Option A (the release binary) is recommended** — it reports the
correct version and needs no Go toolchain.
### Option A — download the release binary (recommended)
Grab the archive for your platform from the
[latest release](https://github.com/codefit-cli/codefit/releases/latest). This is the
tagged build, so `codefit version` reports the real version, and it needs no Go.
**Linux / macOS** (pick your target: `linux_amd64`, `linux_arm64`, `darwin_arm64`):
```bash
tar -xzf codefit_<version>_linux_amd64.tar.gz
sudo mv codefit /usr/local/bin/ # a directory on your PATH
chmod +x /usr/local/bin/codefit
```
**Windows** (`windows_amd64`): download `codefit_<version>_windows_amd64.zip`, extract it,
and put `codefit.exe` in a stable folder (e.g. `C:\tools\codefit\`). Optionally add
that folder to your `PATH`.
Verify the download against `checksums.txt` from the release —
`sha256sum -c checksums.txt` (Linux), `shasum -a 256 -c checksums.txt` (macOS), or
`Get-FileHash codefit_<version>_windows_amd64.zip -Algorithm SHA256` (Windows PowerShell).
### Option B — `go install` (needs Go 1.25+)
```bash
go install github.com/codefit-cli/codefit/cmd/codefit@latest
```
Heads up: this reports its version as `0.1.0-dev (commit none, built unknown)` because
`go install` does not embed release metadata — the version is injected by ldflags only
in the release build (GoReleaser) and in `make build`. The binary is **functionally
identical** to the release. For the tagged version, download from
[Releases](https://github.com/codefit-cli/codefit/releases/latest) or build from a
checkout with `make build`.
### Verify the install
```bash
codefit version
# example output — your version, commit, and date will differ:
# release binary → codefit <version> (commit <commit>, built <date>)
# go install → codefit 0.1.0-dev (commit none, built unknown)
```
A single static binary, no runtime dependencies (`CGO_ENABLED=0`), cross-compiling
to linux/amd64, linux/arm64, windows/amd64, darwin/arm64. There is no LLM or auth
to configure — codefit manages no models and no credentials.
## Quickstart
```bash
# 1. In your project, generate config + install codefit's skill for your agent(s)
codefit init
# 2. Register codefit as an MCP server for your agent (see "Connect codefit" below)
# 3. From your agent, in plain language:
# "audit the endpoints in this project for IDOR and broken authorization"
```
The agent loads codefit's skill, calls `codefit-scan-all`, reads the three buckets,
reasons the surface with your project's context, and reports back. When you decide
an item is a false positive it calls `codefit-baseline-accept` with your reason;
after a fix it calls `codefit-baseline-prune`. You never leave the agent, and
codefit never touches your code.
## Connect codefit
Register codefit as a local (stdio) MCP server. The config blocks need the **absolute
path** to the binary unless it is on the agent process's `PATH`. codefit is stateless —
the project root is passed per call as the `root` tool argument, so the server needs no
`cwd`.
### Finding the binary path
**Linux / macOS:**
```bash
which codefit # if it's on your PATH
echo "$(go env GOPATH)/bin/codefit" # if you used `go install`
```
**Windows (PowerShell):**
```powershell
where.exe codefit # if it's on your PATH
Write-Output "$(go env GOPATH)\bin\codefit.exe" # if you used `go install`
```
With the release binary, the path is wherever you placed it (e.g.
`C:\tools\codefit\codefit.exe`).
> **Windows path gotcha (this is the one that bites):** in JSON (`.mcp.json`,
> `opencode.json`) a Windows path must use **double backslashes**
> (`"C:\\Users\\you\\go\\bin\\codefit.exe"`) or **forward slashes**
> (`"C:/Users/you/go/bin/codefit.exe"`). A single backslash is an invalid JSON escape
> and silently breaks the config. The same applies to TOML basic strings (Codex), or
> use a single-quoted literal string there: `'C:\Users\you\go\bin\codefit.exe'`.
In every Windows example below, **replace `you` with your Windows username** and point
the path at wherever codefit actually lives.
**Claude Code** — `.mcp.json` (project) or `claude mcp add`:
Linux / macOS:
```json
{
"mcpServers": {
"codefit": { "type": "stdio", "command": "/usr/local/bin/codefit", "args": ["mcp", "serve"] }
}
}
```
Windows:
```json
{
"mcpServers": {
"codefit": { "type": "stdio", "command": "C:\\Users\\you\\go\\bin\\codefit.exe", "args": ["mcp", "serve"] }
}
}
```
**OpenCode** — `opencode.json`:
Linux / macOS:
```json
{
"mcp": {
"codefit": { "type": "local", "command": ["/usr/local/bin/codefit", "mcp", "serve"], "enabled": true }
}
}
```
Windows:
```json
{
"mcp": {
"codefit": { "type": "local", "command": ["C:\\Users\\you\\go\\bin\\codefit.exe", "mcp", "serve"], "enabled": true }
}
}
```
**Codex** — `~/.codex/config.toml`:
Linux / macOS:
```toml
[mcp_servers.codefit]
command = "/usr/local/bin/codefit"
args = ["mcp", "serve"]
```
Windows (single-quoted literal string — no backslash escaping needed):
```toml
[mcp_servers.codefit]
command = 'C:\Users\you\go\bin\codefit.exe'
args = ["mcp", "serve"]
```
Then run `codefit init` in the project. It detects Codex by a **project-local
`.codex/`** dir (not the global config); if Codex is only configured globally,
`init` writes the skill to the standard `.agents/skills/codefit/` location and
tells you so.
## The tools
codefit exposes its capabilities as MCP tools in three roles:
**The engine** — run the analysis and read the result.
| Tool | What it does |
| --- | --- |
| `codefit-scan-all` | The per-endpoint synthesis: three buckets (`actionable` / `resolved_clean` / `frontier_pending`) + the baseline delta, plus a parallel `db` section (database-structure findings/surface) and a per-dimension `score`. The main entry point. |
| `codefit-scan-endpoint` | Full detail of one file on demand (to follow a `frontier_pending` endpoint). |
| `codefit-scan-security` | The deterministic findings + mapped surface over a project (the flat result). |
| `codefit-scan-db` | The database-structure audit over the configured schema (`database.schema_paths` — a Prisma `schema.prisma` or SQL-DDL migrations in PostgreSQL, MySQL, or SQL Server dialect per `database.type`): affirmations (e.g. a table with no primary key) + surface (un-indexed FKs, duplicate indexes, …). Returns `measured: false` with a note when there is no schema or parser. |
| `codefit-surface-idor` / `-authz` / `-overfetch` | Enumerate one surface category for the agent to reason. |
| `codefit-check-cves` | Check the project's dependencies against OSV.dev (free, no API key). Reads exact versions from lockfiles / `go.mod`; reports the vulnerable deps with id, severity and fixed version. |
**Baseline** — the project's audit memory (see below).
| Tool | What it does |
| --- | --- |
| `codefit-baseline-list` | List tracked items (fingerprint, file, category, state) — `filter: known` for what's still pending. |
| `codefit-baseline-accept` | Record a human's decision to accept an item (false positive / accepted debt) with a reason. |
| `codefit-baseline-prune` | Drop items a refactor resolved (re-scans to confirm they're gone first). |
**Auxiliary** — feed results back and introspect.
| Tool | What it does |
| --- | --- |
| `codefit-confirm-surface` | Integrate the agent's verdicts: a confirmed item becomes a probabilistic finding anchored to it. |
| `codefit-coverage` | The coverage manifest for a language — what codefit audits vs. reasons over vs. does not cover. |
## The baseline model
The baseline is a committed file (`.codefit-baseline`, repo root — shared knowledge
like `.codefit.yaml`) that records codefit's view of the audited surface, so a
re-scan only surfaces what changed. Key properties:
- **Identity by content, not line.** Each item is fingerprinted by its content
(category + file + normalized snippet), so moving code does not churn the baseline;
the item is re-detected only when its content actually changes (ADR 0009).
- **A snapshot of the current state, not an accept-list.** `scan-all` records the
delta — `new` / `changed` / `known` / `gone` — and acts on what's new; `known`
surface is silenced but counted (ADR 0010).
- **A safeguard graduated by certainty.** A surface item (a *question*) becomes
`known` automatically. A deterministic finding (an *affirmation*, certainty 1.0) is
**never auto-silenced** — it shows on every scan until a human accepts it with a
reason. Silencing an affirmation is graver than silencing a question (ADR 0011).
- **codefit never edits your code** — only its own baseline file, and only via the
agent acting on your decision (ADR 0012). The full decision history lives in
`docs/decisions/`.
## The differentiator: surface mapping
Deterministic rules are what any linter does. The honest **surface mapping** that
the agent reasons over is what makes codefit different. Classes like IDOR, broken
authorization, and over-fetching cannot be caught by a fixed pattern — they need
semantic understanding. So codefit does not mark candidates surgically (inheriting
the AST's blind spot); it **enumerates the complete structural surface** of each
class and hands all of it to the agent, with structural signals that are **facts**
and a reason-to-review that is a **question**. What it cannot confirm locally (the
data left the handler) it hands off at the *frontier*; what it does not cover it
**declares** in [COVERAGE.md](COVERAGE.md). Recorded in
[ADR 0005](docs/decisions/0005-surface-frontier-finite-vs-infinite.md) and
[ADR 0006](docs/decisions/0006-scan-all-endpoint-synthesis.md).
## Principles
- **codefit never touches your code.** It reads code and reads/writes its own
baseline. Fixes are the agent's and yours, never codefit's.
- **The developer always decides.** codefit informs (`blocked`, the buckets, the
consequences); it has no power over your git and never accepts an item on its own.
- **Agent-first, no LLM of its own.** codefit returns facts; your agent reasons.
- **Honest about coverage.** What it does not audit is declared, not hidden.
## Supported languages
| Language / Ecosystem | Status |
| --- | --- |
| **Go** | Provider + static security/best-practice detectors. codefit audits itself in CI. |
| **TypeScript / Next.js / Express / Fastify / NestJS / Prisma** | Deterministic security rules (5 categories, any TS file) + surface mapping (IDOR, authz, over-fetching) for Next.js App Router, Server Actions, Express, Fastify, and NestJS. Cross-file resource access is signalled (`indirect_access`), not followed. Validated against real Next.js, Express/Prisma, and NestJS/Prisma backends. |
| Java / Spring | Roadmap |
| Python / FastAPI / Django | Roadmap |
Adding a language means implementing one `LanguageProvider` — it never touches the
core, the sensors, the MCP server, or the reporting (see
[CONTRIBUTING.md](CONTRIBUTING.md) and `docs/decisions/`).
## Contributing
Contributions are welcome — new rules, surface categories, language providers, and
false-positive reports especially. See [CONTRIBUTING.md](CONTRIBUTING.md) and
[`rules/README.md`](rules/README.md). Please follow our
[Code of Conduct](CODE_OF_CONDUCT.md), and report security issues per our
[Security Policy](SECURITY.md).
## License
[Apache 2.0](LICENSE).
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available