trackmcp
Back to directory

A minimal graph engine for grounded AI — records, associates, and retrieves, but never invents. Written in Rust.

14 stars RustOthers Updated Aug 24, 2026
deterministicrustembedded-databaseexplainable-aigraph-databasemcpaigraph-enginegrounded-aiknowledge-graphmodel-context-protocolai-agentsanti-hallucinationclillm

Documentation

Kremis

A deterministic knowledge graph MCP server. Local, single binary, no LLM in the loop.

A minimal, graph-based cognitive substrate in Rust.

Records, associates, retrieves — but never invents.

> Alpha — Functional and tested. Breaking changes may still occur before v1.0.


Why Kremis

ProblemHow Kremis addresses it
HallucinationEvery result traces back to a real ingested signal. Missing data returns explicit "not found" — never fabricated
OpacityFully inspectable graph state. No hidden layers, no black box
Lack of groundingZero pre-loaded knowledge. All structure emerges from real signals, not assumptions
Non-determinismSame input, same output. No randomness, no floating-point arithmetic in core
Data lossACID transactions via `redb` embedded database. Crash-safe by design

> Design Philosophy — why these constraints exist.


Features

  • Deterministic graph engine — Pure Rust, no async in core, no floating-point. Same input always produces the same output
  • CLI + HTTP API + MCP bridge — Three interfaces to the same engine: terminal, REST, and AI assistants
  • BLAKE3 hashing — Cryptographic hash of the full graph state for integrity verification at any point
  • Canonical export (KREX) — Deterministic binary snapshot for provenance, audit trails, and reproducibility
  • Proof-carrying knowledge (KVQC) — `POST /certify` returns a reproducible Verifiable Query Certificate: a portable proof of a fact, or proof of its absence
  • Zero baked-in knowledge — Kremis starts empty. Every node comes from a real signal
  • ACID persistence — Default `redb` backend with crash-safe transactions

Use Cases

AI agent memory via MCP

Give Claude, Cursor, or any MCP-compatible assistant a verifiable memory layer. Kremis stores facts as graph nodes — the agent queries them, and every answer traces back to a real data point. No embeddings, no probabilistic retrieval.

LLM fact-checking

Ingest your data, let an LLM generate claims, then check each claim against the graph. Every response carries a `grounding` field — `fact`, `inference`, or `unknown` — and `POST /certify` turns an `unknown` into a certificate bound to a BLAKE3 hash of the graph state. No confidence scores, no ambiguity.

Provenance and audit trail

Export the full graph as a deterministic binary snapshot, compute its BLAKE3 hash, and verify integrity at any point. Every node links to the signal that created it. Useful for compliance workflows where you need to prove what data was present and when.


Fabrication Benchmark

A closed registry of 9 fictional services and 5 one-way dependencies. 24 questions of

the form *"does A depend on B, directly or transitively?"* — 8 have an answer, 16 do

not, and no answer exists for them anywhere. Nothing in the prompt asks any model to

invent: the facts are supplied and `UNKNOWN` is offered.

`qwen3.5:4b`, temperature 0, 5 runs:

SystemFalse assertionAnswer accuracy
Kremis (`/query` + `/certify`)0.00 %100 %
LLM holding the entire registry0.00 %100 %
LLM + naive retrieval0.00 %75 %
LLM, no context0.00 %0 %

On a world this small a *capable* model does not fabricate: given every fact it needs,

`qwen3.5:4b` matches the substrate here, answering all 8 answerable questions and

abstaining on the 16 that have no answer. But capability is not free with the year on the

model card — `phi4-mini`, a current local 4B from another lab, holds the identical

registry and still asserts `marn-ledger -> quoll-auth`, the reverse of a stated

dependency, on every run (12.50 %). Which model you run already decides it. Kremis stores

dependencies as one-way edges, so a reverse path is not there to find: it returns

`grounding: "unknown"` and `/certify` issues a certificate carrying no evidence, bound to

a BLAKE3 hash of the graph state. The zero is structural, not measured — and the

interesting failure is the long horizon below.

It is also not a like-for-like race, and should not be read as one. The LLM gets

English and has to find the services itself; Kremis gets `strongest_path(42, 87)` with

the ids already resolved. A graph of one-way edges cannot fabricate an edge — saying so

proves nothing. What is not free is the certificate: an absence bound to a hash, which

someone else can check without trusting the system that issued it.

The bottom row is the control: a model that answers `UNKNOWN` to everything fabricates

nothing and is useless. Abstention counts only alongside accuracy.

bash
python benchmark/run.py --model qwen3.5:4b --runs 5
python benchmark/run.py --skip-llm              # Kremis alone, no Ollama needed

So on the lookup the capable models (`qwen3.5:4b`, `gemma4`) score 0 while a weaker

current 4B (`phi4-mini`) still invents. The base world separates capable from weak — so

the benchmark ships a second one, where the answer no longer fits in a glance and even

the capable models start to fail.

Long horizon

420 services, 330 one-way dependencies, and the answer is a composition of up to 10

steps. The 60 questions with no answer come in two traps, 30 each: a chain with exactly

one link withheld (`N-1` of the `N` links stated, one missing — no chain), and an intact

chain asked backwards (dependencies are one-way, so the reverse has no answer). The

model is handed all 330 dependencies anyway — what is missing is missing *in the world*,

