Skip to main content
Glama
skoniog

hydra-ops-mcp

by skoniog

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, seeded

Registrieren 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.py

Claude 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 codes

hydra_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 (DecommitDecommitFinalized, FanoutHeadIsFinalized), 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_status

(node=1)

Head-Tag, WS-beobachteter Status, UTXO-Anzahl, Gesamt-Lovelace, Snapshot-Nummer, Head-Version, Contestation-Deadline

head_utxos

(node=1)

Das UTxO-Set des Heads, gruppiert nach Adresse, jeweils mit Referenz und Wert

l1_funds

(party="alice")

Die L1-Adresse einer Partei, UTXO-Anzahl, Gesamt-Lovelace und Pro-UTXO-Werte

protocol_parameters

(node=1)

Die Ledger-Parameter des Heads — vollständiger Satz plus eine Zusammenfassung derer, die wehtun (Gebühren, Min-UTXO, Größen)

pending_deposits

(node=1)

Einzahlungen, die beobachtet, aber noch nicht absorbiert wurden — die Wiederherstellungskandidaten

recent_events

(node=1, tag=None, limit=25)

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

init_head

(node=1, confirm=False)

Verweigert, es sei denn, der Head ist Idle. Auf 2.3.0 öffnet sich der Head sofort und leer; Gelder folgen über Einzahlungen

commit_funds

(party="alice", node=1, utxo_ref="", confirm=False)

Erstellt den Einzahlungsentwurf über POST /commit, signiert mit dem Funds-Key der Partei, reicht bei L1 ein und wartet dann auf Absorption. Zahlt ein UTXO ein — das größte, es sei denn, utxo_ref nennt ein anderes

decommit

(utxo_ref, node=1, confirm=False)

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

close_head

(node=1, confirm=False)

Veröffentlicht den letzten bestätigten Snapshot und startet die Contestation-Periode. Betrifft alle Teilnehmer

fanout

(node=1, confirm=False)

Wartet bei Bedarf auf ReadyToFanout und verteilt dann das gesamte UTxO-Set auf L1

partial_fanout

(utxo_refs, node=1, confirm=False)

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

recover_deposit

(tx_id, node=1, confirm=False)

DELETE /commits/{txid} — gibt eine feststeckende Einzahlung an L1 zurück

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

send_tx

(sender, receiver, amount_lovelace, node=1, confirm=False)

In-Head-Transfer. sender ist eine Partei, deren Signaturschlüssel verfügbar ist; receiver ist ein Parteiname oder eine bech32-Adresse

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

node_logs

(node=1, pattern="", since="10m", limit=40)

Container-Logs, optional regex-gefiltert. Gibt zurück, wie viele Zeilen übereinstimmten und die letzten limit davon

explain_error

(code)

Dekodiert einen Abbruchcode (H39, D01, …) zu seinem Konstruktor und Modul aus Ihrem lokalen hydra-Checkout, mit praktischen Hinweisen zu denjenigen, die tatsächlich auftreten


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

i — init

init_head

commit dialog

commit_funds (drafts, signs, submits, waits for absorption)

n — new transaction

send_tx

d — decommit

decommit

c — close

close_head

f — fanout

fanout

p — partial fanout

partial_fanout

r — recover deposit

recover_deposit

main tab

head_status, head_utxos

funds tab

l1_funds

event history tab

recent_events

protocol_parameters, pending_deposits

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_logs und explain_error haben 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_funds fragt die Chain direkt ab, sodass „Ist der Decommit tatsächlich gelandet?" eine Frage ist, kein Kontextwechsel zu cardano-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

NODES

4001, 4002, 4003 auf localhost

Knotenindex → WS/HTTP-Endpunkte und Parteiname

HYDRA_DEMO_DIR

/home/dev/claudecode/hydra/demo

Demo-Devnet: Docker-Compose-Projekt und Anmeldedaten

HYDRA_REPO

/home/dev/claudecode/hydra

Hydra-Checkout, zum Dekodieren von Abbruchcodes

NETWORK_MAGIC

42

Devnet-Magie

MIN_OUTPUT_LOVELACE

1_000_000

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 Idle

test_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 → initcommit → sechs Lese-Werkzeuge → zwei Zahlungen im Head → decommit, verifiziert durch das Erscheinen der Gelder auf L1, während der Head offen bleibtclosefanout → 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 geratencardano-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.

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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.

View all MCP Connectors

Latest Blog Posts

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