hydra-ops-mcp
hydra-ops-mcp
Betreiben Sie einen Hydra-Head, indem Sie mit ihm sprechen. Ein MCP-Server, der einen laufenden Head – Lebenszyklus, Ledger, L1-Wallets, Node-Logs und On-Chain-Fehlercodes – als Werkzeuge bereitstellt, die ein LLM-Client aufrufen kann, sodass Sie einen Head in natürlicher Sprache steuern und debuggen können, anstatt zwischen einem TUI, curl, cardano-cli und docker logs zu wechseln.
Es deckt die gesamte Betriebsoberfläche ab: init, Einzahlungen, In-Head-Transaktionen, decommit, close, fanout, partielles Fanout und Einzahlungswiederherstellung, plus schreibgeschützte Ansichten des Head-Zustands und der L1. Jede Operation, die den Zustand ändert, beschreibt, was sie tun würde, und wartet auf Ihre ausdrückliche Bestätigung, bevor sie ausgeführt wird.
Inhalt
Warum
Einen Head zu betreiben bedeutet, mehrere Werkzeuge gleichzeitig zu verwenden. Das TUI zeigt Ihnen den Head-Zustand, aber nicht, warum eine Transaktion abgelehnt wurde. Die WebSocket-API liefert Ereignisse, aber Sie parsen JSON von Hand. Wenn etwas schiefgeht, liegt die Antwort normalerweise in docker compose logs, korreliert mit dem Head-Zustand und dekodiert anhand von Fehlercodes, die im Plutus-Quellcode leben.
Dieser Server fasst all dies hinter einer einzigen Gesprächsschnittstelle zusammen:
"Der Head führt kein Fanout durch. Was ist los?"
Claude kann den Head-Zustand überprüfen, die fehlgeschlagene Transaktion aus den Node-Logs abrufen, den Abbruchcode H39 zu FanoutUTxOHashMismatch dekodieren und Ihnen die beiden Dinge nennen, die tatsächlich dafür verantwortlich sind – in einem Durchgang, weil es die Head-API, die Container-Logs und die Fehlertabellen alle griffbereit hat.
Es ist auch für die Routineaufgaben nützlich: Öffnen und Finanzieren eines Heads, Verschieben von Geldern und Abwickeln, wobei jeder Schritt erklärt und bestätigt wird, bevor er ausgeführt wird. Und anders als eine TUI-Sitzung, die an einen einzelnen Node gebunden ist, akzeptiert jedes Werkzeug ein node-Argument, sodass Sie vergleichen können, was alice, bob und carol jeweils über denselben Head glauben.
Zielt derzeit auf das hydra demo devnet (drei Nodes, drei Parteien). Die API-Schicht ist nicht devnet-spezifisch; die L1-Helfer und die Schlüsselverwaltung sind es (siehe Einschränkungen).
Schnellstart
Voraussetzungen — Docker, Python 3.10+ und ein Checkout von cardano-scaling/hydra (für das Demo-Devnet und die Plutus-Fehlertabellen).
git clone https://github.com/skoniog/hydra-ops-mcp && cd hydra-ops-mcp
python3 -m venv .venv # or: uv venv .venv
.venv/bin/pip install -r requirements.txt
./reset_devnet.sh # cardano-node + 3 hydra-nodes, seededRegistrieren Sie den Server bei Ihrem MCP-Client. Claude Code:
claude mcp add hydra-ops -- /absolute/path/to/hydra-ops-mcp/.venv/bin/python \
/absolute/path/to/hydra-ops-mcp/server.pyClaude Desktop — fügen Sie zu claude_desktop_config.json hinzu:
{
"mcpServers": {
"hydra-ops": {
"command": "/absolute/path/to/hydra-ops-mcp/.venv/bin/python",
"args": ["/absolute/path/to/hydra-ops-mcp/server.py"]
}
}
}MCP-Launcher starten den Server mit einer bereinigten Umgebung, daher übergeben Sie alle Überschreibungen (HYDRA_DEMO_DIR, HYDRA_REPO) in einem "env"-Block, anstatt sie in Ihrer Shell zu exportieren.
Dann fragen Sie:
"In welchem Zustand ist der Head, und was hält alice auf L1?" "Öffnen Sie einen Head und committen Sie alices Gelder." "Senden Sie 5 ADA von alice an bob, und zeigen Sie mir dann das Head-UTXO-Set."
Neu im Betrieb eines Heads auf diese Weise? RUNBOOK.md führt Sie durch den gesamten Lebenszyklus — öffnen, finanzieren, transagieren, decommitten, schließen, abwickeln und absichtlich stören — als eine Reihe geführter Sitzungen.
Architektur
MCP client (Claude Code / Claude Desktop / anything speaking MCP)
│ stdio
▼
server.py FastMCP registration; thin wrappers only
│
tools/ one module per domain, plain functions
├── observe.py head state, UTXOs, L1 funds, params, events
├── lifecycle.py init, commit, decommit, close, fanout, recover
├── transact.py in-head transfers
├── diagnose.py node logs, error-code decoding
└── types.py ok() / err() / needs_confirmation()
│
├──▶ hydra_client.py WebSocket + HTTP to hydra-node
│ async core, sync facade, event buffer
├──▶ tx_builder.py PyCardano: build + sign in-head txs
├──▶ cardano.py cardano-cli in the node container (L1)
└──▶ errors.py parses hydra-plutus for abort codeshydra_client.py hält eine WebSocket-Verbindung pro Node, die eine asynchrone Ereignisschleife in einem Daemon-Thread hinter einer synchronen Fassade ausführt – so bleiben die Werkzeugfunktionen einfach, während sie dennoch auf Protokollereignisse warten. Es puffert jede Serverausgabe für recent_events, verfolgt den Head-Status und korreliert bestätigte Transaktionen. Befehle warten auf ihr spezifisches Ergebnisereignis (Decommit → DecommitFinalized, Fanout → HeadIsFinalized), anstatt optimistisch zurückzukehren, sodass ein erfolgreicher Werkzeugaufruf bedeutet, dass der Protokollschritt tatsächlich abgeschlossen wurde.
tx_builder.py erstellt und signiert Transaktionen mit PyCardano — kein cardano-cli-Roundtrip pro Transaktion. cardano.py kümmert sich um die L1-Seite (Adressableitung, UTXO-Abfragen, Signieren und Einreichen von Einzahlungstransaktionen), indem es cardano-cli innerhalb des laufenden cardano-node-Containers ausführt, in dem sich auch die Schlüssel befinden.
errors.py parst HeadError.hs, DepositError.hs, HeadTokensError.hs und Verwandte aus Ihrem lokalen hydra-Checkout zur Aufrufzeit, sodass dekodierte Codes immer der von Ihnen ausgeführten Version entsprechen, anstatt einer Tabelle, die abweicht.
Das Bestätigungsmodell
Jedes Werkzeug, das den Zustand ändert, akzeptiert confirm: bool = False. Ohne dieses aufgerufen, validiert das Werkzeug alles, was es kann, ermittelt, was es tatsächlich tun würde, und gibt eine Beschreibung zurück – ohne etwas geändert zu haben:
{
"status": "requires_confirmation",
"action": "deposit alice's UTXO 4a3f…#0 (100,000,000,000 lovelace) into the head via node 1",
"message": "This would deposit… Nothing has been done. Retry with confirm=True to execute.",
"party": "alice", "utxo_ref": "4a3f…#0", "lovelace": 100000000000
}In der Praxis bedeutet dies, dass Claude vorschlägt, Sie genehmigen, und erst dann passiert etwas auf der Chain. Dies ist am wichtigsten für die Operationen, die unilateral und irreversibel sind: close_head betrifft jeden Teilnehmer im Head, und fanout wickelt den endgültigen Zustand des Heads ab.
Die Vorschau ist aufgelöst, nicht hypothetisch — commit_funds nennt das genaue UTXO, das es ausgewählt hat, decommit nennt den Besitzer und den Betrag, den es aus dem UTXO-Set des Heads abgeleitet hat, send_tx meldet die Transaktions-ID, die es erstellt hat. Die Validierung läuft vor der Hürde, sodass Sie nie aufgefordert werden, etwas zu bestätigen, das ohnehin fehlgeschlagen wäre. Schreibgeschützte Werkzeuge haben keine Hürde und laufen sofort.
Werkzeugreferenz
Alle Werkzeuge geben {status, error, ...} zurück; Fehler sind {"status": "error", "error": "<message>", ...} anstelle von Ausnahmen. Jedes Werkzeug akzeptiert node: int = 1 (1 = alice, 2 = bob, 3 = carol) außer l1_funds und explain_error.
Beobachtbarkeit (schreibgeschützt)
Werkzeug | Signatur | Rückgabe |
|
| Head-Tag, WS-beobachteter Status, UTXO-Anzahl, Gesamt-Lovelace, Snapshot-Nummer, Head-Version, Contestation-Deadline |
|
| Das UTxO-Set des Heads, gruppiert nach Adresse, jeweils mit Referenz und Wert |
|
| Die L1-Adresse einer Partei, UTXO-Anzahl, Gesamt-Lovelace und Pro-UTXO-Werte |
|
| Die Ledger-Parameter des Heads — vollständiger Satz plus eine Zusammenfassung derer, die wehtun (Gebühren, Min-UTXO, Größen) |
|
| Einzahlungen, die beobachtet, aber noch nicht absorbiert wurden — die Wiederherstellungskandidaten |
|
| Serverausgaben, die auf dieser Verbindung gesehen wurden, optional nach Tag gefiltert |
recent_events deckt Ereignisse seit der Verbindung des Servers ab — die WS-Verbindung fordert keinen Verlauf an, es handelt sich also um einen Live-Tail und nicht um das vollständige Log. Für ältere Ereignisse verwenden Sie node_logs.
Lebenszyklus (bestätigungsgesperrt)
Werkzeug | Signatur | Anmerkungen |
|
| Verweigert, es sei denn, der Head ist |
|
| Erstellt den Einzahlungsentwurf über |
|
| Zieht ein Head-UTxO auf L1 ab, während der Head noch offen ist. Leitet den Besitzer aus der Adresse des UTxO ab und erstellt eine Vollwert-Selbstüberweisung als die Decommit-Transaktion |
|
| Veröffentlicht den letzten bestätigten Snapshot und startet die Contestation-Periode. Betrifft alle Teilnehmer |
|
| Wartet bei Bedarf auf |
|
| Wickelt eine ausgewählte Teilmenge ab; meldet, was verteilt wurde und was übrig bleibt. Siehe Einschränkungen — benötigt einen Node neuer als 2.3.0 |
|
|
|
commit_funds zahlt bewusst ein einzelnes UTXO pro Aufruf ein: Multi-UTXO-Einzahlungen sind das, was Fanout mit H39 auf 2.3.0 blockiert (siehe Betriebshinweise).
Transaktionen (bestätigungsgesperrt)
Werkzeug | Signatur | Anmerkungen |
|
| In-Head-Transfer. |
Beträge unter 1 ADA werden abgelehnt. Der Head setzt Min-UTXO auf null, sodass ein solcher Output auf L2 gültig ist und dann unmöglich auf L1 neu erstellt werden kann — es würde Fanout dauerhaft blockieren. Die Transaktion wird zum Bestätigungszeitpunkt gegen das aktuelle UTxO-Set neu erstellt, sodass eine Vorschau, die herumlag, keine veralteten Inputs ausgibt. Der Aufruf kehrt zurück, sobald die Transaktion in einem bestätigten Snapshot erscheint, nicht nur, wenn sie akzeptiert wird.
Diagnose (schreibgeschützt)
Werkzeug | Signatur | Anmerkungen |
|
| Container-Logs, optional regex-gefiltert. Gibt zurück, wie viele Zeilen übereinstimmten und die letzten |
|
| Dekodiert einen Abbruchcode ( |
Vergleich mit hydra-tui
Die Werkzeugoberfläche entspricht bewusst dem, was hydra-tui bereitstellt, sodass alles, was Sie im TUI tun können, Sie auch hier tun können:
hydra-tui | here |
|
|
commit dialog |
|
|
|
|
|
|
|
|
|
|
|
|
|
main tab |
|
funds tab |
|
event history tab |
|
— |
|
Wie das TUI bietet auch dies keinen Zugriff auf Contest, SafeClose oder
SideLoadSnapshot. Dabei handelt es sich um Protokollantworten auf bestimmte
On-Chain-Bedingungen, bei denen eine Aktion korrekt ist und das Timing eine
Rolle spielt; sie gehören in deterministische Werkzeuge mit Alarmierung, nicht
hinter eine Eingabeaufforderung.
Wo dies weiter geht:
Diagnose.
node_logsundexplain_errorhaben kein TUI-Äquivalent. Dies ist der größte praktische Gewinn – ein blockierter Head geht von „das TUI sagt, es ist fehlgeschlagen" zu einem dekodierten Abbruchcode und den passenden Logzeilen.Knotenübergreifend. Eine TUI-Sitzung verbindet sich mit einem Knoten. Hier akzeptiert jedes Werkzeug
node, sodass Sie fragen können, was Alice, Bob und Carol jeweils über denselben Head glauben – der schnellste Weg, einen Knoten zu erkennen, der zurückgefallen ist.L1 und L2 zusammen.
l1_fundsfragt die Chain direkt ab, sodass „Ist der Decommit tatsächlich gelandet?" eine Frage ist, kein Kontextwechsel zucardano-cli.Schutzmaßnahmen. Ausgaben unterhalb des Min-UTXO und Multi-UTXO-Einzahlungen werden von vornherein abgelehnt, da beide später den Fanout stillschweigend blockieren.
Komposition. Mehrschrittige Operationen erfolgen in einer Anfrage: „Schließe den Head, warte die Contestation ab, führe Fanout durch und zeige mir die endgültigen L1-Guthaben aller Beteiligten" ist eine einzige Aufforderung.
Wo das TUI immer noch gewinnt: Es ist ein Live-Dashboard. MCP ist Anfrage/Antwort, sodass Sie Schnappschüsse erhalten, keine kontinuierlich aktualisierte Ansicht – zum Beobachten eines Heads über die Zeit hinweg lassen Sie das TUI geöffnet. Tastendrücke schlagen auch eine Modell-Roundtrip für wiederholte Arbeiten, und die UTxO-Auswähler des TUI sind visuell, während Sie hier auflisten und dann auswählen.
Konfiguration
Alles befindet sich in config.py, mit Umgebungsüberschreibungen:
Einstellung | Standard | Bedeutung |
|
| Knotenindex → WS/HTTP-Endpunkte und Parteiname |
|
| Demo-Devnet: Docker-Compose-Projekt und Anmeldedaten |
|
| Hydra-Checkout, zum Dekodieren von Abbruchcodes |
|
| Devnet-Magie |
|
| Ablehnungsschwelle für Ausgaben im Head |
Signierschlüssel sind die {alice,bob,carol}-funds-Paare des Demos.
Container-seitige Pfade werden für cardano-cli verwendet (Signieren und
Einreichen auf L1); host-seitige Kopien derselben Schlüssel werden von
PyCardano für Transaktionen im Head gelesen. Auf eine andere Bereitstellung
mit demselben Layout zu verweisen, ist eine Konfigurationsänderung; auf eine
andere Topologie zu verweisen, ist es nicht (siehe Einschränkungen).
Testen
.venv/bin/python test_ops.py # offline — no devnet needed
.venv/bin/python test_ops_devnet.py # live — needs a devnet with the head Idletest_ops.py stellt sicher, dass jedes zustandsändernde Werkzeug
requires_confirmation zurückgibt und ohne confirm=True keinen Client
erreicht (der Stub-Client wirft einen Fehler, wenn ein Befehl das Tor
verlässt), dass Anfrage-Payloads mit der API übereinstimmen, dass die
Min-UTXO-Ablehnung und UTxO-Validierung ausgelöst werden, dass die
Fehlertabelle geparst und dekodiert wird und dass alle 16 Werkzeuge beim
Server registriert sind.
test_ops_devnet.py treibt einen echten Head durch den gesamten
Lebenszyklus und stellt die Beobachtbarkeit in jeder Phase sicher:
Gate-Prüfung → init → commit → sechs Lese-Werkzeuge → zwei
Zahlungen im Head → decommit, verifiziert durch das Erscheinen der
Gelder auf L1, während der Head offen bleibt → close → fanout →
zurück zu Idle → Logs und Fehlerdekodierung. Es überspringt mit einer
deutlichen Meldung, wenn das Devnet nicht läuft oder der Head nicht Idle ist.
Betriebshinweise
Dinge, die man wissen sollte, bevor sie einen Head kosten.
H39 / FanoutUTxOHashMismatch blockiert einen Head dauerhaft. Der
Fanout kann nicht reproduzieren, wozu der geschlossene Head sich verpflichtet
hat, sodass der Head nicht abgerechnet werden kann und seine Gelder stecken
bleiben. Zwei Ursachen, beide vermeidbar und beide hier abgesichert:
Multi-UTXO-Einzahlungen auf 2.3.0 und jede Head-Ausgabe unterhalb des
L1-Min-UTXO. Fragen Sie explain_error("H39") für die Details.
Der Head setzt Min-UTXO auf Null; L1 tut das nicht. Eine Ausgabe von
0,5 ADA wird auf L2 problemlos übertragen und kann dann auf L1 nicht
wiederhergestellt werden. send_tx lehnt aus diesem Grund unter 1 ADA ab.
Einzahlungen werden nach einer Einzahlungsfrist absorbiert, nicht
sofort. commit_funds wartet und meldet, wenn die Absorption nicht
stattfindet; eine Einzahlung, die nie ankommt, erscheint in
pending_deposits und wird mit recover_deposit zurückgeholt.
Schließen ist einseitig und betrifft alle. Jeder Teilnehmer kann schließen, und der gesamte Head muss dann abgerechnet werden. Das Tor existiert hauptsächlich dafür.
Ein Head benötigt jeden Teilnehmer online. Wenn eine Zahlung hängt,
überprüfen Sie docker compose ps, bevor Sie die Werkzeuge verdächtigen.
Der Blockproduzent des Demo-Devnets kann nach langen Leerlaufzeiten
ins Stocken geraten – cardano-cli query tip gibt denselben Slot zweimal
zurück und alles hängt. ./reset_devnet.sh behebt das; das Devnet ist
bewusst wegwerfbar.
Nicht parsbare WebSocket-Eingaben geben kein tag zurück. Ein Befehl,
den ein Knoten nicht erkennt, kommt als nacktes {"input", "reason"}-Objekt
zurück, nicht als getaggtes Ereignis – wissenswert, wenn Sie direkt gegen die
API skripten, da ein Client, der auf getaggte Ereignisse wartet, hängen
bleibt. Der Client hier behandelt das.
Einschränkungen
partial_fanout benötigt einen Knoten neuer als 2.3.0. Der Befehl
stammt aus der Zeit nach der Veröffentlichung (Hydra PR #2750, Commit
a271cced2), und das festgelegte Demo-Image lehnt ihn ab – der Knoten listet
die ihm bekannten Befehle auf, und PartialFanout ist nicht darunter. Das
Werkzeug erkennt dies genau und meldet die Versionslücke. Der Codepfad ist
für einen aus Master gebauten Knoten bereit, wurde aber nur bis zu dieser
Ablehnung getestet.
Gebühren sind null. tx_builder.py kodiert fee=0 hart, was für die
Protokollparameter des Demos korrekt und überall sonst falsch ist. Eine
realistische Gebührenschätzung und Münzauswahl sind erforderlich, bevor dies
auf Preview/Preprod oder Mainnet abzielt.
Devnet-förmige Annahmen. Drei Parteien mit bekannten Schlüsselnamen,
Schlüssel, die innerhalb des Cardano-Node-Containers lesbar sind, docker compose für L1-Abfragen und Logs verfügbar. Die Head-API-Schicht ist
algemein; die L1-Helfer sind es nicht.
Nur ADA. Die Transaktionserstellung behandelt reine Lovelace-UTXOs – keine nativen Token, Skripte, Datums oder Minting.
recover_deposit ist gegen eine wirklich feststeckende Einzahlung
ungetestet. Es folgt der API, aber das Demo-Devnet absorbiert Einzahlungen
zu zuverlässig, um eine auf Abruf zu produzieren.
Keine Authentifizierung. Jeder, der den Server erreichen kann, kann den Head bedienen. Das ist für ein lokales Operator-Werkzeug angemessen und wäre für etwas, das exponiert ist, nicht.
Erweiterung
Hinzufügen eines Werkzeugs: Schreiben Sie eine einfache Funktion im
entsprechenden tools/-Modul, die ok() / err() / needs_confirmation()
zurückgibt, und registrieren Sie dann einen dünnen Wrapper in server.py.
Werkzeugmodule importieren FastMCP nicht, sodass sie direkt aus Tests
aufrufbar sind – so treiben beide Test-Suiten sie.
Hinzufügen eines Protokollbefehls: Fügen Sie eine Methode zu
HydraClient hinzu, die _command_and_wait(command, ok_tags) verwendet,
welche sendet und auf das Ergebnisereignis wartet, während sowohl
CommandFailed als auch ungetaggte Parse-Ablehnungen als Fehler behandelt
werden.
Zielen auf eine andere Bereitstellung: Richten Sie NODES auf die
Endpunkte und HYDRA_DEMO_DIR / HYDRA_REPO auf die richtigen Pfade.
Alles, was über das Drei-Parteien-Layout des Demos hinausgeht, bedeutet eine
Überarbeitung der Schlüsselverwaltung in cardano.py und tx_builder.py
sowie der Gebühren.
Weiterführende Literatur
Die Hydra-Dokumentation für das Protokoll selbst und RUNBOOK.md für die geführte Tour zum Betreiben eines Heads mit diesen Werkzeugen.
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
MCP server exposing the Backtest360 engine API as tools for AI agents.
Hosted MCP server for live Bittensor chain reads and self-custodial on-chain writes.
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
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/skoniog/hydra-ops-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server