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.
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.
Deduction is delegated to a deterministic engine. The same knowledge base plus the same query always yields the same answer.
Every conclusion comes with a formal derivation chain. Rule IDs surface in proofs, so a decision can be cited: "derived from rule RBAC-0043."
Semantic search finds similar documents; rule enforcement needs the exact logical chain. Encode policies once, derive answers forever.
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
{
"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.
$ 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]
# 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)"}'
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.
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β¦"
}
Not just deduction β a complete lifecycle: validate, reason, explain, diagnose, explore scenarios.
reasonMain deduction β solutions with variable bindings and proof trees.
explainNatural-language reasoning steps derived deterministically from the proof tree. No LLM involved.
diagnoseWhy does a query succeed or fail? Missing facts, missing rules, what would make it true.
what_ifApply modifications to a KB and compare results before touching production.
check_kbValidate consistency before reasoning; returns the predicate inventory as an extraction contract.
register_kbRegister a knowledge base once under a kb_id; reference it by name on every call.
unregister_kbRemove a named KB from the registry.
list_kbsList registered KBs with metadata: hash, version, fact/rule counts.
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.
Every result carries content_hash (sha256 of the exact KB text) and version β pin any answer to the precise knowledge it was computed from.
Instances share nothing: run any number behind a load balancer with zero session affinity. One persistent engine per instance serves many requests cheaply.
SWI-Prolog β 35+ years of continuous development β does the heavy lifting, behind a clean intermediate language.
Real euclid-cli sessions, unedited. Facts in, proof trees out β every step deterministic, every conclusion auditable.
Who can deploy to production? Roles, clearance levels and an arithmetic check chained into one derivation β with the full proof tree.
bob is denied. Why not? The diagnosis pinpoints the gap, and a hypothetical role grant flips the answer from 0 to 1 solution.
SEC-042 denies the vault to suspended users. carol fails, dave passes β and the explanation cites the rule by ID for audit.
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.
| Metric | 8B alone | 480B cloud | 8B + Euclid-MCP |
|---|---|---|---|
| Accuracy (RBAC, 1000+ facts) | 2 / 5 | 2 / 5 | 5 / 5 |
| Avg response time | 6,966 ms | 3,695 ms | 963 ms |
| Avg output tokens | 165 | 212 | 12 |
On small tasks (5β50 facts) all configurations score 5/5 β scale is where probabilistic reasoning breaks. Full methodology: benchmark reports.
Access decisions with inheritance and separation of duties β each grant provable down to the source rule.
CIS controls, company policies, EU AI Act classifications. Ship the policy as data, not as if/else chains.
Loan approval, benefits, licensing β auditable outcomes instead of opaque model judgments.
Offload deduction from 3β8B edge models to the engine; run serious reasoning on modest hardware.
Agents self-correct: diagnose tells them why a query failed, what_if lets them test repairs safely.
Interactive logic tutoring with visible proof chains β see exactly how a conclusion was reached.
Native tool server for any MCP client.
REST endpoints, Prometheus metrics, health checks β production-ready.
Scriptable batch mode and an interactive Euclid-IR shell.
Import the tools directly into your application.