norma im Detail: Ein MCP-Server, der Coding-Standards nicht vorschlägt, sondern erzwingt
Das Problem: Standards, die niemand durchsetzt
Jedes Team hat sie: ungeschriebene oder halb-geschriebene Regeln. Kein System.out.println in Produktionscode. Singletons nur über die vorgesehene Factory. Kein await innerhalb von Promise.all. Diese Regeln landen in Wikis, Style-Guides, PR-Kommentaren – und verblassen dort, weil sie beim eigentlichen Schreiben des Codes nicht sichtbar sind.
AI-Coding-Assistenten wie Claude Code oder Cursor könnten das ändern, wenn sie die Regeln kennen würden. Genau diese Lücke schliesst norma.
Was ist norma
norma ist ein Model Context Protocol (MCP) Server, geschrieben in Rust, der Design-Patterns und Coding-Standards gegen Code prüft und – wo möglich – automatisch fixt. Er nutzt ast-grep-core/-config/-language direkt als Rust-Library (kein Subprozess) und speichert registrierte Regeln persistent in SQLite.
norma ist als ein Binary mit gemeinsamem Core gebaut: norma serve startet den MCP-Server über stdio für Claude Code & Co., norma validate/list-patterns/import sind die CLI-Äquivalente für Terminal und CI/pre-commit – beide Wege laufen durch dieselbe Validierungs-Logik, es gibt keine doppelte Implementierung.
Das Pattern-Modell
Ein Pattern ist immer einsprachig. Eine Idee wie “kein Debug-Print” wird zu mehreren Pattern-Zeilen – eine pro Sprache – verbunden über einen gemeinsamen name. Das Feld rule enthält das vollständige ast-grep RuleConfig-YAML-Dokument, eins zu eins copy-paste-fähig aus ast-greps eigener Doku oder CLI-Output:
id: no-debug-print-java
message: Avoid System.out.println in production code
severity: warning
language: Java
rule:
pattern: System.out.println($$$ARGS)
id, language und severity werden nie separat übergeben – sie werden immer aus rule abgeleitet, damit sie nie mit dem tatsächlichen YAML auseinanderdriften.
Die sieben MCP-Tools
| Tool | Zweck |
|---|---|
validate_pattern_compliance | Code gegen registrierte Patterns prüfen |
apply_pattern_fix | Automatische Fixes anwenden, wo eine Regel fix: definiert |
get_pattern_checklist | Checkliste registrierter Patterns pro Sprache abrufen |
test_pattern | Eine Regel gegen Beispielcode testen, ohne sie zu speichern |
register_pattern | Eine einzelne Regel dauerhaft registrieren |
import_rules | Ein ganzes Rule-Verzeichnis (z. B. aus ast-greps Katalog) auf einmal importieren |
list_patterns | Alle registrierten Patterns auflisten |
norma vs. ast-grep-mcp
ast-grep bringt mit ast-grep-mcp einen eigenen, ausdrücklich experimentellen MCP-Server mit. Beide sind komplementär, nicht konkurrierend:
ast-grep-mcp | norma | |
|---|---|---|
| Beantwortet | “Wo kommt X vor, wie schreibe ich eine Regel dafür?” | “Verstösst dieser Code gegen eine stehende Regel?” |
| Regeln | ephemeral, pro Aufruf gebaut, nie gespeichert | persistent, einmal registriert, jedes Mal durchgesetzt |
| Implementierung | Python, ruft die ast-grep-CLI als Subprozess | Rust, bindet ast-grep-core/-config/-language direkt ein |
| Zustand | keins (kein SQLite) | SQLite-gestützter PatternStore, übersteht Neustarts |
Der Workflow, der sich daraus ergibt: Mit ast-grep-mcp (oder der ast-grep-CLI) eine Regel entdecken und iterieren, dann mit norma dauerhaft registrieren – ab da wird sie bei jedem Aufruf durchgesetzt, nicht nur einmal gefunden.
Loslegen
git clone git@github.com:talent-factory/norma.git
cd norma
cargo build --release
cargo install --path .
norma serve # MCP-Server für Claude Code / Cursor
norma validate --language rust src/main.rs # CLI, auch für pre-commit
norma validate --language rust --fix src/main.rs # automatische Fixes anwenden
20 Patterns sind sofort einsatzbereit (vier Debug-Print-Regeln plus die vier GoF-Klassiker Singleton, Factory, Observer, Strategy, für Java, Python, Rust und TypeScript). Alle 28 von ast-grep-language unterstützten Sprachen sind registrierbar – nicht unterstützte oder falsch geschriebene Sprachen werden laut abgelehnt, nie stillschweigend mit null Treffern durchgewunken.
Mitmachen
Testet norma in einem eigenen Projekt, registriert eure eigenen Team-Patterns oder importiert einen bestehenden ast-grep-Rule-Katalog per import_rules/norma import. Wenn ihr eine Regel baut, die über euer eigenes Projekt hinaus nützlich sein könnte – meldet euch über ein Issue im Repo. norma lebt von den Patterns, die echte Teams tatsächlich brauchen.