kura
蒸留蔵 — distill-kura
Una memoria a largo plazo para agentes que está destilada, no acumulada. El recuerdo funciona por significado, la escritura está controlada por evidencia, y un mismo servidor puede tener varias memorias separadas — una por cada modo de agente — de modo que cambiar de modo cambia lo que el agente recuerda.
Se distribuye como un plugin de DeepSeek Harness, un servidor MCP para cualquier otro host, un servicio HTTP y una librería de Python. Solo con la biblioteca estándar; sin base de datos vectorial, sin embeddings, sin framework.
┌── recall ──────────────────────────────────────────────┐
│ question → whole index in one prompt → picked slugs │
│ → walk [[links]] → the neighbourhood │ ~0.4 s
└────────────────────────────────────────────────────────┘
┌── distil ──────────────────────────────────────────────┐
│ journal → classed evidence → candidates → GATE │
│ → new? → composed → draft → judged → poured │
└────────────────────────────────────────────────────────┘Por qué existe esto
Dos fallos matan la memoria a largo plazo de un agente, y la matan desde lados opuestos.
Recuperar por palabra clave pierde lo que necesitabas. Una pregunta sobre “chips de inferencia SSD” no comparte ninguna palabra con una memoria titulada “ejecutando el modelo de 2.6T desde un nivel de almacenamiento SSD” — y sin embargo son el mismo tema. La búsqueda de palabras no devuelve nada; el agente responde desde la nada. La solución aquí no son los embeddings sino el reconocimiento: el índice completo (una línea por memoria, escrita como un desencadenador de reconocimiento) va en un solo prompt, y un modelo pequeño nombra lo que tiene relación con la cuestión. Un índice de ~500 memorias ocupa unos 6k tokens — un pequeño porcentaje de una ventana de contexto moderna, y se queda en la caché de prefijo.
Escribirlo todo envenena el almacén. Un agente afirma algo; el sistema de destilado registra la afirmación como un hecho; el siguiente agente lo lee como verdad absoluta y lo repite con más confianza. Ese bucle se auto-refuerza, y las instrucciones no lo detienen — eso está medido, no asumido. Así que la ruta de escritura está controlada por Python determinista: toda memoria candidata debe llevar citas que existan carácter por carácter en el material de origen, etiquetadas con su procedencia.
clase | qué es | qué autoriza |
| las palabras del propio usuario | “ellos decidieron”, “ellos pidieron” |
| salida de máquina | los números — la única fuente |
| una herramienta que fue invocada | "esto ocurrió", "esto se hizo" |
| la prosa del propio agente | un juicio, en primera persona, nunca un dato crudo |
Una cita que no se encuentra textualmente se descarta. Un candidato sin ninguna cita superviviente se elimina. Un número sin un [TOOL] que lo respalde se suprime. El texto que atribuye una decisión a la persona, si no sobrevive ninguna cita de [USER], es rechazado en la última puerta. Las ideas son bienvenidas — van a un archivo semilla, nunca al almacén, y se convierten en memoria solo cuando a evidencia posterior las confirme.
Related MCP server: Synapto
Inicio rápido
git clone https://github.com/lna-lab/distill-kura && cd distill-kura
pip install -e . # or just run: python3 -m distill_kura.cli
cp kura.example.toml kura.toml # edit: one model endpoint is enough to start
kura init main --path ~/kura/main # create an empty store
kura serve # http://127.0.0.1:8085curl -s -X POST localhost:8085/recall -H 'content-type: application/json' \
-d '{"question":"what did we decide about the archive disk?","hops":1}'Incorpora el índice para que el agente siempre sepa lo que sabe:
kura weave # build the three-layer cloth
kura prefill # the block to put in the system promptDele las transcripciones de tus agentes:
kura distill run # drink a batch → candidates → gate → drafts
kura distill drafts # look at what it wants to write
kura distill drain # the scribe re-reads each draft cold: pour / fix / toss
kura distill night # stay resident and do it whenever things go quietNada entra en el almacén hasta drain (o un pour manual). Los borradores llevan su evidencia en un comentario HTML, así siempre puedes ver por qué existe una memoria.
El mapa residente
La recuperación como herramienta responde a “¿qué sabes sobre X?” — pero solo una vez que el agente ha decidido preguntar. Nunca responde a la pregunta que el agente no piensa en hacer: ¿hay algo aquí o no? Un agente que no ve el mapa no sabe qué está perdiéndose, así que se pone a adivinar, y una suposición segura sobre tu propio contexto es exactamente la falla que este proyecto existe para prevenir.
Por eso el índice también está presente: es un bloque permanente en el prompt del sistema, en cada turno.
kura weave # re-weave the index into the three-layer cloth
kura prefill # print the block a host should injectTres capas, porque el detalle solo paga para lo reciente
Una prueba A/B a ciegas — 20 preguntas, índice amplio contra índice reducido, corregido sin saber cuál era cuál — determinó la forma:
banda | amplio | ligero |
general | 9 | 11 |
eventos recientes | 4 | 1 |
doctrina | 1 | 4 |
saltos entre dominios | 1 | 4 |
Las líneas de doctrina eran byte idénticas en los dos índices, y el índice más reducido aun así ganó esa categoría: un entorno más ligero deja ver mejor las líneas fijas. El detalle no esa fuente de comprensión. Se gana su lugar solo donde las cosas siguen en movimiento.
capa | regla | línea |
fija | el | se conserva por completo |
reciente | tocado dentro de | se conserva por completo |
disparador | todo lo demás | comprimido a |
Las líneas de activación las escribe el modelo scribe y se guardan en un registro con una clave basada en la descripción y en el presupuesto, de manera que un re-tejido en el estado estable no cueste nada. Si no hay ningún modelo disponible, el telar recorta mecánicamente en su lugar — un sistema de memoria nunca debe quedar en blanco porque una GPU se haya caído.
La edad no es el mtime. Un cp -r, una restauración o un checkout activa todas las marcas de tiempo, todo el índice se vuelve "reciente", no se descarta nada, y el mecanismo se ha deshabilitado silenciosamente. Por eso el telar prefiere una fecha escrita dentro de la memoria, y rechaza cualquier mtime que una quinta parte del almacén esté compartiendo con el mismo día del calendario.
Dónde va y por qué es una decisión sobre la caché
- id: kura
name: distill-kura
config: { store: eq, promptOrder: -50 } # before the personaUna caché de prefijo se pierde desde el primer byte que cambia — como se midió en un servidor local: un preámbulo idéntico de 4.029 tokens cambia de 0.68 s a 0.14 s, añadir al final sigue siendo 0.14 s, y añadir una palabra al principio cuesta toda la caché (0.66 s). La persona que usa el sistema suele tener un reloj, así que cambia cada minuto; el mapa es el bloque más grande del prompt y cambia un puñado de veces al año. Lo grande y estable va delante de lo que da tic y tac.
Por eso el bloque no contiene fecha, ni hora, ni contador — y build() rechaza un encabezado que la tuviera, en tiempo de construcción y no a través de turnos misteriosamente lentos tres semanas después.
Nunca entrega medio mapa
situación | qué recibe el agente |
todo está bien | el mapa completo, entre los marcadores |
se supera | todo el mapa, y una advertencia en el JSON (nunca en texto, porque un banner es contenido volátil) |
se supera | un stub sin líneas de índice, que dice que el mapa falta, no no que está vacío |
kura inaccesible | una nota explícita de que el mapa falta, nunca una cadena vacía |
Un mapa truncado es el peor artefacto posible: parece completo, y cualquier memoria que quede por debajo del corte aparentemente no existir. weave acortará la ventana de frescos para que quepa, pero nunca eliminará una línea; y si ningún ajuste llega al presupuesto, lo dice, y mantiene el mejor mapa que pueda y indica dónde está el peso.
Cómo integrarlo en un host
Host | Uso/Téc de implementación |
DSH | plugin nativo — un |
Claude Code, VS Code, Goose | El campo |
Claude Desktop, Claude.ai | ignoran por completo |
cualquier otro |
|
El campo instructions de MCP es un MAY en la especificación, y un índice de 9000 tokens no puede viajar a través de un límite de 2 KB de ningún forma, así que este proyecto no lo oculta.
Modos: más de un kura
Una sola memoria que sirve tanto para "ayúdame a construir esto" como para "ayúdame a pensar en esto" no sirve bien para ninguna de las dos: lo que te ayuda a depurar es ruido en una conversación sobre qué hacer a continuación. Por eso un almacén es un directorio, y un modo está asociado a un almacén.
[stores.maker]
path = "~/kura/maker"
label = "maker mode — building things"
[stores.eq]
path = "~/kura/eq"
label = "EQ mode — talking things through"
[modes]
maker = "maker"
eq = "eq"Cada ruta toma un selector, así que un mismo proceso puede servirlos todos:
curl -s -X POST localhost:8085/recall -d '{"question":"...","mode":"eq"}'
curl -s localhost:8085/index?store=maker
curl -s localhost:8085/s/eq/doctor # path form, for clients that only vary a base URLLos almacenes no comparten ni memorias, ni índice, ni marca de agua del destino. Cambiar de modo cambia de verdad lo que se recuerda — no es la misma memoria dicha de otra forma.
Independientes como enrutamiento, no como confidencialidad. El servidor no tiene autenticación, así que cualquier proceso que pueda llegar a su puerto puede nombrar cualquiera de los almacenes que contenga. Atar un agente mantiene a un modelo dentro de su carril; no mantiene a un proceso fuera. Hay un solo nivel de confianza por proceso; docs/TRUST.md es solo breve y vale la pena leerlo antes de poner un almacén privado. Ahí se trata también los dos límites que son fáciles de pasar por alto: dos almacenes que beben de la misma raíz del diario, y dos almacenes que están detrás de un mismo servidor de modelo.
Con DeepSeek Openark
DSH cambia la persona y las herramientas mediante el preajuste del agente. distill-kura cambia la arquitectura mediante el almacén. Visona un preajuste y todo el ser se mueve:
# .agent-presets/eq/agent.cordis.yml
- id: kura-eq
name: distill-kura
config:
url: http://127.0.0.1:8085
store: eq # this preset's memory
readonly: true # the CLIENT's own switch: do not even offer a write tool
# (the store's own `write_policy` is the authority; this just keeps the tool
# out of the model's hands. Naming a store already binds the preset.)Deja allowSwitch en su valor predeterminado y el agente también tienes kura_use, así puede desplazarse entre kura en el transcurso de la conversación sin cambiar de preajuste de herramientas: kura_recall, kura_read, kura_doctor, kura_list, kura_use y kura_remember (solo cuando el almacén es escribible). La integración completa, incluyendo el puente MCP y la regla de aislamiento del dominio isolate para filas de servicio, está en examples/pre~remote/.
La persona es asunto del anfitrión, no nuestra. Este proyecto nunca niche render ni inyecta una persona; solo registra, por almacén, qué archivo de persona le corresponde, que se puede leer en GET /profile?store=eq, para que las dos mitades puedan mantenerse en sincronía por quien controle el preajuste. Las instrucciones del agente también se quedan con el mecanismo AGENTS.md del anfitrión; ver AGENTS.md en este repo para las convenciones que debe seguir un agente que trabaja en este código.
Con cualquier host MCP
{ "mcpServers": { "kura": {
"command": "python3", "args": ["-m", "distill_kura.mcp"],
"env": { "KURA_URL": "http://127.0.0.1:8085", "KURA_STORE": "eq", "KURA_READONLY": "1" }
}}}Deje KURA_STORE libre sin configurar para el modo libre: las herramientas aceptan una store opcional, y kura_use switch de sesión.
Modelos: uno por defecto, reparto ese número a la vez
Son tres roles, no tres personas:
rol | cuándo se ejecuta | necesita * |
| cada vez que se hace una búsqueda | pequeño y rápido; debe juzgar relevancia por el significado |
| destilando: lee una edición completa del diario | longitud de contexto y paciencia |
| destilando: escribe el recuerdo y luego juzga los conocimientos | buena prosa en tu idioma y buen juicio |
Declara solo [models.thinker] y un solo modelo se queda con los tres roles. Eleva de nivel a cualquiera de los otros dos independientemente — un modelo local más grande, o una API en línea (cualquiera compatible con /chat/completions; la clave se lee de una variable de entorno que tú nombre, no se guarda nunca en la configuración):
[models.thinker] # always-on, local, small
url = "http://127.0.0.1:8000/v1"
model = "local-small"
[models.scribe] # upgrade just the writing
url = "https://api.example.com/v1"
model = "big-model"
api_key_env = "EXAMPLE_API_KEY"Dos cosas que este sistema maneja por ti: los dialectos de esfuerzo de razonamiento difieren por familia de modelos (reasoning_effort, thinking_effort, enable_thinking), así que se envían todos — las desconocidas se ignoran en la plantilla, y un modelo que por defecto queda en el modo de pensamiento profundo puede gastar todo su presupuesto en razonar y no devolver nada. Also el texto de la carta se coloca idéntico byte a byte al frente del prompt de cada rol, de manera que en un modelo local lento los tres model usen una sola caché de prefijo en lugar de hacer tres prefijos diferencias.
Si el pensador está caído, recall no se queda en silencio — recurre a la superposición
de palabras y etiqueta la respuesta como how=words, que las herramientas muestran como
⚠ degraded. La degradación silenciosa es peor que la degradación.
Cómo es una memoria
Un archivo, un hecho.
---
name: archive-on-slow-disk
description: the archive lives on the slow disk; the fast one stays scratch
metadata:
type: project # user | feedback | project | reference
---
The archive goes on the slow disk. The fast disk is scratch space.
**Why:** the other way round burns write endurance for nothing.
**How to apply:** check which disk a target directory is on before writing there.
Related: [[disk-layout]]Y una línea en MEMORY.md:
- [Archive on the slow disk](archive-on-slow-disk.md) — the archive lives on the slow disk; the fast one stays scratchEsa línea es lo único que se lee absolutamente siempre. Es un disparador de
reconocimiento, no un resumen: nombres propios, números, ⚠️ minas, la conclusión
alcanzada. Si una línea pudiera intercambiarse con la línea de otra memoria y seguir
leyéndose bien, no está haciendo su trabajo — kura distill tidy encuentra los casos
mecánicamente detectables y los reescribe.
kura doctor informa de recuentos, enlaces muertos, islas (memorias a las que nada
enlaza) y deriva del índice. Es el ojo que el metabolismo necesita.
La superficie HTTP
ruta | qué hace |
|
|
|
|
| el índice sin procesar |
| el bloque residente, listo para inyectar ( |
| una memoria completa |
| salud de un almacén ( |
| almacenes, modos y qué modelo desempeña cada rol |
| la carta del almacén y un puntero a su persona (nunca se renderiza aquí) |
| disponibilidad |
Cualquier ruta acepta ?store= / ?mode=, un campo store/mode en el cuerpo, o el
prefijo de ruta /s/<name>/…. No hay autenticación: enlázalo a loopback o pon algo delante.
Notas de diseño que conviene leer antes de cambiar nada
docs/DESIGN.md — por qué el reconocimiento supera a la búsqueda, qué aporta la compuerta y el fallo que motivó cada mecanismo.
docs/OPERATING.md — ejecutarlo residente, planificadores y códigos de salida, copias de seguridad, qué vigilar.
docs/TRUST.md — qué es y qué no es un límite de almacén, políticas de escritura y los dos límites que son fáciles de pasar por alto (diarios compartidos, modelos compartidos). Léelo antes de poner en marcha un almacén privado.
Algunas decisiones que parecen extrañas hasta que te topas con lo que evitan:
Reservar antes de beber. El destilador reclama un tramo del diario antes de leerlo, bajo un bloqueo, y las marcas de agua solo avanzan. Dos destiladores que escribían cada uno su propia instantánea borraron el progreso del otro y volvieron a beber la misma agua una docena de veces.
Las marcas de agua son unidades por adaptador. Desplazamientos de bytes para transcripciones de solo añadir, números de secuencia para archivos que se reescriben (un desplazamiento de bytes dentro de un archivo recompimido es una mentira).
Supresión de eco. Una cita que ya existe en el almacén no es material nuevo: es el almacén leyéndose a sí mismo a través del resultado de una herramienta. Sin esto, un sistema de memoria redescubre y vuelve a registrar sus propios contenidos para siempre.
La última compuerta es un modelo, no un humano. Si una persona debe aprobar cada borrador, el sistema ha convertido silenciosamente a esa persona en su cuello de botella, y los borradores se acumulan para siempre. Nada en el bucle puede requerir a alguien que no esté siempre presente.
kura distill runsale con el código 2 cuando no había nada que hacer. Un planificador debe poder distinguir "hizo trabajo" de "no encontró nada", o un vigilante gira en una cola vacía y priva de recursos a los pasos que necesitan el tiempo de inactividad.
Medirlo, en lugar de afirmarlo
Dos preguntas se responden con un solo número y no deberían.
¿Cuánto más pequeño? store_ratio = tokens en las memorias y el índice / tokens del diario
bruto realmente consumido. ¿Qué se perdió? Esa es una medición diferente, y un almacén que
guarda una memoria de cada cien obtiene una puntuación magnífica en la primera mientras es inútil.
kura bench compress # what this store cost, from the distiller's own metrics
kura bench compress --tokenizer-command "./count-tokens" # exact, not estimated
kura bench retention --questions bench/fixtures/questions.jsonMedido aquí, con los datos de prueba incluidos y el estimador integrado:
corpus |
|
| 0.18 |
| 1.14 |
El segundo no es un error. Con material donde nada es relleno, destilar no comprime: cada memoria añade su porqué y su cómo aplicarlo, y el almacén sale ligeramente más grande que la transcripción. La proporción es una propiedad del corpus, no de esta herramienta, por lo que aquí no hay una cifra destacada y por lo que el comando informa de con qué ha contado.
La retención se puntúa sin modelos: cada hecho plantado lleva un marcador que debe aparecer en lo
que devuelve recall, de modo que la puntuación es reproducible en la máquina de otro. Los distractores
invierten la puntuación: un hecho marcado con must_not_store cuesta un punto si el almacén lo ha
conservado, porque un sistema de memoria se juzga tanto por lo que rechaza como por lo que conserva.
score 1.0 (10/10) decision 1/1 number 2/2 negation 1/1 reversal 1/1
conditional 1/1 landmine 1/1 returning 1/1 distractor 2/2Eso son diez hechos plantados en un banco de pruebas sintético, destilados por un Qwen3.8-27B local
(NVFP4) como cerebro y escriba con max_items = 8, coverage_passes = 2, y puntuados con el mismo
modelo como pensador. Un modelo diferente dará una puntuación diferente: la puntuación mide un
pipeline más modelo, y el banco de pruebas existe para que el modelo sea lo único que varíe. Mide si
un hecho es encontrable, no si la respuesta se lee bien: juzgar la prosa necesita un modelo, y
entonces el benchmark deja de ser reproducible.
kura distill run escribe una línea por lote en _still/metrics.jsonl, que es de donde proviene el
lado bruto. El lado canónico cuenta solo las memorias cuyo manifiesto de evidencia apunta a un lote
registrado — dividir un almacén entero por el material bruto de unos pocos lotes da un número
desviado por un orden de magnitud, y la primera versión de este comando hizo exactamente eso. Las
memorias anteriores a los manifiestos se notifican como unattributed, no se incluyen
silenciosamente. El lado bruto es siempre la estimación del destilador en el momento de beber, así que
con --tokenizer-command la proporción se etiqueta como mixed.
Contra qué se ejecuta
requisito | |
Python | 3.11+ (sin dependencias; |
Node | 20+, solo para el plugin DSH |
| solo para leer archivos de sesión DSH |
endpoint de modelo | cualquier cosa que responda a |
"OpenAI-compatible" es más estricto que "cualquier proveedor". La API nativa de un proveedor
necesita una pasarela compatible con OpenAI delante; su propia URL no sirve. Un servicio estricto
también rechaza campos de nivel superior desconocidos, así que configura dialect = "openai" (o
"generic") — el valor predeterminado "vllm" envía chat_template_kwargs, que los servidores
locales quieren y uno estricto responde con 400. El cliente reintenta una vez con un cuerpo simple y
registra por qué falló una llamada, en lugar de reducir cada causa a un None silencioso.
Pruebas
python3 -m pytest tests -q # 145 tests, no model required
cd dsh-plugin && npm test # 24 more for the pluginLa compuerta se prueba de forma adversarial: cada caso es una forma en que un modelo real intentó
realmente colar algo. test_containment.py está escrito de la misma manera — cada caso es un intento
de escape, no un camino feliz — porque protege un agujero que era real: un almacén solía responder por
cualquier archivo cuya ruta pudieras escribir. La prueba de extremo a extremo ejecuta un ciclo completo
de distil→drain contra un servidor de modelos con guion en un socket real.
Licencia
MIT.
Available Tools
6 toolskura_doctorA
Health check of the kura: how many memories, resolved and dead [[links]], islands (memories nothing links to), index drift. Call when recall behaves oddly, or when asked about the memory system itself.
| Name | Required | Description | Default |
|---|---|---|---|
| store | No | Which kura. Omit for the current one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does well by naming the diagnostic nature ('health check'), the categories of data inspected, and the symptom-triggered use case. It does not explicitly state whether the tool is read-only or whether any repair/reindexing occurs, but 'health check' strongly implies diagnostic rather than mutating behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: two sentences, front-loaded with the core purpose, followed by a concise list of diagnostic metrics and explicit usage triggers. Every clause earns its place, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with zero required parameters and a fully documented optional parameter, the description provides enough context to select and invoke the tool correctly. It explains what will be inspected and when to use it. The only gap is that it does not describe the return format or explicitly confirm the absence of side effects, but neither is critical for a diagnostic health-check tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the description provides no additional parameter-level meaning beyond what the schema already states. The optional 'store' parameter is fully documented in the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pairing: 'Health check of the kura', and enumerates concrete diagnostic outputs (memory counts, resolved/dead links, islands, index drift). This clearly differentiates it from the sibling tools like kura_read or kura_recall, which focus on reading or retrieving memories rather than diagnosing system health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Call when recall behaves oddly, or when asked about the memory system itself.' This provides clear invocation context. However, it does not explicitly mention alternatives or when not to use it, so it stops just short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kura_listA
List the kura this server holds and which agent mode each one belongs to. Call it when you are unsure which memory you are speaking from, or before switching.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states the operation (list) and the output (kura and agent modes) but does not mention side effects, read-only nature, performance, or any edge cases. Adequate but not rich for a tool without annotation safety signals.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero wasted words. The first sentence states the core function; the second provides immediate usage context. Information is front-loaded and every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter list tool with no output schema, the description explains what is listed and exactly when to invoke it. It could mention what 'kura' refers to or if results are ordered, but the definition is sufficient for an agent to decide and call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema coverage is trivially 100%. Per the rubric, 0 params earns a baseline of 4. The description does not need to add parameter details since none exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list', the resource 'kura', and what is listed (which agent mode each belongs to). It implies a distinction from siblings like kura_read or kura_recall by focusing on the server's collection and mode mapping, though it does not explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Call it when you are unsure which memory you are speaking from, or before switching.' It lacks explicit when-not-to-use or named alternative tools, but the usage context is concrete and helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kura_mapA
Show the whole index of the kura — every memory's one-line recognition trigger, in one answer. Use it when you need to see WHAT EXISTS rather than look something up: before claiming a topic was never discussed, when choosing which memory to open, or right after switching kura. It is a map, not the contents: open a memory with kura_read for the detail.
| Name | Required | Description | Default |
|---|---|---|---|
| store | No | Which kura. Omit for the current one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It clearly frames a display operation ('Show the whole index... in one answer') and sets output expectations ('map, not the contents'). It does not discuss permissions or exact formatting, but for a non-mutating index tool the core behavioral disclosure is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first states the action and scope, the second gives concrete use cases, and the third clarifies depth and names the sibling for details. It is front-loaded and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool with one optional parameter and no output schema, the description provides the essential context: what it returns, when to use it, what it is not, and where to go for detail. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the single 'store' parameter is already documented as 'Which kura. Omit for the current one.' The description adds no parameter-level detail beyond that, so it meets the baseline but does not exceed it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Show the whole index of the kura - every memory's one-line recognition trigger.' It also distinguishes itself from siblings by saying it is 'a map, not the contents' and explicitly directs details to kura_read, so an agent can tell it apart from the other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use conditions ('when you need to see WHAT EXISTS... before claiming a topic was never discussed, when choosing which memory to open, or right after switching kura') and an explicit alternative ('open a memory with kura_read for the detail'). This is clear routing guidance rather than leaving usage to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kura_readA
Read one whole memory from the kura by its slug (e.g. 'storage-doctrine'). Use after kura_recall when a summary is not enough and you need the full text.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | Memory slug, without .md | |
| store | No | Which kura. Omit for the current one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations available, the description carries the burden of behavior. It clearly indicates a read operation fetching the full memory text, which is sufficient for this simple tool. It could add detail about return format or failure behavior, but the core behavior is transparent enough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The primary behavior is front-loaded, and the usage guidance, alternative, and selection condition are packed efficiently into the second sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-by-slug tool with only two parameters, no output schema, and full schema coverage, the description is complete. It tells the agent what it does, when to use it, and provides an example. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds a useful example slug ('storage-doctrine') but otherwise does not need to add much beyond what the schema already documents for 'slug' and 'store'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Read'), the resource ('one whole memory'), and the retrieval key ('by its slug'), with a concrete example. It also names the sibling tool it complements, distinguishing it from kura_recall without needing to inspect the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool: 'Use after kura_recall when a summary is not enough and you need the full text.' This directly routes the agent to the appropriate alternative and gives a clear selection condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kura_recallA
Recall from the kura — long-term memory retrieved by MEANING rather than keyword, then following [[links]] between memories. Call it whenever the question touches past decisions, measurements, people, machines, or anything done before — prefer it over guessing. An empty result means it is simply not remembered yet: say so plainly and never fill the gap with invention. Pass store to reach a different kura, or call kura_use to switch for the session.
| Name | Required | Description | Default |
|---|---|---|---|
| hops | No | How many [[link]] hops to walk (default 1) | |
| store | No | Which kura to ask (store or mode name). Omit for the current one. | |
| question | Yes | What you want to remember, as a natural question |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description carries the full burden of behavioral disclosure. It does reveal important behavior: it retrieves by meaning, follows links, and emphasizes not to fabricate when no result is found. However, it does not disclose potential side effects, rate limits, or what happens with the hops parameter (e.g., how deep the search goes and whether more hops affect latency). It also doesn't specify if the tool is read-only, though recall implies reading. Overall, it gives useful context but leaves some behavioral aspects unmentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense paragraph but contains no filler. It front-loads the core purpose and usage guidance, then addresses edge cases and parameter use. It is appropriately sized for a tool with multiple interconnected behaviors (meaning-based recall, link-following, empty result handling). It could be slightly more structured (e.g., bullet points for handling empty results or parameter variants), but it is efficient and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters (1 required), no output schema, and moderate complexity due to link-following and alternate stores, the description covers the essential aspects: what it does, when to use it, how to handle empty results, and how to use parameters. It does not explicitly describe return format (e.g., whether it returns text or a list of memories), but with no output schema, it could have provided more on that. Missing details on hops behavior and potential limitations are minor gaps. Overall, it is fairly complete for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all three parameters (question, hops, store) with descriptions, and coverage is 100%, so the baseline for parameter semantics is 3. The description adds value by explaining the semantics of 'store' ('reach a different kura') and hints that 'question' should be phrased as a natural question. It also implies the meaning of 'hops' (following [[links]]). It doesn't detail the format or constraints beyond the schema, but it enriches the meaning of each parameter sufficiently.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Recall from the kura — long-term memory retrieved by MEANING rather than keyword, then following [[links]] between memories.' It differentiates itself from siblings by emphasizing meaning-based retrieval over keyword, which distinguishes it from tools like kura_read or kura_list. It also mentions specific use cases, making it easy for an agent to understand what it does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool: 'Call it whenever the question touches past decisions, measurements, people, machines, or anything done before — prefer it over guessing.' It also explains what to do on empty results ('An empty result means it is simply not remembered yet: say so plainly and never fill the gap with invention') and mentions alternatives or related actions ('Pass store to reach a different kura, or call kura_use to switch for the session'). This provides clear guidance on selection and behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kura_useA
Switch which kura the following calls read from, for the rest of this session. Use when the conversation moves to a different mode of work (for example from building things to talking things through). Has no effect on a bridge that was bound to a single kura at startup — it will say so.
| Name | Required | Description | Default |
|---|---|---|---|
| store | Yes | Store or mode name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It does this well by revealing that the switch persists for the session, affects subsequent calls, and has no effect on a single-kura bridge (and that it will say so). It does not cover every possible error or side effect, but the key stateful behavior is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted words. The main effect and scope are front-loaded, the usage condition follows, and the edge case is placed last. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter state-switching tool with no annotations and no output schema, this description is complete enough. It explains what the tool does, when to invoke it, how long the effect lasts, and the one major exception an agent needs to know about.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% — 'store' is already described as 'Store or mode name.' The description adds some context by suggesting that stores correspond to modes of work, but it does not enumerate valid values or add meaningful parameter detail beyond the schema. This is the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Switch') and names both the resource ('which kura the following calls read from') and the scope ('rest of this session'). This clearly distinguishes it from the sibling read/analysis tools like kura_read and kura_map, which retrieve data rather than change the active context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use it: 'Use when the conversation moves to a different mode of work,' with a concrete example. It also discloses a limitation about bridges bound to a single kura. It does not explicitly name sibling alternatives or state when not to use it, but the intended context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
kura_doctor - First observed
kura_list - First observed
kura_map - First observed
kura_read - First observed
kura_recall - First observed
kura_use
TDQS
Scored across 6 tools
Each tool has a distinct purpose: recall for meaning-based search, read for slug-based retrieval, map for index views, doctor for health checks, list for enumerating kuras, and use for switching. No overlap in functionality.
All tools follow the same `kura_` prefix with a verb-based second part (recall, read, map, doctor, list, use), creating a consistent and predictable naming scheme.
Six tools is a well-scoped number for a memory-management server, covering retrieval, inspection, maintenance, and context switching without excess or deficiency.
The set covers all read and management operations (recall, read, map, health, list, switch), but lacks an explicit write or delete capability, which is a minor gap for a full memory system. Agents can work around this by relying on existing memories.
Maintenance
Related MCP Connectors
- sepiaceOAuthio.sepiace
Long-term memory for AI agents. Pass one sentence, and it remembers, recalls, or forgets.
- RecallOAuthdev.recallmem
Long-term memory for AI agents: learns what is true about each person and answers with sources.
- mem0OAuthio.github.mem0ai
Persistent memory for AI agents: add, search, update, and delete long-term memories.
Universal persistent memory and knowledge retrieval layer for AI agents and LLMs.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides AI agents with persistent, searchable memory that survives across conversations using semantic search, temporal versioning, and smart organization. Enables long-term context retention and cross-session continuity for AI assistants.14-
- AlicenseNot gradedqualityAmaintenanceProvides persistent, searchable memory for MCP-compatible agents, enabling recall by meaning, automatic decay, trust scoring, and cross-agent handoffs.5MIT

Hebbrix MCP Serverofficial
AlicenseAqualityAmaintenanceProvides long-term memory and a temporal knowledge graph for AI agents, enabling persistent memory and reasoning across sessions.33101 PyPI2MIT
whimsicality-mcpofficial
AlicenseBqualityBmaintenanceProvides persistent memory for AI agents, including context storage, facts, plans, RAG search, code snippets, and conversation compaction, enabling state to survive across sessions and processes.1414 npm2MIT