LLMs describe.
Euclid proves.

An open-source MCP server for deterministic logical reasoning. A lightweight LLM describes the world as facts and rules in Euclid-IR; a Prolog-backed engine performs the deduction β€” and every answer ships with a proof tree you can trace, cite, and audit.

pip install euclid-mcp
Get started Read the paper
PyPI version Python versions License CI
The problem

Your agent is guessing. Make it prove its answers.

LLMs process information statistically, not logically. Ask one to evaluate access policies across hundreds of records and it hallucinates systematically β€” wrong counts, missed conflicts, fabricated permissions. For rules that matter, "approximately correct" isn't correct.

🎲

No more hallucinated logic

Deduction is delegated to a deterministic engine. The same knowledge base plus the same query always yields the same answer.

🌳

Proof trees, not vibes

Every conclusion comes with a formal derivation chain. Rule IDs surface in proofs, so a decision can be cited: "derived from rule RBAC-0043."

πŸ”

RAG retrieves. Euclid derives.

Semantic search finds similar documents; rule enforcement needs the exact logical chain. Encode policies once, derive answers forever.

Get started

Up and running in two minutes

Install

pip install euclid-mcp           # MCP server + CLI/REPL β€” pure Python, works out of the box

# Suggested for best performance (optional): without it, a built-in pure-Python engine takes over.
brew install swi-prolog          # apt install swi-prolog Β· choco install swi-prolog

Use via MCP β€” Claude Desktop, OpenCode, Cursor, …

{
  "mcpServers": {
    "euclid-mcp": { "command": "euclid-mcp" }
  }
}

The euclid-mcp executable ships with the pip package β€” no paths or working directory needed. Running from source instead? Use "command": "python3", "args": ["-m", "euclid_mcp"] with cwd set to the repo.

Or try the interactive REPL β€” included in the same pip package

$ euclid-cli
Euclid-MCP REPL β€” type facts and rules in Euclid-IR, then `? query`.
euclid > human(socrates)
euclid > mortal($x) IF human($x)
euclid > ? mortal($who)
Solution 1:
  who: socrates
mortal(socrates)  [rule]
  human(socrates)  [fact]

Or call the HTTP API from n8n, Zapier, Make, curl…

# Start the API server once β€” from a clone:
git clone https://github.com/meob/Euclid-MCP && cd Euclid-MCP
python3 integrations/euclid_api.py --port 8080
# …or with Docker (bundles SWI-Prolog): docker compose up euclid-api

# …then call it:
curl -X POST http://localhost:8080/reason \
  -H "Content-Type: application/json" \
  -d '{"knowledge": "human(socrates)\nmortal($x) IF human($x)\n? mortal($who)"}'
Architecture

How it works

The LLM never reasons β€” it only describes. All deduction happens outside the model, which is why a local 8B model can outperform 400B+ cloud models on reasoning tasks.

LLM / AgentMCP client
(Claude, OpenCode, Cursor…)
β†’
Euclid-MCP8 reasoning tools
over MCP / HTTP / CLI
β†’
TranslatorEuclid-IR β†’ Prolog
+ meta-interpreter
β†’
Solutions + Proof treesstructured JSON,
deterministic
The language

Euclid-IR β€” logic without the Prolog syntax

A declarative intermediate representation designed for both humans and LLMs: variables start with $, implication is IF, conjunction is AND.

# Facts
parent(tom, bob)
parent(bob, ann)

# Rules (recursion is fine)
ancestor($x, $y) IF parent($x, $y)
ancestor($x, $y) IF parent($x, $z) AND ancestor($z, $y)

# Audit-trail ID on any rule
can_deploy($user) IF
    user($user) AND
    has_role($user, deployer)  # RULE: DEPLOY-POL-1

# Arithmetic & negation
stale($u) IF last_login($u, $d) AND $d > 90
blocked($u) IF NOT active($u)

# Query
? ancestor(tom, $who)
{
  "query": "ancestor(tom, $who)",
  "solutions": [
    {
      "substitutions": { "who": "bob" },
      "proof": {
        "type": "rule",
        "goal": "ancestor(tom, bob)",
        "rule_id": null,
        "subproof":
          { "type": "fact",
            "goal": "parent(tom, bob)" }
      }
    },
    { "substitutions": { "who": "ann" }, "proof": { … } }
  ],
  "elapsed_ms": 12.4,
  "content_hash": "a3f9c1e4…"
}
Horn-clause core Negation (NOT) Arithmetic comparisons Rule IDs for audits @version directives String literals YAML format too .euclid files
Tooling

