Skip to main content
Glama
skoniog

hydra-ops-mcp

by skoniog

hydra-ops-mcp

Управляйте Hydra-головой, общаясь с ней. Это MCP-сервер, который предоставляет работающую голову — её жизненный цикл, реестр, L1-кошельки, журналы узла и коды ошибок на цепочке — в виде инструментов, которые может вызывать LLM-клиент. Так вы можете управлять и отлаживать голову на обычном языке, вместо того чтобы переключаться между TUI, curl, cardano-cli и docker logs.

Он охватывает всю операционную поверхность: init, депозиты, транзакции внутри головы, decommit, close, fanout, частичный fanout и восстановление депозитов, а также режимы только для чтения состояния головы и L1. Каждая операция, изменяющая состояние, описывает, что она сделает, и ждет вашего явного подтверждения перед выполнением.


Содержание


Зачем

Управление головой означает одновременное владение несколькими инструментами. TUI показывает состояние головы, но не говорит, почему транзакция была отклонена. WebSocket API предоставляет события, но вам приходится вручную разбирать JSON. Когда что-то идет не так, ответ обычно находится в docker compose logs, сопоставленный с состоянием головы и декодированный по кодам ошибок, которые живут в исходном коде Plutus.

Этот сервер помещает всё это в один диалоговый интерфейс:

"Голова не хочет разворачиваться. Что не так?"

Claude может проверить состояние головы, извлечь неудачную транзакцию из журналов узла, декодировать код прерывания H39 в FanoutUTxOHashMismatch и сказать вам две вещи, которые на самом деле к этому приводят — за один шаг, потому что у него есть API головы, журналы контейнеров и таблицы ошибок под рукой.

Это также полезно для рутинных действий: открытие и финансирование головы, перемещение средств и завершение расчётов — каждый шаг объясняется и подтверждается перед выполнением. И в отличие от сеанса TUI, привязанного к одному узлу, каждый инструмент принимает аргумент node, так что вы можете сравнить, что Алиса, Боб и Карол знают об одной и той же голове.

В настоящее время нацелен на Hydra demo devnet (три узла, три участника). Уровень API не привязан к devnet; помощники L1 и обработка ключей — привязаны (см. Ограничения).


Быстрый старт

Предварительные условия — Docker, Python 3.10+ и клон cardano-scaling/hydra (для демо-девнета и таблиц ошибок Plutus).

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

Зарегистрируйте сервер в вашем MCP-клиенте. 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 — добавьте в claude_desktop_config.json:

{
  "mcpServers": {
    "hydra-ops": {
      "command": "/absolute/path/to/hydra-ops-mcp/.venv/bin/python",
      "args": ["/absolute/path/to/hydra-ops-mcp/server.py"]
    }
  }
}

Загрузчики MCP запускают сервер с сокращённым окружением, поэтому передавайте любые переопределения (HYDRA_DEMO_DIR, HYDRA_REPO) в блоке "env", а не экспортируя их в вашей оболочке.

Затем спросите:

"В каком состоянии находится голова, и что у Алисы на L1?" "Открой голову и внеси средства Алисы." "Отправь 5 ADA от Алисы к Бобу, затем покажи мне UTXO-набор головы."

Новичок в управлении головой таким способом? RUNBOOK.md проведёт вас через весь жизненный цикл — открытие, финансирование, транзакции, декоммит, закрытие, расчёты и намеренные сбои — в виде серии учебных сессий.


Архитектура

  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 содержит по одному WebSocket-соединению на узел, запуская асинхронный цикл событий в фоновом потоке за синхронным фасадом — так функции инструментов остаются простыми, при этом ожидая событий протокола. Он буферизирует каждый вывод сервера для recent_events, отслеживает статус головы и коррелирует подтверждённые транзакции. Команды ждут конкретного события результата (DecommitDecommitFinalized, FanoutHeadIsFinalized), а не возвращаются оптимистично, так что успешный вызов инструмента означает, что шаг протокола действительно завершён.

tx_builder.py создаёт и подписывает транзакции с помощью PyCardano — без обращений к cardano-cli на каждую транзакцию. cardano.py обрабатывает сторону L1 (вывод адресов, запросы UTXO, подписание и отправку депозитных транзакций), запуская cardano-cli внутри запущенного контейнера cardano-node, где также хранятся ключи.

