Talent Factory Talent Factory
Home Products Services About Us Resources Teaching Contact

norma in Detail: An MCP Server That Doesn't Suggest Coding Standards — It Enforces Them

· by claude
mcp ast-grep rust developer-tools code-quality design-patterns

norma in Detail: An MCP Server That Doesn’t Suggest Coding Standards — It Enforces Them

The Problem: Standards That Nobody Enforces

Every team has them: unwritten or half-written rules. No System.out.println in production code. Singletons only via the designated Factory. No await inside Promise.all. These rules end up in wikis, style guides, and PR comments — where they fade away, because they aren’t visible at the moment the code is actually being written.

AI coding assistants such as Claude Code or Cursor could change that, if only they knew the rules. That is precisely the gap norma closes.

What is norma

norma is a Model Context Protocol (MCP) server, written in Rust, that checks design patterns and coding standards against code and — where possible — applies fixes automatically. It uses ast-grep-core/-config/-language directly as a Rust library (no subprocess) and stores registered rules persistently in SQLite.

norma is built as a single binary with a shared core: norma serve starts the MCP server over stdio for Claude Code and similar tools, whilst norma validate/list-patterns/import are the CLI equivalents for the terminal and CI/pre-commit — both paths run through the same validation logic, with no duplicated implementation.

The Pattern Model

A Pattern is always single-language. An idea such as “no debug print” becomes multiple Pattern entries — one per language — linked by a shared name. The rule field contains the complete ast-grep RuleConfig YAML document, ready to copy and paste directly from ast-grep’s own documentation or 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, and severity are never passed separately — they are always derived from rule, so they can never drift out of sync with the actual YAML.

The Seven MCP Tools

ToolPurpose
validate_pattern_complianceCheck code against registered patterns
apply_pattern_fixApply automatic fixes where a rule defines fix:
get_pattern_checklistRetrieve a checklist of registered patterns per language
test_patternTest a rule against sample code without saving it
register_patternPermanently register a single rule
import_rulesImport an entire rules directory (e.g. from ast-grep’s catalogue) in one go
list_patternsList all registered patterns

norma vs. ast-grep-mcp

ast-grep ships its own explicitly experimental MCP server, ast-grep-mcp. The two are complementary rather than competing:

ast-grep-mcpnorma
Answers“Where does X occur, and how do I write a rule for it?”“Does this code violate an established rule?”
RulesEphemeral, built per call, never savedPersistent, registered once, enforced every time
ImplementationPython, calls the ast-grep CLI as a subprocessRust, binds ast-grep-core/-config/-language directly
StateNone (no SQLite)SQLite-backed PatternStore, survives restarts

The workflow that emerges from this: use ast-grep-mcp (or the ast-grep CLI) to discover and iterate on a rule, then register it permanently with norma — from that point on it is enforced on every invocation, not merely found once.

Getting Started

git clone git@github.com:talent-factory/norma.git
cd norma
cargo build --release
cargo install --path .

norma serve                                       # MCP server for Claude Code / Cursor
norma validate --language rust src/main.rs        # CLI, also suitable for pre-commit
norma validate --language rust --fix src/main.rs  # apply automatic fixes

20 patterns are ready to use straight away (four debug-print rules plus the four GoF classics — Singleton, Factory, Observer, and Strategy — for Java, Python, Rust, and TypeScript). All 28 languages supported by ast-grep-language can be registered — unsupported or misspelt languages are rejected loudly and never silently passed through with zero matches.

Get Involved

Try norma in your own project, register your team’s patterns, or import an existing ast-grep rules catalogue via import_rules/norma import. If you build a rule that could be useful beyond your own project, raise an issue in the repository. norma thrives on the patterns that real teams actually need.

👉 github.com/talent-factory/norma