Eight tools, one purpose

Not just deduction β€” a complete lifecycle: validate, reason, explain, diagnose, explore scenarios.

reason

Main deduction β€” solutions with variable bindings and proof trees.

explain

Natural-language reasoning steps derived deterministically from the proof tree. No LLM involved.

diagnose

Why does a query succeed or fail? Missing facts, missing rules, what would make it true.

what_if

Apply modifications to a KB and compare results before touching production.

check_kb

Validate consistency before reasoning; returns the predicate inventory as an extraction contract.

register_kb

Register a knowledge base once under a kb_id; reference it by name on every call.

unregister_kb

Remove a named KB from the registry.

list_kbs

List registered KBs with metadata: hash, version, fact/rule counts.

Token efficiency

Load the rules once. Query them forever.

Complex business rules don't belong in a prompt. Preload a KB at server startup (EUCLID_KB_PATH) or register it under a kb_id β€” then each request carries only session-specific facts via delta_knowledge. Small models can reason over large rule sets without ever seeing the whole thing.

Auditable by construction

Every result carries content_hash (sha256 of the exact KB text) and version β€” pin any answer to the precise knowledge it was computed from.

Stateless & scalable

Instances share nothing: run any number behind a load balancer with zero session affinity. One persistent engine per instance serves many requests cheaply.

Battle-tested backend

SWI-Prolog β€” 35+ years of continuous development β€” does the heavy lifting, behind a clean intermediate language.

Demos

See it in action

Real euclid-cli sessions, unedited. Facts in, proof trees out β€” every step deterministic, every conclusion auditable.

RBAC session: who can deploy to prod, with proof tree

Multi-hop RBAC

Who can deploy to production? Roles, clearance levels and an arithmetic check chained into one derivation β€” with the full proof tree.

Diagnose why bob cannot deploy, then enable it with what-if

Diagnose & what-if

bob is denied. Why not? The diagnosis pinpoints the gap, and a hypothetical role grant flips the answer from 0 to 1 solution.

Security rule SEC-042 blocks a suspended user via negation

Negation as failure

SEC-042 denies the vault to suspended users. carol fails, dave passes β€” and the explanation cites the rule by ID for audit.

Evidence

An 8B model beats a 480B cloud model

Large-scale RBAC task over 1,000+ facts with role hierarchies and separation-of-duties constraints. Both LLMs alone fail systematically; the 8B model augmented with Euclid-MCP answers everything, faster and cheaper.

Metric8B alone480B cloud8B + Euclid-MCP
Accuracy (RBAC, 1000+ facts)2 / 52 / 55 / 5
Avg response time6,966 ms3,695 ms963 ms
Avg output tokens16521212

On small tasks (5–50 facts) all configurations score 5/5 β€” scale is where probabilistic reasoning breaks. Full methodology: benchmark reports.

Applications

Built for rules that matter

πŸ” RBAC & IAM

Access decisions with inheritance and separation of duties β€” each grant provable down to the source rule.

πŸ“‹ Compliance automation

CIS controls, company policies, EU AI Act classifications. Ship the policy as data, not as if/else chains.

🏦 Eligibility engines

Loan approval, benefits, licensing β€” auditable outcomes instead of opaque model judgments.

🧠 Small-model reasoning

Offload deduction from 3–8B edge models to the engine; run serious reasoning on modest hardware.

🧩 Agentic pipelines

Agents self-correct: diagnose tells them why a query failed, what_if lets them test repairs safely.

πŸŽ“ Education

Interactive logic tutoring with visible proof chains β€” see exactly how a conclusion was reached.

Ecosystem

Consume it your way

MCP stdio

Native tool server for any MCP client.

HTTP API

REST endpoints, Prometheus metrics, health checks β€” production-ready.

CLI + REPL

Scriptable batch mode and an interactive Euclid-IR shell.

Python API

Import the tools directly into your application.