errors.py парсит HeadError.hs, DepositError.hs, HeadTokensError.hs и другие файлы из вашей локальной копии Hydra в момент вызова, так что декодированные коды всегда соответствуют запущенной версии, а не таблице, которая устаревает.


Модель подтверждения

Каждый инструмент, изменяющий состояние, принимает confirm: bool = False. Вызванный без него, инструмент проверяет всё, что может, определяет, что именно он сделает, и возвращает описание — ничего не изменив:

{
  "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
}

На практике это означает, что Клод предлагает, вы одобряете, и только тогда что-то происходит на цепочке. Это наиболее важно для операций, которые являются односторонними и необратимыми: close_head влияет на всех участников головы, а fanout завершает окончательное состояние головы.

Предпросмотр решённый, а не гипотетический — commit_funds указывает конкретный выбранный UTXO, decommit указывает владельца и сумму, полученные из UTXO-набора головы, send_tx сообщает идентификатор построенной транзакции. Валидация выполняется до шлюза, так что вас никогда не попросят подтвердить то, что всё равно бы не сработало. Инструменты только для чтения не имеют шлюза и выполняются сразу.


Справочник инструментов

Все инструменты возвращают {status, error, ...}; ошибки — это {"status": "error", "error": "<message>", ...}, а не исключения. Каждый инструмент принимает node: int = 1 (1 = alice, 2 = bob, 3 = carol), кроме l1_funds и explain_error.

Наблюдаемость (только чтение)

Инструмент

Сигнатура

Возвращает

head_status

(node=1)

Тег головы, статус из WS, количество UTXO, общее количество ловеласов, номер снимка, версия головы, крайний срок оспаривания

head_utxos

(node=1)

UTxO-набор головы, сгруппированный по адресу, каждый со ссылкой и значением

l1_funds

(party="alice")

L1-адрес участника, количество UTXO, общее количество ловеласов и значения по каждому UTXO

protocol_parameters

(node=1)

Параметры реестра головы — полный набор плюс сводка тех, которые доставляют хлопоты (комиссии, min-UTXO, размеры)

pending_deposits

(node=1)

Депозиты, замеченные, но ещё не поглощённые — кандидаты на восстановление

recent_events

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

Выводы сервера, наблюдаемые на этом соединении, опционально отфильтрованные по тегу

recent_events охватывает события с момента подключения сервера — WS-соединение не запрашивает историю, так что это «живой хвост», а не полный журнал. Для более старых событий используйте node_logs.

Жизненный цикл (с подтверждением)

Инструмент

Сигнатура

Примечания

init_head

(node=1, confirm=False)

Отказывается, если голова не в состоянии Idle. В версии 2.3.0 голова открывается сразу и пустой; средства добавляются через депозиты

commit_funds

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

Составляет депозит через POST /commit, подписывает ключом средств участника, отправляет на L1, затем ждёт поглощения. Вносит один UTXO — самый большой, если utxo_ref не указывает другой

decommit

(utxo_ref, node=1, confirm=False)

Выводит один UTXO головы на L1 при открытой голове. Определяет владельца из адреса UTxO и строит полный перевод самому себе в качестве транзакции decommit

close_head

(node=1, confirm=False)

Отправляет последний подтверждённый снимок и запускает период оспаривания. Влияет на всех участников

fanout

(node=1, confirm=False)

При необходимости ждёт ReadyToFanout, затем распределяет весь UTxO-набор на L1

partial_fanout

(utxo_refs, node=1, confirm=False)

Расчитывает выбранное подмножество; сообщает, что было распределено и что осталось. См. Ограничения — требуется узел новее 2.3.0

recover_deposit

(tx_id, node=1, confirm=False)

DELETE /commits/{txid} — возвращает застрявший депозит на L1

commit_funds намеренно вносит один UTXO за вызов: мульти-UTXO депозиты приводят к застреванию fanout с H39 в версии 2.3.0 (см. Эксплуатационные заметки).

Транзакции (с подтверждением)

Инструмент

Сигнатура

Примечания

send_tx

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

