Kyno
Kyno
Eine Kohärenz-Kontrollebene für Multi-Agenten-Systeme: eine versionierte Quelle der Wahrheit für die Mission und Prinzipien Ihres Systems (seine Verfassung), bereitgestellt über MCP, sodass jeder Agent nach der aktuell geltenden Richtung handeln kann – selbst wenn sich diese Richtung während des Betriebs ändert.
Warum
Wenn sich die Ziele eines Multi-Agenten-Systems ändern, produzieren Agenten mit einer veralteten Kopie der alten Richtung weiterhin Arbeit dafür – und schlimmer noch, Qualitätsprüfungen gegen die veraltete Kopie treiben die Arbeit aktiv zurück zum veralteten Ziel. Kyno entfernt die veraltete Kopie: Die Richtung lebt in einem versionierten Speicher, Agenten ziehen die aktuelle Version an jeder Schrittgrenze, und Abonnenten werden benachrichtigt, sobald sie sich ändert.
Schnellstart
pip install . # from a clone; CLI: kyno
kyno init-db
kyno set --mission "Ship a lending product people trust" \
--note "initial constitution"
kyno current
kyno serve --transport stdio # or --transport httpEine Verfassung besteht aus einer Mission (dem übergeordneten Zweck – dem Entscheider bei Prinzipienkonflikten) plus geordneten Prinzipien. Jede Änderung fügt eine neue unveränderliche Version mit einem Änderungshinweis in einfacher Sprache an; nichts wird direkt bearbeitet, sodass die Frage „Welche Richtung galt, als Agent X handelte?“ immer beantwortet werden kann.
Eine Verfassung schreiben
Ein einzeiliges Prinzip ist ein Name, keine Regel. Geben Sie einer Verfassung so viel, wie sie braucht, und nicht mehr – jedes dieser Elemente ist optional:
eine Erklärung, das ausführliche Dokument, dessen Überschrift die Mission ist;
eine Beschreibung unter einem Prinzip, der Absatz, der einen Streit darüber beilegt, was der Name bedeutet.
Beides sind Prosa, und Prosa über Kommandozeilen-Flags ist mühsam, daher wird eine Verfassung in einer Datei geschrieben:
# constitution.yaml
mission: Ship a lending product people trust with their worst month
declaration: |
## What we are for
Lending is a promise about somebody's worst month. We would rather lose
the deal than make a promise we cannot keep.
## What that costs us
- We say no early, in plain words, rather than late in a maze.
- We publish the number before the story that softens it.
principles:
- Say the hard number first
- title: Refuse quietly
description: |
A refusal is a sentence, not a maze. If we cannot lend, say so on the
first screen and say why.
note: the constitution as written
by: camilokyno set --file constitution.yaml
kyno set --file constitution.yaml --constitution eu --note "the EU edit"Die Erklärung ist Markdown, und die veröffentlichte Seite rendert sie: Überschriften, Listen, Hervorhebungen, Zitate, Links. Rohes HTML darin wird maskiert statt durchgereicht, und javascript:-Links werden abgewiesen – die Seite wird anonymen Besuchern ausgeliefert, daher darf Ihr eigener Text sie nie als ausführbares Markup erreichen. Bilder werden ebenfalls nicht gerendert, was die Seite zu einer einzigen in sich geschlossenen Antwort macht.
Überall sonst bleibt die Erklärung genau das von Ihnen geschriebene Markdown: Der JSON-Endpunkt, die MCP-Tools und kyno export liefern alle die Quelle, nicht das gerenderte Dokument.
--note, --by und --constitution können die Datei überschreiben, da sie sich auf diese Bearbeitung beziehen und nicht auf die Verfassung; die Feld-Flags (--mission, --declaration, --principle) können nicht mit --file kombiniert werden, da zwei Quellen für ein Feld eine Frage sind, die niemand beantworten sollte. Felder, die die Datei auslässt, werden aus der vorherigen Version übernommen – das Löschen eines Feldes wird mit declaration: "" ausgedrückt.
Die Flags sind für eine schnelle Bearbeitung weiterhin vorhanden:
kyno set --mission "Ship a lending product people trust" --note "sharpen the mission"Der Vertrag
Über MCP oder Python:
get_constitution– die aktuell geltende Richtung (Mission, Prinzipien, Version).get_changes_since(known_version)– der Abruf, den ein Agent vor einem Schritt durchführt: die aktuelle Richtung plus die Änderungshinweise seit der zuletzt gesehenen Version. Eine verpasste Benachrichtigung ist harmlos – der nächste Abruf ist selbsterklärend.get_mission,get_declaration,get_principles,get_principle(title)– jeweils ein Teil des Dokuments, für den Fall, dass eine kompakte Lektüre ihn ausgelassen hat.set_direction(mission?, declaration?, principles?, change_note)– die nächste Version anhängen. Ausgelassene Felder werden übernommen;""löscht eines. Bei HTTP erfordert dies das Bearer-Token.
Jeder Lesevorgang ist standardmäßig so klein wie möglich – Namen, nicht der lange Text – da ein Agent vor jedem Schritt abruft und sonst jedes Mal das gesamte Dokument kaufen würde. Fragen Sie nach mehr, wenn etwas es tatsächlich benötigt: detail="full" bei den beiden Abrufen, detail="full" bei get_principles oder einer der gezielten Lesevorgänge. Jede Antwort trägt die Version, aus der sie stammt, sodass ein Client, der sie mischt, erkennen kann, wann sie auseinandergedriftet sind.
Clients können auch die Ressource kyno://constitution/current abonnieren und bei jeder Versionserhöhung eine standardmäßige MCP resources/updated-Benachrichtigung erhalten. Sie liefert die kompakte Form: Eine Ressource benötigt keine Parameter, und das gesamte Dokument ist einen Tool-Aufruf entfernt.
Mehrere Verfassungen
Ein Kyno kann mehrere Verfassungen nebeneinander halten – zum Beispiel eine pro Produktlinie oder pro Rechtsraum. Jeder Vorgang akzeptiert einen optionalen constitution-Namen, über MCP und in der CLI (--constitution eu), und standardmäßig auf "default", sodass ein Einzelverfassungs-Setup ihn nie erwähnen muss. Jeder Name hat seine eigene Versionssequenz: Das Erhöhen von eu auf v2 lässt default auf der Version, die es hatte. Ein Name, in den Sie nie geschrieben haben, liest sich wie der gleiche leere Zustand Version 0 wie ein unberührter Speicher. Die abonnierbare Ressource ist die der Standardverfassung; Agenten auf einer anderen rufen sie namentlich mit get_changes_since ab.
Adapter (CrewAI, LangGraph)
pip install "kyno[crewai]" # or: pip install "kyno[langgraph]"Ein Adapter bindet ein Crew oder einen Graphen an eine benannte Verfassung und bindet jeden nächsten Schritt an die aktuell geltende Version neu:
from kyno.adapters.core import (
DirectionBinder,
KynoBinding,
McpDirectionSource,
SessionRunner,
http_session,
)
from kyno.adapters.crewai import CrewAiKyno
binding = KynoBinding.from_env(constitution="eu") # KYNO_URL, KYNO_TOKEN
runner = SessionRunner(http_session(binding))
runner.start()
binder = DirectionBinder(McpDirectionSource(runner))
adapter = CrewAiKyno(binder, constitution=binding.constitution)
adapter.register() # injects the current direction before each model call
crew = Crew(..., task_callback=adapter.task_callback) # gates each finished taskKyno stattdessen im selben Prozess einbetten? Tauschen Sie die Quelle: DirectionBinder(LocalDirectionSource(control_plane)).
Abruf vor jedem Schritt – die aktuelle Mission und die Prinzipientitel werden in den nächsten Modellaufruf eingefügt, gekennzeichnet mit der Verfassung und Version, aus der sie stammen. Dieser Block reist bei jedem Modellaufruf mit, bleibt also standardmäßig klein. Binden Sie mit
DirectionBinder(source, context="full"), wenn Sie lieber die Tokens ausgeben möchten: Die Erklärung und die Prinzipienbeschreibungen werden ebenfalls eingefügt, und der Abruf holt sie, nicht nur die Namen. Wenn Kyno nicht erreichbar ist – oder mit etwas Unlesbarem antwortet – degradiert der Abruf: Der Schritt läuft mit der letzten Richtung, die der Binder hält, und die Veralterung wird als Telemetrie ausgegeben. Binden Sie mitDirectionBinder(source, policy=PullPolicy(fail_closed=True)), wenn Ihre Haltung „keine Richtung, keine Arbeit“ ist: Der Schritt löst einen Fehler aus, anstatt fortzufahren.Push-Konsum –
BackgroundSubscriberverwandelt eine MCPresources/updated-Benachrichtigung in einen erneuten Abruf nach Namen. Ein bereits laufender Schritt wird nie unterbrochen; der nächste bindet die neue Richtung.Neuausrichtungstor – modellfrei und geprüft pro abgeschlossener Aufgabe (CrewAIs Task-Abschluss-Callback), nicht nach jedem LLM-Aufruf – günstiger und weniger verrauscht, sobald ein echter Richter angeschlossen ist, und die abgeschlossene Aufgabe ist bereits die überprüfbare Einheit. Es ruft eine von Ihnen bereitgestellte
VerdictSourceauf und löst einen Fehler aus (CrewAI, vontask_callback) oderinterrupt()für eine Entscheidung (LangGraph) beiDRIFTED. Wenn kein Richter verfügbar ist, wird die Arbeit fortgesetzt, markiert alsunchecked, und das Ereignis wird als Telemetrie ausgegeben: Der Standard tauscht eine übersprungene Prüfung gegen einen ununterbrochenen Lauf. Setzen SieGatePolicy(fail_closed=True)auf ein Tor, das stattdessen anhalten soll.Adapter sind schreibgeschützt – sie rufen ab und abonnieren;
set_directionbleibt eine Operator-/CLI-Aktion gegen Kyno, niemals etwas, das ein Adapter im Namen eines Crews oder Graphen aufruft.
Bei LangGraph erben Sie KynoState im Zustandsschema Ihres Graphen. LangGraph trägt nur die Schlüssel, die ein Schema deklariert, daher erreicht ohne es die Richtung, die ein Knoten abruft, nie den Gate-Knoten, der dagegen urteilt:
from kyno.adapters.langgraph import KynoState, direction_node, gate_node
class State(KynoState, total=False):
output: strSpeicher
SQLite standardmäßig; PostgreSQL für die Produktion über KYNO_DATABASE_URL. Der Speicher ist steckbar: Übergeben Sie SqlConstitutionStore Ihre eigene SQLAlchemy Engine, um in einer vorhandenen Datenbank zu leben, oder implementieren Sie das kleine Store-Protokoll, um Ihre eigene Persistenz vollständig mitzubringen. Gleichzeitige Schreiber sind sicher – Versionen werden durch einen eindeutigen Index und einen Wiederholungsversuch serialisiert, niemals verloren oder dupliziert.
Lesevorgänge schlagen bei einem leeren Speicher nie fehl: Bevor eine Richtung festgelegt wird, erhalten Verbraucher einen leeren Zustand Version 0, sodass die Integration von Kyno vor der Übernahme nichts kostet.
Ihre Verfassung veröffentlichen
Wenn Sie den Leuten die Prinzipien zeigen möchten, nach denen Sie angeblich handeln, kann Kyno diese Seite selbst ausliefern – sodass die veröffentlichte Seite und die, die Ihre Agenten befolgen, derselbe Datensatz sind, nicht zwei Kopien, die auseinanderdriften.
kyno publish # the default constitution
kyno publish --constitution eu --with-history
kyno unpublish --constitution euWährend kyno serve --transport http läuft, ist eine veröffentlichte Verfassung für jeden lesbar unter:
GET /constitutions/{name}– eine in sich geschlossene HTML-Seite (keine Skripte, keine externen Assets, hell und dunkel). Die Erklärung ist der Hauptteil, gerendert aus Markdown, und ein beschriebenes Prinzip trägt seinen Absatz.GET /constitutions/{name}.json– derselbe Inhalt, maschinenlesbar.GET /constitutions/undGET /constitutions.json– ein Index dessen, was Sie veröffentlicht haben.
Zwei Dinge, die wissenswert sind:
Ein veröffentlichter Name muss ein Slug sein – Kleinbuchstaben, Ziffern und einzelne Bindestriche (
acme,acme-eu). Er ist sowohl die URL als auch der Name, den Ihre Agenten verwenden, daher weigert Kyno sich, etwas anderes zu akzeptieren, anstatt es stillschweigend umzuschreiben. Namen, die Sie nie veröffentlichen, sind uneingeschränkt.Nichts ist öffentlich, bis Sie es veröffentlichen, und die Veröffentlichung erfolgt pro Name. Ein Kyno kann Ihre interne Verfassung und Ihre öffentliche nebeneinander halten; das Veröffentlichen der zweiten hat keine Auswirkungen auf die erste.
Die Veröffentlichung zeigt nur die aktuelle Richtung – Mission, Erklärung, Prinzipien, Version, Datum der letzten Änderung. Der Versionsverlauf bleibt privat, es sei denn, Sie fügen
--with-historyhinzu, da Änderungshinweise für Ihre Betreiber geschrieben werden und regelmäßig erklären, warum Sie den Kurs geändert haben. Ein veröffentlichter Verlauf zeigt die 100 neuesten Versionen – das ist der Vertrag der Seite; der vollständige Verlauf bleibt authentifizierten Aufrufern über MCP undkyno exportzugänglich.
Alles, was Sie nicht veröffentlicht haben, antwortet mit 404, genau wie ein Name, der nicht existiert. Nichts auf der öffentlichen Seite verrät, welcher der beiden Fälle es war.
Anpassen
Für eine Neufärbung sechs Umgebungsvariablen. Setzen Sie die, die Ihnen wichtig sind, und lassen Sie den Rest:
Variable | Standard | Was es färbt |
|
| Link-Unterstreichungen, Prinzipiennummern |
|
| die Seite |
|
| Fließtext |
|
| Labels, Daten, der Versionsstempel |
|
| die Haarlinien zwischen Elementen |
| System-Sans |
|
Nicht gesetzt erhalten Sie das integrierte Aussehen mit seinem automatischen Dunkelmodus. Setzen Sie irgendeine Farbe und Kyno stoppt das Umschalten der Palette für den Dunkelmodus – das Invertieren von Farben, die Sie gewählt haben, würde Ihnen eine Seite geben, die Sie nie genehmigt haben, also ist ab diesem Punkt die Palette Ihre. Nur die Schriftart zu setzen, behält den Dunkelwechsel bei.
Richtig anpassen
Die Seiten, die Kyno ausliefert, sind Vorlagendateien, und es wird Ihnen die echten aushändigen:
kyno page export ./pages # constitution.html, index.html, page.cssBearbeiten Sie sie, und weisen Sie dann Kyno auf Ihre Kopien – es gibt diese beiden Zeilen für Sie aus:
export KYNO_CONSTITUTION_TEMPLATE=/srv/pages/constitution.html
export KYNO_INDEX_TEMPLATE=/srv/pages/index.html # optionalDas ist der gesamte Workflow. Was Sie exportiert haben, ist das, was Kyno bereits gerendert hat – dieselben Dateien, auf dieselbe Weise gefüllt –, sodass Sie eine funktionierende Seite bearbeiten, anstatt eine zu rekonstruieren, und alles, was Sie unberührt lassen, funktioniert weiter.
kyno page export weigert sich, bereits vorhandene Dateien zu überschreiben, und schreibt gar nichts, wenn es müsste.
Das exportierte page.css ist ein Ausgangspunkt für Ihre eigenen Styles: Verlinken Sie es, binden Sie es ein oder werfen Sie es weg. Der $stylesheet-Platzhalter unten serviert immer die in Kyno eingebauten Styles, nicht Ihre Kopie davon – eine Vorlage, die $stylesheet behält, bleibt also beim Haus-Look (und folgt den Farbvariablen oben), und eine, die es weglässt, ist ganz Ihre.
Platzhalter
constitution.html
Platzhalter | Was es ist |
| Der gesamte |
| Der Name der Verfassung |
| Die Mission oder der Name, wenn es keine Mission gibt |
| Die aus Markdown gerenderte Erklärung, umschlossen von ihrem |
| Der Abschnitt „Grundsätze“, Überschrift und Liste — leer, wenn es keine gibt |
| Die Versionsnummer, z. B. |
| Das Datum der letzten Änderung, z. B. |
| Der Block mit dem Versionsverlauf — leer, wenn kein Verlauf veröffentlicht wurde |
index.html
Platzhalter | Was es ist |
| wie oben |
| Die Liste der veröffentlichten Verfassungen oder der Hinweis „noch nichts veröffentlicht“ |
| Anzahl der veröffentlichten Verfassungen |
Jeder Block-Platzhalter bringt seinen eigenen Wrapper mit und verschwindet vollständig, wenn er nichts zu sagen hat, sodass eine Vorlage nie fragen muss: „Was ist, wenn es keine Erklärung gibt?“. Das ist beabsichtigt: Es handelt sich um Platzhalter, nicht um eine Vorlagensprache – keine Schleifen, keine Bedingungen, keine Ausdrücke – und auch die Standardwerte unterliegen derselben Einschränkung, weshalb es dieselben Dateien sind, die Sie gerade exportiert haben.
Der daraus resultierende Sicherheitsvorteil: Kyno maskiert Ihre Mission, Grundsätze und Änderungsnotizen, bevor sie Ihre Datei erreichen, und rendert das Markdown Ihrer Erklärung mit deaktiviertem HTML, sodass keine Vorlage Text, den jemand in eine Verfassung eingegeben hat, in ausführbares Markup verwandeln kann. Ein falsch buchstabierter Platzhalter bleibt unverändert, anstatt die Seite zu beschädigen, und wenn Ihre Datei beim Eintreffen einer Anfrage fehlt oder nicht lesbar ist, stellt Kyno eine eigene Seite bereit und protokolliert eine Warnung – eine fehlerhafte Vorlage bringt niemals Ihre öffentliche Seite zu Fall.
Authentifizierung
stdio: offen. Ein Prozess, der den Server starten kann, besitzt bereits die darunterliegende Datenbankdatei; ein Token dort wäre Formsache, keine Grenze.
HTTP: Ein gemeinsames Bearer-Token (
KYNO_TOKEN) schützt jede Anfrage an den MCP-Endpunkt (/mcp). Der Server weigert sich, ohne Token über HTTP zu starten, es sei denn, Sie stimmen explizit zu (KYNO_ALLOW_INSECURE_HTTP, nur für lokale Experimente – es gibt eine Warnung), und ein gesetztes, aber leeresKYNO_TOKENist ein Konfigurationsfehler, keine stille Deaktivierung der Authentifizierung. Entwickler, die die App im Code einbetten, stimmen auf dieselbe Weise zu:build_http_app(..., allow_insecure=True). Die veröffentlichten Verfassungsseiten oben liegen absichtlich außerhalb dieser Absicherung – sie sind die Oberfläche, die Sie geöffnet haben.
Das Schreib-Token ist eine Richtungskontrolle: Wer es besitzt, steuert die
Anweisungen jedes Agenten, der an dieses Kyno gebunden ist. Behandeln Sie es wie
System-Prompt-Anmeldeinformationen – betreiben Sie /mcp über TLS und halten Sie
das Token aus Protokollen und Checkpoints heraus (Kynos eigene Repräsentationen geben
es nie preis). Damit zusammenhängend ist der [kyno:direction …]-Header im
injizierten Block eine Transkript-Protokollierung, keine Authentizitätsgrenze: Von
Tools oder Benutzern eintreffender Text kann ihn nachahmen, daher sollte nichts einem
Block vertrauen, weil er wie einer aussieht. Kyno lehnt Verfassungstext ab, der den
Marker enthält, und die Adapter ersetzen immer nur den Block, den sie selbst injiziert
haben.
Bereitstellung
Verwenden Sie in der Produktion eine absolute
KYNO_DATABASE_URL. Der Standardwert (sqlite:///kyno.sqlite3) ist ein Entwicklungs-Komfort, der relativ zum aktuellen Arbeitsverzeichnis des Prozesses aufgelöst wird.Betreiben Sie ein gehostetes Kyno hinter einem Reverse-Proxy, der Ratenbegrenzungen durchsetzt; die öffentlichen Seiten beantworten anonymen Datenverkehr, und die Ratenbegrenzung ist Aufgabe des Proxys, nicht von Kyno.
Feldgrößen sind Teil des API-Vertrags: Mission ≤ 4.000 Zeichen, Erklärung ≤ 200.000, Änderungsnotiz ≤ 2.000, bis zu 100 Grundsätze mit Titeln ≤ 300 und Beschreibungen ≤ 4.000, Verfassungsnamen ≤ 200.
set_directionlehnt alles Größere ab, und/mcp-Anfragekörper sind auf 5 MB begrenzt.Ein per pip installiertes Kyno enthält seine eigenen Migrationsskripte:
kyno init-dberstellt ein neues Schema, das auf den aktuellen Stand gestempelt ist, undkyno upgrade-dbbringt eine vorhandene Datenbank nach einem Update auf den neuesten Stand.
Testen
python -m pytest -q # SQLite, no network
KYNO_TEST_POSTGRES_URL=postgresql+psycopg://… python -m pytest -q # + PostgresVerwandtes Projekt: Canon testet, ob die Ausgaben Ihres Systems tatsächlich kohärent mit der Verfassung sind, die Kyno bereitstellt.
Siehe CONTRIBUTING.md für Style- und Testerwartungen.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Agent-native collaboration network: orchestrate a team of long-running agents from any MCP client.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cizambra/kyno'
If you have feedback or need assistance with the MCP directory API, please join our Discord server