not in the context.

Temperature 0, 60 questions with no answer, each model holding the entire registry:

Two local models you would actually run, two hosted at the extremes of the frontier:

SystemFalse assertionAnswer accuracy
Kremis (`/query` + `/certify`)0.00 %100 %
`gemma4` (hosted)0.00 %100 %
`qwen3.5:4b` (local)3.33 %20 %
`phi4-mini` (local)1.67 %6.67 %
`llama-3.3-70b` (hosted)61.67 %100 %

Read the second row before the last. As of July 2026 a frontier model matches

Kremis on every column of this benchmark — so "LLMs fabricate and Kremis doesn't" is

not a claim this project makes in the present tense. What is left is narrower: that

zero is one execution, and it arrives with nothing you can check. Kremis's is a

property of a graph of one-way edges, and it certifies all 60 absences against a

BLAKE3 state hash.

Capability is also not uniform — `llama-3.3-70b` (Meta, via NVIDIA) invents 37 of the

60 chains while answering every real one, and the two local 4B models fabricate less but

still fabricate (`qwen3.5:4b` 3.33 %, `phi4-mini` 1.67 %) while answering almost nothing.

None of them gives you a way to tell which answer you just got.

One caveat is ours, not theirs: 420 services is ~6.6k tokens, so the whole world fits

in the prompt. That is the single regime where an LLM can compete on this task at all.

`--scale` leaves it — the questions stay identical and only the prompt grows.

And it matters. At `--scale 3000` (57k prompt tokens) `gemma4` fabricates 1 / 60

where it fabricated 0 / 60 at the default size; the local `qwen3.5:4b` at

`--scale 500` instead answers *fewer* questions (accuracy 20 % → 13.33 %) without inventing

more. The LLMs move with scale, in different directions; the parity in the table above is

a property of a small world, not of the model. Kremis is `0 / 60` with 100 % accuracy at

every scale measured.

bash
python benchmark/run.py --world horizon

Caveats, the counter-experiment, the noise in the curve, and the ground truth are in

`benchmark/README.md`.


Quick Start

Requires Rust 1.89+ and Cargo.

bash
git clone https://github.com/TyKolt/kremis.git
cd kremis
cargo build --release
cargo test --workspace
bash
cargo run -p kremis -- init                                          # initialize database
cargo run -p kremis -- ingest -f examples/sample_signals.json -t json # ingest sample data
cargo run -p kremis -- server                                        # start HTTP server

In a second terminal:

bash
curl http://localhost:8080/health
curl -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"type":"lookup","entity_id":1}'

> Note: CLI commands and the HTTP server cannot run simultaneously (`redb` holds an exclusive lock). Stop the server before using CLI commands.

Docker

bash
docker build -t kremis .

# MCP server (default) — pipe MCP stdio JSON-RPC; suitable for any MCP client
docker run -i --rm kremis

# HTTP API only — override the entrypoint
docker run -d -p 8080:8080 -v kremis-data:/data \
  --entrypoint kremis kremis server -H 0.0.0.0 -D /data/kremis.db

Architecture

ComponentDescription
kremis-coreDeterministic graph engine (pure Rust, no async)
apps/kremisHTTP server + CLI (tokio, axum, clap)
apps/kremis-mcpMCP server bridge for AI assistants (rmcp, stdio)

See the architecture docs for internals: data flow, storage backends, algorithms, export formats.


Documentation

Full reference at **kremis.mintlify.app**:


Testing

bash
cargo test --workspace
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all -- --check

Benchmarks

> Auto-generated on CI runners — 2026-08-24.

OperationLinuxWindowsmacOS
Node insertion (100K)20.63 ms ±0.1823.05 ms ±1.0846.13 ms ±5.82
Signal ingestion (10K batch)8.37 ms ±0.0810.79 ms ±1.3116.38 ms ±2.43
Graph traversal (depth 50, 1K nodes)2.7 µs ±0.03.2 µs ±0.18.4 µs ±2.3
Strongest path (1K nodes)7.5 µs ±0.09.2 µs ±1.120.7 µs ±4.6
Canonical export (1K nodes)68.0 µs ±1.477.2 µs ±5.9164.1 µs ±40.0
Canonical import (10K nodes)3.09 ms ±0.033.74 ms ±0.297.11 ms ±1.24
Redb node insertion (1K)299.46 ms ±3.7716.3 s ±0.72.3 s ±0.4

> The ± is criterion's deviation within a single run. Spread *between* runs

> on hosted CI is wider still, because the runners themselves vary: figures

> here have moved by tens of percent with no change to the benched code.

> Read them as orders of magnitude, not as a regression signal.


License

Apache License 2.0

The brand assets in `docs/logo/` (logo, icon, favicon) are proprietary and not covered by the Apache 2.0 license. See `docs/logo/LICENSE`.

Contributing

See CONTRIBUTING.md for guidelines. The architecture is still evolving — open an issue before submitting a PR.

Acknowledgments

This project was developed with AI assistance.


Keep it minimal. Keep it deterministic. Keep it grounded. Keep it honest.

Frequently asked questions

What is kremis?

kremis is A minimal graph engine for grounded AI — records, associates, and retrieves, but never invents. Written in Rust.

How do I install kremis?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is kremis open source?

Yes — it is hosted on GitHub at https://github.com/TyKolt/kremis and has 14 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP