Kremis
Servidor MCP de grafo de conocimiento determinista. Binario único, sin LLM en el bucle.
Documentación
Kremis
Un servidor MCP de grafo de conocimiento determinista. Local, un solo binario, sin LLM en el bucle.
Un sustrato cognitivo mínimo basado en grafos, escrito en Rust.
Registra, asocia, recupera — pero nunca inventa.
Alfa — Funcional y probado. Pueden ocurrir cambios disruptivos antes de v1.0.
Por qué Kremis
| Problema | Cómo lo aborda Kremis |
|---|---|
| Alucinación | Cada resultado se remonta a una señal real ingerida. Los datos faltantes devuelven explícitamente "no encontrado" — nunca fabricado |
| Opacidad | Estado del grafo totalmente inspeccionable. Sin capas ocultas, sin caja negra |
| Falta de fundamentación | Cero conocimiento precargado. Toda la estructura surge de señales reales, no de suposiciones |
| No determinismo | Misma entrada, misma salida. Sin aleatoriedad, sin aritmética de coma flotante en el núcleo |
| Pérdida de datos | Transacciones ACID mediante base de datos embebida redb. Seguro ante fallos por diseño |
Filosofía de diseño — por qué existen estas restricciones.
Características
- Motor de grafo determinista — Rust puro, sin async en el núcleo, sin coma flotante. La misma entrada siempre produce la misma salida
- CLI + API HTTP + puente MCP — Tres interfaces para el mismo motor: terminal, REST y asistentes de IA
- Hash BLAKE3 — Hash criptográfico del estado completo del grafo para verificación de integridad en cualquier punto
- Exportación canónica (KREX) — Instantánea binaria determinista para procedencia, pistas de auditoría y reproducibilidad
- Conocimiento con prueba (KVQC) —
POST /certifydevuelve un Certificado de Consulta Verificable reproducible: una prueba portable de un hecho, o prueba de su ausencia - Cero conocimiento incorporado — Kremis comienza vacío. Cada nodo proviene de una señal real
- Persistencia ACID — Backend
redbpredeterminado con transacciones seguras ante fallos
Casos de uso
Memoria de agentes de IA mediante MCP
Dale a Claude, Cursor o cualquier asistente compatible con MCP una capa de memoria verificable. Kremis almacena hechos como nodos del grafo — el agente los consulta, y cada respuesta se remonta a un punto de datos real. Sin embeddings, sin recuperación probabilística.
Verificación de hechos para LLM
Ingiere tus datos, deja que un LLM genere afirmaciones y luego verifica cada afirmación contra el grafo. Cada respuesta lleva un campo grounding — fact, inference o unknown — y POST /certify convierte un unknown en un certificado vinculado a un hash BLAKE3 del estado del grafo. Sin puntuaciones de confianza, sin ambigüedad.
Procedencia y pista de auditoría
Exporta el grafo completo como una instantánea binaria determinista, calcula su hash BLAKE3 y verifica la integridad en cualquier punto. Cada nodo enlaza con la señal que lo creó. Útil para flujos de cumplimiento donde necesitas demostrar qué datos estaban presentes y cuándo.
Benchmark de fabricación
Un registro cerrado de 9 servicios ficticios y 5 dependencias unidireccionales. 24 preguntas de
la forma "¿depende A de B, directa o transitivamente?" — 8 tienen respuesta, 16 no
la tienen, y no existe respuesta para ellas en ningún lugar. Nada en el prompt pide a ningún
modelo que invente: los hechos se proporcionan y se ofrece UNKNOWN.
qwen3.5:4b, temperatura 0, 5 ejecuciones:
| Sistema | Afirmación falsa | Precisión de respuesta |
|---|---|---|
Kremis (/query + /certify) | 0,00 % | 100 % |
| LLM con el registro completo | 0,00 % | 100 % |
| LLM + recuperación ingenua | 0,00 % | 75 % |
| LLM, sin contexto | 0,00 % | 0 % |
En un mundo tan pequeño, un modelo capaz no fabrica: dado todos los hechos que necesita,
qwen3.5:4b coincide con el sustrato aquí, respondiendo las 8 preguntas respondibles y
absteniéndose en las 16 que no tienen respuesta. Pero la capacidad no es gratuita según el año en la
ficha del modelo — phi4-mini, un 4B local actual de otro laboratorio, mantiene el
registro idéntico y aun así afirma marn-ledger -> quoll-auth, la inversa de una
dependencia declarada, en cada ejecución (12,50 %). Qué modelo ejecutas ya lo decide. Kremis almacena
las dependencias como aristas unidireccionales, por lo que un camino inverso no existe para encontrarlo: devuelve
grounding: "unknown" y /certify emite un certificado sin evidencia, vinculado a
un hash BLAKE3 del estado del grafo. El cero es estructural, no medido — y el
fallo interesante es el horizonte largo a continuación.
Tampoco es una carrera comparable, y no debe leerse como tal. El LLM recibe
inglés y tiene que encontrar los servicios por sí mismo; Kremis recibe strongest_path(42, 87) con
los ids ya resueltos. Un grafo de aristas unidireccionales no puede fabricar una arista — decirlo
no prueba nada. Lo que no es gratuito es el certificado: una ausencia vinculada a un hash, que
alguien más puede verificar sin confiar en el sistema que lo emitió.
La fila inferior es el control: un modelo que responde UNKNOWN a todo no fabrica
nada y es inútil. La abstención cuenta solo junto con la precisión.
python benchmark/run.py --model qwen3.5:4b --runs 5
python benchmark/run.py --skip-llm # Kremis alone, no Ollama needed
Así que en la búsqueda, los modelos capaces (qwen3.5:4b, gemma4) obtienen 0 mientras que un
4B actual más débil (phi4-mini) aún inventa. El mundo base separa a los capaces de los débiles — por lo
que el benchmark incluye un segundo, donde la respuesta ya no cabe en un vistazo e incluso
los modelos capaces comienzan a fallar.
Horizonte largo
420 servicios, 330 dependencias unidireccionales, y la respuesta es una composición de hasta 10
pasos. Las 60 preguntas sin respuesta vienen en dos trampas, 30 cada una: una cadena con exactamente
un enlace retenido (N-1 de los N enlaces declarados, uno faltante — sin cadena), y una cadena
intacta preguntada al revés (las dependencias son unidireccionales, por lo que la inversa no tiene respuesta). El
modelo recibe las 330 dependencias de todos modos — lo que falta falta en el mundo,
no en el contexto.
Temperatura 0, 60 preguntas sin respuesta, cada modelo con el registro completo:
Dos modelos locales que realmente ejecutarías, dos alojados en los extremos de la frontera:
| Sistema | Afirmación falsa | Precisión de respuesta |
|---|---|---|
Kremis (/query + /certify) | 0,00 % | 100 % |
gemma4 (alojado) | 0,00 % | 100 % |
qwen3.5:4b (local) | 3,33 % | 20 % |
phi4-mini (local) | 1,67 % | 6,67 % |
llama-3.3-70b (alojado) | 61,67 % | 100 % |
Lee la segunda fila antes que la última. A julio de 2026, un modelo de frontera coincide con Kremis en cada columna de este benchmark — por lo que "los LLM fabrican y Kremis no" no es una afirmación que este proyecto haga en tiempo presente. Lo que queda es más estrecho: que el cero es una ejecución, y llega sin nada que puedas verificar. El de Kremis es una propiedad de un grafo de aristas unidireccionales, y certifica las 60 ausencias contra un hash de estado BLAKE3.
La capacidad tampoco es uniforme — llama-3.3-70b (Meta, vía NVIDIA) inventa 37 de las
60 cadenas mientras responde todas las reales, y los dos modelos locales 4B fabrican menos pero
aun así fabrican (qwen3.5:4b 3,33 %, phi4-mini 1,67 %) mientras responden casi nada.
Ninguno te da una forma de saber qué respuesta acabas de recibir.
Una advertencia es nuestra, no suya: 420 servicios son ~6,6k tokens, por lo que el mundo completo cabe
en el prompt. Ese es el único régimen donde un LLM puede competir en esta tarea.
--scale lo deja — las preguntas permanecen idénticas y solo crece el prompt.
Y esto importa. En --scale 3000 (57k tokens de prompt) gemma4 fabrica 1 / 60
donde fabricó 0 / 60 en el tamaño predeterminado; el qwen3.5:4b local en
--scale 500 en cambio responde menos preguntas (precisión 20 % → 13,33 %) sin inventar
más. Los LLM se mueven con la escala, en direcciones diferentes; la paridad en la tabla anterior es
una propiedad de un mundo pequeño, no del modelo. Kremis es 0 / 60 con 100 % de precisión en
cada escala medida.
python benchmark/run.py --world horizon
Las advertencias, el contraexperimento, el ruido en la curva y la verdad fundamental están en
benchmark/README.md.
Inicio rápido
Requiere Rust 1.89+ y Cargo.
git clone https://github.com/TyKolt/kremis.git
cd kremis
cargo build --release
cargo test --workspace
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
En una segunda terminal:
curl http://localhost:8080/health
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{"type":"lookup","entity_id":1}'
Nota: Los comandos CLI y el servidor HTTP no pueden ejecutarse simultáneamente (
redbmantiene un bloqueo exclusivo). Detén el servidor antes de usar comandos CLI.
Docker
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
Arquitectura
| Componente | Descripción |
|---|---|
| kremis-core | Motor de grafo determinista (Rust puro, sin async) |
| apps/kremis | Servidor HTTP + CLI (tokio, axum, clap) |
| apps/kremis-mcp | Puente de servidor MCP para asistentes de IA (rmcp, stdio) |
Consulta la documentación de arquitectura para los detalles internos: flujo de datos, backends de almacenamiento, algoritmos, formatos de exportación.
Documentación
Referencia completa en kremis.mintlify.app:
| Tema | Enlace |
|---|---|
| Introducción | kremis.mintlify.app/introduction |
| Instalación | kremis.mintlify.app/installation |
| Inicio rápido | kremis.mintlify.app/quickstart |
| Configuración | kremis.mintlify.app/configuration |
| Referencia CLI | kremis.mintlify.app/cli/overview |
| Referencia de API | kremis.mintlify.app/api/overview |
| Servidor MCP | kremis.mintlify.app/mcp/overview |
| Filosofía | kremis.mintlify.app/philosophy |
| El nombre | kremis.mintlify.app/the-name |
Pruebas
cargo test --workspace
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all -- --check
Benchmarks
Generados automáticamente en runners de CI — 2026-08-18.
| Operación | Linux | Windows | macOS |
|---|---|---|---|
| Inserción de nodos (100K) | 22,93 ms ±0,26 | 18,86 ms ±1,10 | 17,43 ms ±1,04 |
| Ingestión de señales (lote de 10K) | 8,69 ms ±0,15 | 12,21 ms ±1,46 | 6,65 ms ±0,22 |
| Recorrido de grafo (profundidad 50, 1K nodos) | 2,8 µs ±0,0 | 3,4 µs ±0,2 | 2,2 µs ±0,1 |
| Camino más fuerte (1K nodos) | 8,1 µs ±0,0 | 8,5 µs ±0,2 | 6,5 µs ±0,4 |
| Exportación canónica (1K nodos) | 72,4 µs ±0,4 | 75,6 µs ±1,4 | 55,7 µs ±2,7 |
| Importación canónica (10K nodos) | 3,20 ms ±0,07 | 3,61 ms ±0,18 | 2,83 ms ±0,16 |
| Inserción de nodos Redb (1K) | 355,88 ms ±14,08 | 16,3 s ±0,6 | 500,28 ms ±165,97 |
El ± es la desviación de criterion dentro de una sola ejecución. La dispersión entre ejecuciones en CI alojado es aún mayor, porque los propios runners varían: las cifras aquí se han movido en decenas de porcentaje sin cambios en el código evaluado. Léelas como órdenes de magnitud, no como una señal de regresión.
Licencia
Los activos de marca en docs/logo/ (logotipo, icono, favicon) son propietarios y no están cubiertos por la licencia Apache 2.0. Consulta docs/logo/LICENSE.
Contribuciones
Consulta CONTRIBUTING.md para las pautas. La arquitectura aún está evolucionando — abre un issue antes de enviar un PR.
Agradecimientos
Este proyecto fue desarrollado con asistencia de IA.
Mantenlo mínimo. Mantenlo determinista. Mantenlo fundamentado. Mantenlo honesto.