ERDL MCP Server
by OpenOBA
README.md
# ERDL MCP Server
> **Stop reminding your Agent to behave. Teach it.**
> **One when/then sentence is all it takes.**
[](https://www.npmjs.com/package/@openoba-ai/erdl-mcp)
[](https://www.npmjs.com/package/@openoba-ai/erdl-mcp)
[](https://github.com/OpenOBA/erdl-mcp-server/blob/master/LICENSE)
[](https://github.com/OpenOBA/erdl-mcp-server/actions)
[](https://modelcontextprotocol.io)
[](https://github.com/OpenOBA/erdl-mcp-server/blob/master/LICENSE)
> π [δΈζη](./README.zh.md)
```bash
npx -y @openoba-ai/erdl-mcp
```
**30 rules. 5 tools. Zero config. Unlimited custom rules. Free forever.**

---
## The Problem
You tell your Agent "don't use `any`", "keep it short", "ask before adding dependencies". It nods. Five turns later, it's back to its old habits.
**Prompt-based rules don't work.** LLMs forget. They reinterpret. They rationalize. You're not guiding them β you're negotiating with them.
---
## The Solution
ERDL (Entity-Rule Definition Language) is a **deterministic rule engine** that runs as an MCP Server. Your Agent doesn't *try* to follow rules β the engine *enforces* them before every tool call.
| You say | What actually happens |
|---------|----------------------|
| "Never use `any`" | **Blocked**. The engine intercepts `write_file` calls, scans the content, and rejects `any` before the write happens. |
| "Don't start with 'In today's world'" | **Denied**. Writing rules fire before every output. The Agent receives the correction before it speaks. |
| "Ask before adding npm dependencies" | **Intercepted**. `exec` of `npm install` is stopped. You approve it, or it doesn't happen. |
| "Why did you do that?" | **Explained**. `erdl_explain` shows exactly which rule fired, what condition matched, and what happened. |
---
## How It Works
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Agent Workflow β
β β
β User says: "Write me a function" β
β β β
β βΌ β
β LLM plans: use write_file(path, code) β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββ β
β β ERDL Action Guard (MCP Server) β β Protocol β
β β β Layer β
β β 1. Load 30 built-in rules β β
β β 2. Evaluate: field/operator/value β β
β β 3. Decision: ALLOW / DENY / CORRECT β β
β β 4. Return badge card + explanation β β
β ββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β Tool executes (or is blocked) β
β β
β No prompt engineering. No negotiation. Protocol-level. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## Quick Start
```bash
# One command. 30 rules active immediately.
npx -y @openoba-ai/erdl-mcp
```
That's it. No account. No API key. No configuration.
**Chinese / δΈζοΌ**
```bash
npx -y @openoba-ai/erdl-mcp --lang zh
```
Add it to your MCP client:
```json
{
"mcpServers": {
"erdl": {
"command": "npx",
"args": ["-y", "@openoba-ai/erdl-mcp@latest"]
}
}
}
```
Or let ERDL generate the config:
```bash
npx @openoba-ai/erdl-mcp@latest --setup
```
**Supported clients:** Claude Desktop Β· Cursor Β· VS Code / Copilot Β· OpenClaw Β· WorkBuddy Β· any MCP-compatible client.
---
## ERDL vs Prompt Rules
| | Prompt / SKILL.md | ERDL |
|---|:---:|:---:|
| **Enforcement** | LLM "tries" to follow | **Deterministic engine** β guarantees execution |
| **Reliability** | May forget after 5 turns | Condition match is mathematical β **zero hallucination** |
| **Visibility** | Can't tell if it worked | `erdl_explain` shows every decision, every rule |
| **Testing** | Manual verification | `erdl_simulate` β 3 auto-generated scenarios |
| **Portability** | Tied to one platform | **All MCP-compatible Agents** |
| **Overridability** | LLM can "reinterpret" | **Protocol-layer block** β Agent cannot bypass |
---
## What's Included
### 30 Built-in Rules
| Category | Count | Covers |
|----------|:-----:|--------|
| `engineering` | 13 | Pipeline gates, no shortcuts, self-verify, decision logging, no force-push, no stash |
| `coding` | 6 | No `any`, no `@ts-ignore`, naming conventions, one-commit-one-change, dependency hygiene |
| `security` | 6 | No eval with input, no hardcoded secrets, no string SQL, validate all input, security headers, no stack traces |
| `testing` | 2 | Coverage never drops, no behavior without test |
| `writing` | 2 | Direct tone, no AI jargon |
| `observability` | 1 | No secrets in logs |
### 5 MCP Tools
| Tool | Use it when |
|------|-------------|
| `erdl_evaluate` | **Before every tool call** β mandatory Action Guard |
| `erdl_simulate` | Test a rule against 3 scenarios before creating it |
| `erdl_create_rule` | User says "remember this" β create a rule from NL |
| `erdl_list_rules` | User asks "what rules are active?" |
| `erdl_explain` | User asks "why did you do that?" β full decision trail |
### 2 Resources
| Resource | Purpose |
|----------|---------|
| `erdl://rules/list` | All active rules as JSON |
| `erdl://status` | Runtime status: rule counts by category, agent role |
---
## Creating a Rule
> **Turn your pain points into rules, one sentence at a time β banned, period.**
> **Turn your experience into rules, one sentence at a time β shared, forever.**
Every pain point is a `when(β¦) then(β¦)` sentence:
> when [trigger] Β· then [action]
| Variable | Meaning | Example |
|----------|---------|---------|
| **when** | What triggers it | code contains `any` Β· logs contain secrets Β· `git stash` used |
| **then** | What happens | **Block** it Β· **Correct** it Β· **Allow** with a warning Β· **Pause** for approval |
Fill in the blanks:
> **when** code contains `any` **then** block it\.
That's a rule.
```
You β "Never use `any` in TypeScript."
Agent β 1. erdl_simulate β tests against 3 scenarios
2. erdl_create_rule β saves to ~/.openoba/rules/
3. Rule is active. β next `any` is blocked.
You β "Why was my code rejected?"
Agent β erdl_explain β full decision trail:
β
no_any: tool.name in [write_file, edit, apply_patch] AND content contains "any"
β DENY: Do not use `any` type.
```
Or write rules by hand in `~/.openoba/rules/` (ERDL SPEC Β§5 format):
```yaml
protocol: "erdl/v1"
version: "1.0.0"
rules:
- name: "no_console_log"
description: "Don't commit console.log statements"
priority: 10
when:
logic: AND
conditions:
- field: "tool.name"
operator: in
value: ["write", "edit", "apply_patch"]
- field: "tool.args"
operator: match
value: "console\\.log"
then: DENY
message: "Remove console.log before committing"
```
[π Full Tutorial β](./docs/tutorial-create-rules.md) Β· [π Rule Reference (30 rules) β](./docs/rule-reference.md)
---
## Free vs Pro
| | Free | Pro |
|------|:---:|:---:|
| 5 MCP Tools | β
| β
|
| 30 Preset Rules | β
| β
|
| Unlimited Personal Rules | β
| β
|
| Chinese / English | β
| β
|
| All 11 Operators | β
| β
|
| MIT Open Source | β
| β
|
| **Execution Rings 1β2** (REQUEST_HUMAN, ESCALATE, ROLLBACK, QUARANTINE) | β | β
|
| **Guardian Agent Role** | β | β
|
| **Audit Export** (OCSF / OTLP) | β | β
|
| **Team Rules** | β | β
|
| **Dashboard** (hit statistics) | β | β
|
| **Enterprise Compliance** (GB/Z 185, NIST, EU AI Act) | β | Enterprise |
[Get a Pro License β](https://openoba.com/erdl-mcp/pro)
---
## CLI Reference
```bash
npx @openoba-ai/erdl-mcp@latest # Start (auto-latest via npx)
npx @openoba-ai/erdl-mcp@latest --lang zh # Chinese mode
npx @openoba-ai/erdl-mcp@latest --upgrade # Force upgrade
npx @openoba-ai/erdl-mcp@latest --uninstall # Clean removal
npx @openoba-ai/erdl-mcp@latest --setup # Show MCP config
npx @openoba-ai/erdl-mcp@latest --help # Full usage
```
---
## From Source
```bash
git clone https://github.com/OpenOBA/erdl-mcp-server.git
cd erdl-mcp-server
npm install
npm run build
npm test # 92 tests
node bin/erdl-mcp.js
```
---
## Contributing
ERDL MCP Server is MIT-licensed and open to contributions. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
---
## Star History
If ERDL helps your workflow, [give us a β on GitHub](https://github.com/OpenOBA/erdl-mcp-server) β it helps others discover the project.
[](https://star-history.com/#OpenOBA/erdl-mcp-server&Date)
---
## License
MIT Β· [OpenOBA](https://openoba.com) Β· [@OpenOBA](https://github.com/OpenOBA)
> Deterministic architecture, not prompt engineering.
TDQS
A4.3/5.0
Scored across 5 tools
Disambiguation5/5
Each tool has a clearly distinct purpose: create, evaluate, explain, list, simulate. No overlap or ambiguity between them.
Naming Consistency5/5
All tools use a consistent 'erdl_' prefix and verb-based naming (e.g., create_rule, evaluate, explain, list_rules, simulate). Minor variation in noun inclusion is acceptable.
Tool Count5/5
5 tools is well-scoped for a rule management server. Each tool covers a necessary function without redundancy or bloat.
Completeness3/5
The tool set covers creation, evaluation, explanation, listing, and simulation, but lacks update and delete capabilities for rules, which are notable gaps for a rule management system.
Maintenance
ActivityStale
ResponsivenessNo issues