Внутри-головная передача. sender — участник, чей ключ подписи доступен; receiver — имя участника или bech32-адрес

Суммы ниже 1 ADA отклоняются. Голова обнуляет min-UTXO, поэтому такой выход допустим на L2, но затем его невозможно воссоздать на L1 — это навсегда заблокирует fanout. Транзакция перестраивается на основе текущего UTxO-набора в момент подтверждения, поэтому предпросмотр, который долго висел, не тратит устаревшие входы. Вызов возвращается, когда транзакция появляется в подтверждённом снимке, а не просто когда она принята.

Диагностика (только чтение)

Инструмент

Сигнатура

Примечания

node_logs

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

Журналы контейнера, опционально отфильтрованные по регулярному выражению. Возвращает количество совпавших строк и последние limit из них

explain_error

(code)

Декодирует код прерывания (H39, D01, ...) в его конструктор и модуль из вашей локальной копии Hydra, с практическими заметками для тех, которые действительно встречаются


Сравнение с hydra-tui

Поверхность инструментов намеренно соответствует тому, что предоставляет hydra-tui, так что всё, что можно сделать в TUI, можно сделать и здесь:

hydra-tui

here

i — 初始化

init_head

commit dialog

commit_funds (起草、签名、提交、等待吸收)

n —Δ 新交易

send_tx

d — 撤销提交

decommit

c — 关闭

close_head

f — 扇出

fanout

p — 部分扇出

partial_fanout

r — 恢复存款

recover_deposit

main tab

head_status, head_utxos

funds tab

l1_funds

event history tab

recent_events

protocol_parameters, pending_deposits

与TUI类似,此工具并不暴露ContestSafeCloseSideLoadSnapshot。这些是对特定链上条件的协议响应,在这些条件下只有一个操作是正确的且时机至关重要;它们属于带有警报的确定性工具,而不是放在提示符后面。

此工具的进一步功能:

  • 诊断。 node_logsexplain_error没有TUI对应项。这是最大的实际收益——一个卡住的头部从“TUI说它失败了”变成了解码后的中止码和匹配的日志行。

  • 跨节点。 TUI会话连接到一个节点。这里每个工具都接受node,因此你可以询问alice、bob和carol各自对同一头部的看法——这是发现落后节点的最快方法。 n* L1和L2一起。 l1_funds直接查询链,因此“那个撤销提交真的落地了吗?”是一个问题,而不是切换到cardano-cli的上下文切换。

  • 防护栏。 低于最小UTXO的输出和多个UTXO存款在构造时被拒绝,因为两者都会在后面静默地阻塞扇出。

  • 组合。 多步骤操作在一个请求中完成:“关闭头部,等待争议期结束,扇出,并显示所有人最终的L1余额” 是一个单一的请求。 n TUI仍然胜出的地方: 它是一个实时仪表板。MCP是请求/响应模式,因此你获得的是快照而非持续更新的视图——要持续观察一个头部,请保持TUI打开。按键操作在重复性工作中也优于模型往返,并且TUI的UTxO选择器是可视化的,而在这里你是先列出然后选择。 n


配置

所有配置在config.py中,可通过环境变量覆盖: n | 设置 | 默认值 | 含义 | | --------------------- | ----------------------------------- | --------------------------------------------------- | n| NODES | 4001, 4002, 4003 on localhost | 节点索引 → WebSocket/HTTP端点及参与者名称 | n| HYDRA_DEMO_DIR | /home/dev/claudecode/hydra/demo | 演示开发网络:Docker Compose项目及凭证 | n| HYDRA_REPO | /home/dev/claudecode/hydra | Hydra源代码,用于解码中止码 | n| NETWORK_MAGIC | 42 | 开发网络魔法号 | n| MIN_OUTPUT_LOVELACE | 1_000_000 | 头部输出拒绝阈值 |

签名密钥是演示的{alice,bob,carol}-funds配对。容器端路径用于cardano-cli(在L1上签名和提交);主机端相同密钥的副本由PyCardano读取用于头内交易。指向具有相同布局的不同部署是一个配置更改;指向不同的拓扑则不是(见限制)。“”

测试

.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**断言所有改变状态的工具都返回requires_confirmation,并且没有confirm=True时不会到达任何客户端(如果命令逃出网关,棵户端会抛出异常),请求载荷匹配API,最小UTXO拒绝和UTxO验证触发,错误表解析和解码,以及所有16个工具都在服务器上注册。

**test_ops_devnet.py**驱动一个真实头部经过整个生命周期,并在每个阶段断言可观察性:门禁检查 → initcommit → 六个读取工具 → 两次头内支付 → 撤销提交(通过当头部保持打开时资金出现在L1上来验证)closefanout → 回到 Idle → 日志和解码错误。如果开发网络未启动或头部不是Idle,它会以一条明确的消息跳过。

*** n

操作说明 n

在它们让你失去一个头部之前值得了解的事情。

**H39 / FanoutUTxOHashMismatch永久卡住头部。**扇出无法复现已关闭头部所承诺的内容,因此头部无法结算,其资金被卡住。两个原因,都是可预防的,并且在这里都得到了防范:2.3.0上的多UTxO存款,以及任何低于L1最小UTXO的头部输出。详情请询问explain_error("H39")

**头部将最小UTXO归零;L1不会。**一个0.5 ADA的输出在L2上愉快交易,然后在L1上无法重建。因此send_tx拒绝低于1 ADA的输出。 n 存款在存款期后被吸收,而不是立即。commit_funds等待并报告吸收是否未发生;从未落地的存款会出现在pending_dep osits中,并通过recver_deposit恢复。

**关闭是单方面的,影响所有人。**任何参与者都可以关闭,然后整个头部必须结算。门禁主要是为此存在。

**一个头部需要每个参与者在线。**如果一笔支付挂起,在怀疑工具之前检查docker compose ps

演示开发网络的区块生产者可能因长时空闲而停滞——cardano-cli query tip返回相同槽位两次,所有事情挂起。./reset_devnet.sh修复它;开发网络按设计是一次性的。

**不可解析的WebSocket输入不会返回tag**节点不认识的命令会返回一个裸的{"input", "reason"}对象,而不是标记事件——如果你直接使用API脚本,这一点值得了解,因为等待标记事件的客户端会挂起。此处的客户端处理了这种情况。 n *** n

限制

**partial_fanout需要一个高于2.3.0的节点。**此命令晚于该版本(hydra PR #2750,提交a271cced2),固定的演示映像拒绝它——节点会列出它知道的命令,而PartiaFanout不在其中。该工具精确检测到此情况并报告版本差距。代码路径已为从master构建的节点准备就绪,但仅在该拒绝点被测试过。

费用为零。 tx_builder.py硬编码fee=0,这对演示的协议参数是正确的,但在其他地方都不正确。在指向preview/preprod或主网之前,需要真实的费用估算和币选择。

**开发网形态假设。**三方具有已知密钥名称,密钥在cardano-node容器内可读,docker compose可用于L1查询和日志。头部API层是通用的;L1辅助工具则不是。

**仅ADA。**交易构建处理纯lovelace UTXO——没有原生代币、脚本、数据或铸造。 n **recver_deposit未在经过真正卡住的存款上测试过。**它遵循API,但演示开发网络吸收存款过于可靠,无法按需产生一个。

**无认证。**任何能到达服务器的人都可以操作头部。这对于本地操作工具是合适的,但如果暴露出来则不行。 n *** n

扩展 n

**添加一个工具:**在相关的tools/模块中编写一个返回ok() / err() / needs_confirmation()的普通函数,然后在server.py中注册一个薄封装。工具模块不导入FastMCP,因此可以直接从测试中调用——两个套件就是这样驱动它们的。

**添加协议命令:**使用_command_and_wait(command, ok_tags)HydraClient添加一个方法,该方法发送并等待结果事件,同时将CommandFailed和未标记的解析拒绝视为错误。

**针对另一个部署:**NODES指向端点,将HYDRA_DEMO_DIR / HYDRA_REPO指向正确的路径。任何超出演示三方布局的东西都意味着需要重新审视cardano.pytx_builder.py中的密钥处理以及费用。

*** n

扩展阅读 n

关于协议本身的Hydra文档,以及使用这些工具操作头部的指南RUNBOOK.md.

-
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