Are you the author? Sign in to claim
AI writes. SPARDA proves. A deterministic, offline gate that catches when an AI edit removes a guard, exposes a route, o
🇫🇷 Français — L'IA écrit. SPARDA prouve. Un gate déterministe et hors-ligne qui détecte quand une modif d'IA retire une garde, expose une route ou casse un invariant — sans clé API, directement dans la boucle d'édition de l'agent. Pour tout comprendre en 10 minutes (douleur, architecture, vision) : SPARDA-EXPLIQUE.md.
L'IA écrit. SPARDA prouve.
The trust layer for AI-written backends. SPARDA compiles your backend — routes, database queries, state mutations, guards, side-effects — into one deterministic behavior graph, then statically proves what can and can't break before you ship: no unguarded mutation, no broken invariant, no non-atomic aggregate write.
100% local · deterministic · zero API key · no cloud account. It fails loudly on a real risk, and when it can only see part of your app it says PROVEN (PARTIAL) — never a false green.
From your Express, FastAPI, Flask, Next.js, NestJS or Medusa app — nothing to configure:
npx sparda-mcp apocalypse # prove the tree is safe to deploy — exit 1 on any real risk
npx sparda-mcp prove # the whole verdict: proof + coverage + shareable seal
npx sparda-mcp badge # a README badge: proven · coverage% · routes
Under the hood it compiles your backend into one language-agnostic graph — the Unified Behavior Graph (UBG), serialized as .sparda/ubg.json under the SBIR specification (SPARDA Behavior IR) — and every command is a pass over that graph.
[!IMPORTANT]
The Route-Compilation Proof — reproduce it yourself. SPARDA compiles real open-source monsters to their behavior graph with zero crashes, each in ≈1–2 seconds: Next.js Dub (579 routes), NestJS Immich (281), MedusaJS (477). It natively resolves deep Dependency Injection, external controllers, and Next.js handlers. Try it on your own codebase in 60 seconds:hljs language-bashnpx sparda-mcp proveHonesty first: compiling a route is a parser result; proving it safe is a separate per-repo verdict — and most real apps come back NOT_PROVEN, which is the true state, not a failure.
What the graph unlocks — 100% local, deterministic, zero runtime dependencies, zero API key:
| Command | What it does |
|---|---|
prove | The whole trust verdict in one gesture — proof + coverage + a shareable seal (--json / --markdown) |
apocalypse | Prove the deploy — no guard, invariant, transaction or aggregate boundary can be broken (SARIF + CI gate) |
heal | Self-heal, proven — the gate Copilot Autofix doesn't have: a fix ships only if replay matches, verify still passes, and apocalypse finds no new risk / no dropped guard. Whoever wrote the fix, the machine judges it. |
badge | The shareable artifact — a self-contained SVG badge + README snippet (verdict · coverage · routes) |
dossier | The public report — one self-contained HTML page: verdict, risks, and SPARDA's own blind spots |
ubg | Compile the codebase to its behavior graph (Express · FastAPI · Flask · Next.js · NestJS · Medusa natively; any stack via OpenAPI) |
timeless | Time-travel — record a production request, replay it byte-identically, export the bug as a test |
mirror | Execute the graph — serve the compiled behavior over HTTP with no framework and no source |
init / dev | Runtime, optional — expose the graph to AI clients as a live MCP server (+ Twin, Immune, Evolution) |
The prover is the product. The MCP server is one output of the graph, not the point — SPARDA compiles the whole system's behavior, then proves, replays, heals, and (optionally) serves it.
Nomenclature: SBIR is the specification (the format, like "JSON"); UBG is the compiled graph itself (the artifact, ubg.json). The MCP server is one output of the graph, not the product.
Beyond proving, SPARDA can turn your running app into a live MCP server — the graph, executable, with write-safety and an immune layer. This is optional and separate from the prover above.
Scan + inject — run once, from your app's directory:
npx sparda-mcp init
SPARDA parses your routes (AST), generates a marked /mcp router, injects it into
your app (with a backup), and writes sparda.json. Every step is reversible.
Start your app, then start the bridge:
npx sparda-mcp dev
Connect your client. init prints a ready-to-paste block for
claude_desktop_config.json, pre-filled with your app's name and path:
{
"mcpServers": {
"your-app": {
"command": "npx",
"args": ["sparda-mcp", "dev"],
"cwd": "/absolute/path/to/your-app"
}
}
}
Claude Code connects to the same bridge. That's it — your running app is now a set of MCP tools your AI can call.
To see SPARDA in action instantly without modifying your codebase:
npx sparda-mcp demo
This runs the entire MCP lifecycle (detect → parse → generate → inject → remove) on a bundled demo app in a temporary folder, in about 10 seconds. For the compiler itself, run npx sparda-mcp ubg then apocalypse on any Express/FastAPI app.
SPARDA is designed as a local organism. To see what it remembers and how much compute it has recycled:
npx sparda-mcp report
This prints a terminal dashboard aggregating your exposed tools, write opt-ins, proof journal decisions, and crystallized composite tools.
To write a self-contained, offline HTML dashboard at .sparda/report.html, append the --html flag:
npx sparda-mcp report --html
To output raw JSON for integration:
npx sparda-mcp report --json
SPARDA's Behavior Graph is a formal model of your system. Instead of waiting for runtime failures or relying on static analysis vibes, you can statically prove the safety of your backend before any deployment:
npx sparda-mcp apocalypse
This command reads the compiled .sparda/ubg.json (with zero source code parsing at runtime) and discharges five static correctness obligations:
guard..sql DDL or schema.prisma, Prisma enums included) without prior validation (Zod/Pydantic).To save your current graph as a safe baseline:
npx sparda-mcp apocalypse --save-baseline
Subsequent runs will diff the candidate graph against this baseline to detect regression vectors:
guard (Critical).If any Critical or High finding is found, apocalypse exits with a non-zero code to block your CI pipeline.
One step in your workflow — findings land in the GitHub Security tab (SARIF):
- uses: zyx77550/sparda@main
with:
sarif: 'true'
Every production request is deterministic between its effects — the compiler knows exactly where the nondeterminism lives (db, http, clock, random, uuid: the effect nodes of the graph). Timeless records only those points (a few KB per request) and replays the request byte-identically against your current code, with the database, webhooks and clock virtualized from the recording:
npx sparda-mcp timeless # list recorded flights
npx sparda-mcp timeless replay <id> # re-fly it — byte-identical or loud divergence
npx sparda-mcp timeless export <id> # the production bug is now a vitest test
Recording is two lines in your app (ESM), with deterministic sampling and GDPR redaction built in:
import { getFlightBox } from 'sparda-mcp/src/flight/box.js';
const box = getFlightBox();
box.arm();
app.use(box.middleware({ sample: 100 })); // 1 request in 100; passwords/tokens redacted by default
const db = box.wrapClient(pgPool); // your query client, tapped
The closed loop nobody else has: production bug → recorded flight → failing test → AI writes the fix → apocalypse proves the fix breaks no guard, invariant or transaction → deploy. Replay is per-request (concurrent-race capture is out of scope for v1 — stated, not hidden).
sparda healThe loop above, as one gesture — and the machine judges the fix, whoever wrote it:
npx sparda-mcp heal <flightId> # diagnose + write the fix brief
# ...apply the fix (a human, or --agent "your-ai-cli")...
npx sparda-mcp heal <flightId> --check --expect '{"status":404}'
The brief is built from the graph itself — it hands the fixer the handler's file:line, the capabilities the fix must not grow, and the guards it must not remove. Then the gate — the actual product — proves the fix on three axes at once:
verify still passes: the graph is still sound and deterministic.apocalypse diff against the frozen pre-fix graph: zero new critical/high findings, no guard removed, no blast radius grown.✓ HEALED & PROVEN — same recorded inputs, correct output, zero law broken, zero protection lost. Ship it.
The gate is honest in both directions: an unfixed bug, or a "fix" that silently drops a guard, keeps it closed (exit 1). This is the difference between an AI that writes plausible code and a system that proves the code is correct — the trust layer the agent era is missing.
SPARDA parses Express, FastAPI, Flask and Next.js natively — and every other stack through the format the industry already agreed on. Go, Java, Rails, Laravel, .NET: if it has an OpenAPI spec, it compiles.
npx sparda-mcp ubg --openapi openapi.json
Security schemes become gating guard nodes, response schemas become typed returns, declared request bodies count as validated input. Pair the spec with your .sql or schema.prisma files and the full state layer — invariants, aggregates, state machines — fills in from declared truth. (JSON specs in v1; we refuse to half-parse YAML with zero dependencies.)
The graph is not a diagram — it executes:
npx sparda-mcp mirror
MIRROR — the graph is serving. 3 entrypoint(s) on http://127.0.0.1:4477
GET /orders/{orderId} → {amount, id, status}
POST /orders 🔒 bearerAuth → {amount, id, status}
No Express. No FastAPI. No source code — just ubg.json answering HTTP: guards actually deny (401), responses render the compiled return schemas, unknown paths 404 with the full route table. Front-end teams develop against backends that aren't deployed yet — or aren't written yet (point mirror at an OpenAPI spec). Every response carries x-sparda-mirror: true; the mirror serves declared behavior, it never invents business values.
To undo everything: npx sparda-mcp remove restores your code byte-for-byte.
npx sparda-mcp remove restores your code byte-for-byte (tested on JS, TS, Python, even Windows CRLF files). No trace, no lock-in.What we don't promise: the honest limits in docs/SECURITY.md.
npx sparda-mcp init parses your codebase (AST), extracts every route, and injects a tiny marked router (/mcp) into your app — fully reversible with npx sparda-mcp remove.sparda.json + git.sparda.json — your choices survive re-runs.npx sparda-mcp doctor --app audits your codebase for drift: it detects stale tools (IA seeing ghosts), unsynced routes, schema drift via fingerprints, and zombie configurations. High severity issues trigger a non-zero exit code for your CI pipeline.npx sparda-mcp seed export/import lets you package and share your app's "genome" (semantic memory, workflows, antibodies) securely, transferring immune memory between environments or across similar stacks with zero data leak.npx sparda-mcp twin starts a safe, simulated mock server of your backend on the original port. It serves GET calls from learned exemplars (observed response shapes & mock data) and returns simulated 202 writes without ever touching your real database or production APIs. Learn exemplars by running npx sparda-mcp twin --learn.npx sparda-mcp grammar maps the graph of valid sequences of tool calls (observed circuits and candidate hypotheses) to prevent LLM hallucination of routes.npx sparda-mcp evolve mutates candidate chains and tests them against the twin in-memory, promoting successful chains to evolved workflow suggestions.Every route becomes a tool that runs against your live process — real auth, real data,
warm connections. One call to sparda_get_context hands the AI the whole living
picture: enabled tools, suggested workflows, runtime telemetry, quarantine state, and
immune memory — so every session resumes where the last one stopped.
The AI just edited a route. Did it quietly drop a guard? It calls sparda_prove and
finds out now, not in a CI run later. The tool recompiles the app to its behavior graph,
discharges the same static obligations as sparda apocalypse, and returns a deterministic
verdict — the exact word the CLI and badge emit, so it can never over-claim (a low-coverage
clean app reads SURFACE, never a bare PROVEN). Save a baseline once
(sparda apocalypse --save-baseline) and every later sparda_prove flags any finding with
regression: true — the guard your edit removed, the route it dropped, the blast radius it
grew. That's "AI writes. SPARDA proves." inside the edit loop. Clients that list MCP prompts
also get the prove-my-edit workflow.
sparda.json; your choice survives every re-init.awaiting_confirmation envelope — a single-use token plus a preview of the action — and commits only after an explicit confirm step.503 with a reason and a retry delay instead of hammering your broken route. After a cooldown it half-opens for a single probe.sparda.json, so the same failure later costs zero tokens. Cloning your code doesn't clone its immune memory.On first connection your AI client's own model (via MCP sampling) rewrites raw routes
into business-language tool descriptions and proposes multi-step workflows — cached in
sparda.json and exposed as MCP prompts. Nothing to configure, nothing to pay.
GET /mcp/stats counts how many calls were answered from SPARDA's own knowledge vs. how many paid the host route. It reads 0% on day one and fills with usage — a measure, never a promise.Turn it on with "labs": { "recordSequences": true } in sparda.json. SPARDA then
notices when one tool's output feeds the next tool's input and records the circuit —
structure only (tool names, argument names, counts), never your data. A read-only
circuit seen enough times crystallizes into a composite tool, announced
mid-session: one call runs the whole chain, auto-feeding each step from the previous
step's real response. Write routes are never absorbed — their per-call confirmation
always stands.
GET /mcp/stats (per-tool calls/errors, tool "purity", quarantine state) and
GET /mcp/events (errors, latency anomalies, cached diagnoses) expose exactly what
your app is doing — surfaced to the AI as live notifications.
SPARDA ships with an Agent Skill (SKILL.md) that teaches any compatible
AI client how to drive a SPARDA server to its full potential — call
sparda_get_context first, exploit response recycling, honor quarantine, prefer
crystallized circuits over re-walking a chain, and follow the two-phase write-confirm
protocol. The live, per-project tool list always comes from sparda_get_context at
runtime, so the guidance never goes stale.
export const POST = withAuth(h)) and deep effect chains.baseUrl/paths imports. Supports Prisma, TypeORM, and Kysely.bootstrap.ts, etc).SPARDA_LOCAL_KEY environment variable or the local gitignored .sparda/key file, and fails closed (503) when neither is found. For custom production or staging setups, you can override this behavior by exposing SPARDA_LOCAL_KEY in your environment.npx sparda-mcp remove leaves a clean git diff.Full threat model and known gaps: docs/SECURITY.md.
init, the injected router, and the bridge fit together, plus the sparda.json schema.SPARDA is free, including in production (see License). Team-scale capabilities — fine-grained per-person access policies and a signed, tamper-evident audit log — are planned for a future paid tier. The open core stands on its own; nothing here is crippled to upsell you.
Business Source License 1.1 — free to use, including in production. You may not resell SPARDA or offer it as a competing commercial service. Each version converts to Apache 2.0 four years after its release.
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows