Ludwig Spec Driven Development MCP Ludwig Spec Driven Development MCP is a specification-driven framework that uses prose-first markdown specs to drive LLM code generation and verification for Rust projects. The framework ensures spec and implementation stay coupled by using the same document for both generation and verification, with deterministic checks via cargo test. Named after Ludwig Wittgenstein, it targets Rust exclusively and supports two workflows: decomposing descriptions into specs and generating code from active specs. A specification-driven development framework whose specs are written as close to natural language as possible. The same prose-first markdown spec drives LLM code generation and verifies the resulting code. Named after Ludwig Wittgenstein. Scope:Ludwig targetsRust. Deterministic checks shell out to cargo test , so verifying a project requires a Cargo workspace. The spec format itself is plain markdown, but verification is Rust-specific by design — there is no plan to add adapters for other languages. Today, when a human asks an LLM to write code, the request is a chat message and the contract is whatever the model inferred. The result drifts the moment either side is edited. Ludwig replaces the chat message with a specification — a markdown document with a small fixed shape — that is the durable, versioned source of intent. The same document drives generation and verifies the resulting code, so spec and implementation stay coupled. --- id: token-bucket-rate-limiter title: Token-bucket rate limiter status: active implements: - src/rate limit/token bucket.rs version: 4 --- Intent Protect downstream services from bursty clients by allowing short bursts up to a configured capacity while enforcing a steady average rate. The limiter is a building block for per-tenant API quotas; it is not, by itself, a fairness mechanism between tenants. Behavior - { b1} A limiter is created with capacity and refill rate tokens/sec . - { b2} try acquire n returns true and consumes n tokens iff at least n are available. - { b3} Tokens refill continuously based on wall-clock time, capped at capacity. Examples ​ example name="burst then throttle" Given a limiter with capacity 5 and refill rate 1/sec When try acquire 1 is called 5 times in immediate succession Then all 5 calls return true And the 6th call in the same instant returns false ​ Invariants - {deterministic} tokens consumed <= capacity + refill rate elapsed seconds. - {property} after waiting C / refill rate seconds the limiter is full. - {judgment} Errors surfaced to callers name the limiter and required wait in plain English. Sections are fixed and ordered: Intent → Behavior → Examples → Invariants plus optional Non-goals , Open questions , Implementation notes . The only embedded DSL is Given/When/Then inside Examples — Gherkin-shaped so LLMs already know it. Ludwig supports two complementary directions: 1. Description → specs. Start from a project or feature description; the host agent decomposes it into specs and drafts each one; Ludwig validates and persists; the human reviews before any implementation. echo "A URL shortener with per-tenant analytics" | ludwig decompose inside Claude Code: /project-decompose A URL shortener with per-tenant analytics agent emits JSON, then for each game/spec calls game.create + spec.propose + spec.write ludwig catalog && cat specs/ index.md review, then move drafts to status: active 2. Spec → code. Once a spec is active, generate the implementation, then verify. ludwig init one-time scaffolding ludwig new auth/login --game auth OR write a spec by hand /spec-generate login inside Claude Code: LLM writes src/ + tests/ludwig login.rs ludwig verify login structural + deterministic + judgment-pending /spec-verify login inside Claude Code: also evaluates {judgment} invariants git add specs/ src/ tests/ .ludwig/state.json && git commit When you change the spec, ludwig diff flags the implementing files. When you change the code directly, the same diff flags drift on the other side. The trailing ludwig-spec: