kura
蒸留蔵 — distill-kura
Ein Langzeitgedächtnis für Agenten, das destilliert, nicht akkumuliert. Abruf funktioniert über Bedeutung, Schreiben ist durch Belege abgesichert, und ein Server kann mehrere getrennte Gedächtnisse halten — eines pro Agentenmodus — sodass ein Moduswechsel auch das Gedächtnis wechselt.
Wird als DeepSeek Harness-Plugin, als MCP-Server für jeden anderen Host, als HTTP-Dienst und als Python-Bibliothek ausgeliefert. Nur Standardbibliothek; keine Vektordatenbank, keine Embeddings, kein 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 │
└────────────────────────────────────────────────────────┘Warum es das gibt
Zwei Fehler zerstören das Langzeitgedächtnis eines Agenten, und sie zerstören es von gegenüberliegenden Seiten.
Abruf per Schlüsselwort verfehlt das, was du brauchst. Eine Frage nach "SSD-Inferenz- Chips" teilt kein Wort mit einer Erinnerung mit dem Titel "das 2,6-T-Modell von einer SSD-Stufe ausführen" — und doch sind es dasselbe Thema. Die Wortsuche liefert nichts; der Agent antwortet aus dem Nichts. Die Lösung hier sind nicht Embeddings, sondern Erkennung: Der gesamte Index (eine Zeile pro Erinnerung, geschrieben als Erkennungsauslöser) geht in einen Prompt, und ein kleines Modell benennt, was für die Frage relevant ist. Ein Index von ~500 Erinnerungen sind etwa 6k Tokens — ein paar Prozent eines modernen Kontextfensters, und er sitzt im Präfix-Cache.
Alles aufzuschreiben vergiftet den Speicher. Ein Agent behauptet etwas; ein naiver Destillierer zeichnet die Behauptung als Tatsache auf; der nächste Agent liest sie als Grundwahrheit zurück und wiederholt sie mit mehr Selbstvertrauen. Diese Schleife verstärkt sich selbst, und Prompt-Anweisungen stoppen sie nicht — gemessen, nicht angenommen. Deshalb ist der Schreibpfad durch deterministisches Python abgesichert: Jeder Kandidat für eine Erinnerung muss Zitate enthalten, die zeichengenau im Rohmaterial existieren, gekennzeichnet mit ihrer Herkunft.
Klasse | was es ist | was es erlaubt |
| die eigenen Worte des Menschen | "sie haben entschieden", "sie haben gefragt" |
| Maschinenausgabe | Zahlen — die einzige Quelle |
| ein aufgerufenes Werkzeug | "das wurde getan" |
| die eigene Prosa des Agenten | ein Urteil, in der ersten Person, niemals eine nackte Tatsache |
Ein Zitat, das nicht wörtlich gefunden wird, wird verworfen. Ein Kandidat ohne
überlebendes Zitat wird weggeworfen. Eine Zahl ohne [TOOL] dahinter wird entfernt.
Text, der dem Menschen eine Entscheidung zuschreibt, wenn kein [USER]-Zitat
überlebt hat, wird am letzten Tor abgelehnt. Ideen sind willkommen — sie gehen in eine
Seed-Datei, nie in den Speicher, und graduieren erst, wenn spätere Belege sie
bestätigen.
Related MCP server: Synapto
Schnellstart
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}'Trage den Index, damit der Agent immer weiß, was bekannt ist:
kura weave # build the three-layer cloth
kura prefill # the block to put in the system promptFüttere ihn mit deinen Agenten-Transkripten:
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 quietNichts gelangt in den Speicher, bis drain (oder ein manuell ausgeführtes pour)
läuft. Entwürfe tragen ihre Belege in einem HTML-Kommentar, sodass du immer sehen
kannst, warum eine Erinnerung existiert.
Die residente Karte
Abruf-per-Werkzeug beantwortet "Was weißt du über X?" — aber nur, wenn der Agent entschieden hat zu fragen. Es beantwortet nie die Frage, die der Agent nicht zu stellen denkt: gibt es hier überhaupt etwas? Ein Agent, der die Karte nicht sehen kann, weiß nicht, was ihm fehlt, also rät er, und eine selbstbewusste Vermutung über deinen Haushalt ist genau das Versagen, das dieses Projekt verhindern soll.
Deshalb wird der Index auch getragen: ein fester Block im System-Prompt, bei jeder Runde.
kura weave # re-weave the index into the three-layer cloth
kura prefill # print the block a host should injectDrei Ebenen, weil Detail nur für Neues etwas bringt
Ein blinder A/B-Test — 20 Fragen, dicker Index gegen schlanken Index, bewertet ohne zu wissen, welcher welcher war — legte die Form fest:
Band | dick | schlank |
gesamt | 9 | 11 |
aktuelle Ereignisse | 4 | 1 |
Doktrin | 1 | 4 |
Querschnitts-Sprünge | 1 | 4 |
Die Doktrin-Zeilen waren in beiden Indizes byte-identisch, und der schlanke Index gewann trotzdem in diesem Band: Eine leichtere Umgebung macht die stehenden Zeilen besser. Detail ist nicht die Quelle der Einsicht. Es verdient seinen Platz nur dort, wo sich noch etwas bewegt.
Ebene | Regel | Zeile |
gepinnt | Frontmatter | vollständig behalten |
frisch | geändert innerhalb | vollständig behalten |
Auslöser | alles andere | komprimiert auf ~ |
Auslöser-Zeilen werden vom scribe-Modell geschrieben und in einem Ledger
zwischengespeichert, das auf Beschreibung und Budget schlüsselt, sodass ein
Neu-Weben im stationären Zustand nichts kostet. Wenn kein Modell erreichbar ist,
schneidet der Webstuhl stattdessen mechanisch zu — ein Gedächtnissystem darf nicht
leer werden, nur weil eine GPU ausfällt.
Alter ist nicht mtime. cp -r, eine Wiederherstellung oder ein Checkout setzt
jeden Zeitstempel zurück, der ganze Index wird "frisch", nichts wird beschnitten, und
der Mechanismus hat sich stillschweigend abgeschaltet. Deshalb bevorzugt der Webstuhl
ein Datum, das innerhalb der Erinnerung geschrieben ist, und misstraut jeder mtime,
die ein Fünftel des Speichers mit einem Kalendertag teilt.
Wo es hingeht, und warum das eine Cache-Entscheidung ist
- id: kura
name: distill-kura
config: { store: eq, promptOrder: -50 } # before the personaEin Präfix-Cache geht ab dem ersten geänderten Byte verloren — gemessen auf einem lokalen Server: Ein identischer 4.029-Token-Präambel wird von 0,68 s auf 0,14 s umgerechnet, das Anhängen am Ende bleibt bei 0,14 s, und ein Wort vorne hinzugefügt kostet den gesamten Cache (0,66 s). Die Persona trägt normalerweise eine Uhr, also ändert sie sich jede Minute; die Karte ist der größte Block im Prompt und ändert sich ein paar Mal am Tag. Der große stabile Block kommt vor das, was tickt.
Der Block selbst enthält daher kein Datum, keine Uhr, keinen Zähler — und build()
verweigert einen Header, der eines enthält, zur Build-Zeit statt durch mysteriös
langsame Runden drei Wochen später.
Es übergibt nie eine halbe Karte
Situation | was der Agent bekommt |
alles gut | die Karte, zwischen |
über | die ganze Karte und eine Warnung im JSON (nie im Text — ein Banner ist flüchtiger Inhalt) |
über | einen Stub ohne Indexzeilen, der sagt, die Karte fehlt, statt leer zu sein |
kura nicht erreichbar | einen expliziten Hinweis, dass die Karte fehlt, niemals einen leeren String |
Eine abgeschnittene Karte ist das schlechteste verfügbare Artefakt: Sie sieht
vollständig aus, und jede Erinnerung unterhalb des Schnitts scheint nicht zu existieren.
weave verkürzt das Frische-Fenster, um zu passen, aber es lässt nie eine Zeile fallen —
und wenn keine Einstellung das Budget erreicht, sagt es das, behält die bessere Karte
und zeigt dir, wo das Gewicht liegt.
Wie man sie in einen Host bekommt
Host | Mechanismus |
DSH | natives Plugin — ein |
Claude Code, VS Code, Goose | MCP |
Claude Desktop, claude.ai | ignoriert |
alles andere |
|
Das MCP-Feld instructions ist ein MAY in der Spezifikation, und ein 9.000-Token-
Index kann ohnehin nicht durch ein 2KB-Cap reisen, also tut dieses Projekt nicht so,
als wäre es anders.
Modi: mehr als ein kura
Ein einzelnes Gedächtnis, das sowohl "hilf mir, das zu bauen" als auch "hilf mir, das durchzudenken" bedient, dient keinem gut: Der Abruf, der dir beim Debuggen hilft, ist Rauschen in einem Gespräch darüber, was als Nächstes zu tun ist. Also ist ein Speicher ein Verzeichnis, und ein Modus bildet auf einen Speicher ab.
[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"Jede Route nimmt einen Selektor, also bedient ein Prozess alle:
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 URLDie Speicher teilen keine Erinnerungen, keinen Index und kein Destillierer-Wasserzeichen. Der Moduswechsel ändert wirklich, was erinnert wird — nicht dieselbe Erinnerung in einer anderen Stimme.
Unabhängig als Routing, nicht als Vertraulichkeit. Der Server hat keine
Authentifizierung, also kann jeder Prozess, der seinen Port erreicht, jeden Speicher
benennen, den er hält. Einen Agenten zu binden hält ein Modell in seiner Spur; es
hält keinen Prozess fern. Eine Vertrauensstufe pro Prozess — docs/TRUST.md
ist kurz und lesenswert, bevor ein privater Speicher eingerichtet wird. Es behandelt
auch die zwei Grenzen, die leicht übersehen werden: zwei Speicher, die aus einer
Journal-Wurzel trinken, und zwei Speicher hinter einem Modell-Endpunkt.
Mit DeepSeek Harness
DSH wechselt Persona und Werkzeuge über Agent-Presets. distill-kura wechselt Gedächtnis über Speicher. Binde sie, und ein Preset-Wechsel bewegt das ganze Selbst:
# .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.)Lass allowSwitch auf seinem Standard, und der Agent bekommt auch kura_use, sodass er
sich mitten im Gespräch zwischen kuras bewegen kann, ohne einen Preset-Wechsel.
Werkzeuge: kura_recall, kura_read, kura_doctor, kura_list, kura_use und
kura_remember (nur wenn der Speicher beschreibbar ist). Vollständige Verdrahtung,
einschließlich der MCP-Brücke und der isolate-Realm-Regel für Dienstzeilen, findest
du in examples/dsh-presets/.
Persona ist Sache des Hosts, nicht unsere. Dieses Projekt rendert oder injiziert
nie eine Persona; es zeichnet nur pro Speicher auf, welche Persona-Datei dazugehört,
lesbar unter GET /profile?store=eq, damit die beiden Hälften von dem, der das Preset
besitzt, in Schritt gehalten werden können. Agenten-Anweisungen bleiben ebenfalls beim
AGENTS.md-Mechanismus des Hosts — siehe AGENTS.md in diesem Repo für
die Konventionen, die ein Agent, der an dieser Codebasis arbeitet, befolgen sollte.
Mit jedem MCP-Host
{ "mcpServers": { "kura": {
"command": "python3", "args": ["-m", "distill_kura.mcp"],
"env": { "KURA_URL": "http://127.0.0.1:8085", "KURA_STORE": "eq", "KURA_READONLY": "1" }
}}}Lass KURA_STORE für den freien Modus ungesetzt: Die Werkzeuge nehmen ein optionales
store-Argument, und kura_use wechselt für die Sitzung.
Modelle: eins als Standard, Rolle für Rolle aufrüsten
Drei Rollen, nicht drei Maschinen:
Rolle | wann sie läuft | braucht |
| bei jedem Abruf | klein und schnell; muss Relevanz nach Bedeutung beurteilen |
| beim Destillieren: liest ein ganzes Journal-Batch | Kontextlänge und Geduld |
| beim Destillieren: schreibt die Erinnerung, beurteilt dann Entwürfe | gute Prosa in deiner Sprache, Urteilsvermögen |
Deklariere nur [models.thinker], und ein Modell macht alle drei. Rüste die anderen
unabhängig auf — ein größeres lokales Modell oder eine Online-API (jedes
OpenAI-kompatible /chat/completions; der Schlüssel wird aus einer Umgebungsvariable
gelesen, die du benennst, nie in der Konfiguration gespeichert):
[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"Zwei Dinge übernimmt das für dich: Reasoning-Effort-Dialekte unterscheiden sich pro
Modellfamilie (reasoning_effort, thinking_effort, enable_thinking), also werden
alle gesendet — ein unbekanntes wird von der Vorlage ignoriert, während ein Modell,
das standardmäßig auf Tiefen-Denken steht, sein ganzes Budget für Reasoning ausgeben
und nichts zurückgeben kann. Und der Charta-Text wird byte-identisch an den Kopf jedes
Rollen-Prompts gesetzt, sodass bei einem langsamen lokalen Modell die drei Rollen einen
gemeinsamen gecachten Präfix teilen, statt drei Prefills zu zahlen.
Wenn der Denker ausfällt, verstummt die Erinnerung nicht — sie fällt zurück auf Wortüberschneidung
und kennzeichnet die Antwort als how=words, was die Werkzeuge als ⚠ degraded anzeigen. Leise
Verschlechterung ist schlimmer als lauter Ausfall.
Was eine Erinnerung ist
Eine Datei, eine Tatsache.
---
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]]Und eine Zeile in MEMORY.md:
- [Archive on the slow disk](archive-on-slow-disk.md) — the archive lives on the slow disk; the fast one stays scratchDiese Zeile ist das Einzige, was jedes Mal gelesen wird. Sie ist ein Erkennungsauslöser,
keine Zusammenfassung: Eigennamen, Zahlen, ⚠️ Stolpersteine, die gezogene Schlussfolgerung. Wenn eine Zeile
mit der Zeile einer anderen Erinnerung getauscht werden könnte und immer noch korrekt funktioniert, erfüllt sie ihre
Aufgabe nicht — kura distill tidy findet die mechanisch erkennbaren Fälle und korrigiert sie.
kura doctor meldet Zählwerte, tote Verweise, Inseln (Erinnerungen, auf die nichts verweist) und
Indexabweichungen. Es ist das Auge, das der Stoffwechsel braucht.
Die HTTP-Oberfläche
Route | Funktion |
|
|
|
|
| der rohe Index |
| der residente Block, bereit zum Einfügen ( |
| eine Erinnerung vollständig |
| Zustand eines Speichers ( |
| Speicher, Modi und welches Modell welche Rolle ausfüllt |
| die Satzung des Speichers und ein Verweis auf seine Persona (wird hier nie gerendert) |
| Betriebsbereitschaft |
Jede Route akzeptiert ?store= / ?mode=, ein store/mode-Feld im Body oder das
/s/<name>/…-Pfadpräfix. Keine Authentifizierung: Binden Sie an Loopback oder setzen Sie etwas
davor.
Entwurfsnotizen, die man lesen sollte, bevor man etwas ändert
docs/DESIGN.md — warum Erkennung besser ist als Suche, was die Schleuse erkauft und welcher Fehler jedes Verfahren motiviert hat.
docs/OPERATING.md — Betrieb als residenter Dienst, Planer und Exit- Codes, Backups, worauf man achten muss.
docs/TRUST.md — was eine Speichergrenze ist und was nicht, Schreib- richtlinien und die zwei Grenzen, die man leicht übersieht (gemeinsame Journale, gemeinsame Modelle). Lesen Sie es, bevor ein privater Speicher in Betrieb geht.
Ein paar Entscheidungen, die seltsam wirken, bis man auf den Fehler stößt, den sie verhindern:
Reservieren, bevor man trinkt. Der Destillierer beansprucht einen Journalabschnitt, bevor er ihn liest, unter einer Sperre, und Wasserstände bewegen sich nur vorwärts. Zwei Destillierer, die jeweils ihren eigenen Schnappschuss zurückschreiben, hätten sonst den Fortschritt des anderen gelöscht und denselben Abschnitt ein Dutzend Mal erneut gelesen.
Wasserstände sind pro Adapter. Byte-Offsets für reine Anhänge-Protokolle, Sequenznummern für Archive, die neu geschrieben werden (ein Byte-Offset in einer neu komprimierten Datei ist eine Lüge).
Echo-Unterdrückung. Ein Zitat, das bereits im Speicher existiert, ist kein neues Material — es ist der Speicher, der sich selbst durch ein Werkzeugergebnis zurückliest. Ohne dies würde ein Speichersystem seine eigenen Inhalte endlos neu aufzeichnen.
Die letzte Schleuse ist ein Modell, kein Mensch. Wenn ein Mensch jeden Entwurf genehmigen muss, hat das System diesen Menschen heimlich zum Engpass gemacht, und Entwürfe stapeln sich endlos. Nichts im Ablauf darf jemanden erfordern, der nicht ständig anwesend ist.
kura distill runendet mit Exit-Code 2, wenn es nichts zu tun gab. Ein Planer muss unterscheiden können zwischen „hat Arbeit erledigt" und „hat nichts gefunden", sonst dreht eine Überwachung durch und hungert die Schritte aus, die auf den Ruhezustand angewiesen sind.
Messen statt behaupten
Zwei Fragen werden mit einer Zahl beantwortet und sollten es nicht.
Wie viel kleiner? store_ratio = Token in den Erinnerungen und im Index / Token des
tatsächlich verbrauchten Journals. Was ging verloren? Das ist eine andere Messgröße, und ein
Speicher, der eine von hundert Erinnerungen aufbewahrt, glänzt bei der ersten Frage, während er bei der zweiten
nutzlos ist.
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.jsonGemessen mit den mitgelieferten Testdaten und dem eingebauten Schätzer:
Korpus |
|
| 0.18 |
| 1.14 |
Der zweite Wert ist kein Fehler. Bei Material, in dem nichts Füllmaterial ist, verkleinert Destillation nicht — jede Erinnerung fügt ihr Warum und Wie anzuwenden hinzu, und der Speicher wird geringfügig größer als das Transkript. Die Kennzahl ist eine Eigenschaft des Korpus, nicht dieses Werkzeugs, weshalb es hier keine einzelne Headline-Zahl gibt und der Befehl stattdessen meldet, was er gezählt hat.
Bewertung ohne Modell
Die Bewertung ist modellfrei: jede eingepflanzte Tatsache trägt eine Markierung, die in
dem erscheinen muss, was die Erinnerungssuche zurückgibt, sodass das Ergebnis auf einer fremden Maschine reproduzierbar ist. Ablenker
kehren das Vorzeichen um — eine Tatsache, die mit must_not_store markiert ist, kostet einen Punkt, wenn der Speicher sie behalten hat, denn ein
Speichersystem wird ebenso danach beurteilt, was es ablehnt, wie danach, was es bewahrt.
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/2Das sind zehn eingepflanzte Tatsachen in einem synthetischen Testaufbau, destilliert von einem lokalen Qwen3.8-27B
(NVFP4) als Gehirn und Schreiber mit max_items = 8, coverage_passes = 2, und bewertet mit
demselben Modell als Denker. Ein anderes Modell ergibt eine andere Bewertung: Die Bewertung
misst eine Pipeline-plus-Modell-Kombination, und der Testaufbau existiert, damit das Modell das einzige ist, was
sich unterscheidet. Sie misst, ob eine Tatsache auffindbar ist, nicht ob die Antwort gut
formuliert ist — die Beurteilung von Prosa braucht ein Modell, und dann ist die Messung nicht mehr reproduzierbar.
kura distill run schreibt eine Zeile pro Stapel in _still/metrics.jsonl, und dorther
kommen die Rohdaten. Die kanonische Seite zählt nur Erinnerungen, deren Evidenz-
manifest auf einen aufgezeichneten Stapel verweist — das Dividieren durch das Rohmaterial eines
einzelnen Stapels ergäbe eine Zahl in die falsche Richtung um eine Größenordnung, und die erste
Version dieses Befehls tat genau das. Erinnerungen, die älter sind als die Manifeste, werden gemeldet
als unattributed, nicht stillschweigend einbezogen. Die Rohdaten-Seite ist immer die Seite des Destillierers,
also wird bei --tokenizer-command das Verhältnis als mixed gekennzeichnet.
Voraussetzungen
Anforderung | |
Python | 3.11+ (keine Abhängigkeiten; |
Node | 20+, nur für das DSH-Plugin |
| nur zum Lesen von DSH-Sitzungsarchiven |
Modell-Endpunkt | alles, das |
„OpenAI-kompatibel" ist enger als „beliebiger Anbieter". Die native API eines Anbieters braucht ein
OpenAI-kompatibles Gateway davor; seine eigene URL reicht nicht. Ein strenger Dienst
lehnt auch unbekannte Felder auf oberster Ebene ab, also setzen Sie dialect = "openai" (oder "generic") — der
Standardwert "vllm" sendet chat_template_kwargs, was lokale Server wollen, ein strenger jedoch
mit 400 beantwortet. Der Client wiederholt einmal mit einem schlichten Body und protokolliert, warum ein Aufruf fehlschlug,
anstatt jede Ursache in einem stillen None verschwinden zu lassen.
Tests
python3 -m pytest tests -q # 145 tests, no model required
cd dsh-plugin && npm test # 24 more for the pluginDie Schleuse wird adversariell getestet: Jeder Fall ist eine Art, wie ein echtes Modell tatsächlich versucht hat,
etwas an ihr vorbeizuschmuggeln. test_containment.py ist auf dieselbe Weise geschrieben — jeder Fall ist
ein Ausbruchsversuch, kein glücklicher Pfad — weil es ein Loch bewacht, das real war: Ein Speicher
antwortete früher für jede Datei, deren Pfad man buchstabieren konnte. Der End-to-End-Test führt einen vollständigen
Distill→Drain-Zyklus gegen einen skriptgesteuerten Modellserver auf einem echten Socket aus.
Lizenz
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