hydra-ops-mcp
hydra-ops-mcp
通过对话操作 Hydra 头。 一个 MCP 服务器,将运行中的 Hydra 头——生命周期、账本、L1 钱包、节点日志和链上错误码——暴露为 LLM 客户端可调用的工具,让您可以用自然语言驱动和调试 Hydra 头,而无需在 TUI、curl、cardano-cli 和 docker logs 之间切换。
它涵盖了完整的操作面:init、存款、头内交易、decommit、close、fanout、部分 fanout 和存款恢复,以及头状态和 L1 的只读视图。每个改变状态的操作都会描述它将做什么,并在执行之前等待您的明确确认。
目录
为什么
操作一个头意味着同时掌握多个工具。TUI 显示头状态,但不会告诉你交易为何被拒绝。WebSocket API 提供事件,但你得手动解析 JSON。当出现问题时,答案通常藏在 docker compose logs 中,需要与头状态关联,并根据 Plutus 源码中的错误码进行解码。
这个服务器将所有内容置于一个对话式接口之后:
“头无法 fanout。出了什么问题?”
Claude 可以检查头状态,从节点日志中提取失败交易,将 H39 中止码解码为 FanoutUTxOHashMismatch,并告诉你实际导致它的两个原因——一轮对话即可完成,因为它能同时访问头 API、容器日志和错误表。
对于常规操作也很有用:打开并注资一个头,转移资金,以及结算,每一步在运行前都会得到解释和确认。与绑定到单个节点的 TUI 会话不同,每个工具都接受一个 node 参数,因此你可以比较 alice、bob 和 carol 各自对同一个头的看法。
目前针对 hydra 演示 devnet(三个节点,三方)。API 层并非 devnet 专用;L1 辅助函数和密钥处理是 devnet 特定的(参见限制)。
快速开始
先决条件 — Docker、Python 3.10+,以及 cardano-scaling/hydra 的克隆(用于演示 devnet 和 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.pyClaude 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" 块中传递,而不是在 shell 中导出。
然后询问:
“头处于什么状态,alice 在 L1 上持有什么?” “打开一个头并提交 alice 的资金。” “从 alice 向 bob 发送 5 ADA,然后显示头 UTXO 集。”
第一次以这种方式操作头?RUNBOOK.md 以一系列引导式会话的方式,贯穿整个生命周期——打开、注资、交易、decommit、关闭、结算,以及故意破坏。
架构
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 为每个节点持有一个 WebSocket 连接,在守护线程上运行异步事件循环,背后是同步接口——这样工具函数保持简单,同时仍能等待协议事件。它为 recent_events 缓冲每个服务器输出,跟踪头状态,并关联已确认的交易。命令会等待其特定结果事件(Decommit → DecommitFinalized,Fanout → HeadIsFinalized),而不是乐观返回,因此成功的工具调用意味着协议步骤实际完成。
tx_builder.py 使用 PyCardano 构建和签署交易——无需每次交易都经过 cardano-cli 往返。cardano.py 通过在执行 cardano-cli 的容器内执行 cardano-cli 处理 L1 端(地址派生、UTXO 查询、签署和提交存款交易),密钥也存放在那里。
errors.py 在调用时从本地 hydra 检出中解析 HeadError.hs、DepositError.hs、HeadTokensError.hs 等文件,因此解码的代码始终与你运行的版本匹配,而不是一个可能过时的表。
确认模型
每个改变状态的工具都接受 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
}实际上,这意味着 Claude 提议,你批准,然后才在链上发生任何事情。这对于单方面且不可逆的操作最为重要:close_head 影响头中的所有参与者,而 fanout 结算头的最终状态。
预览是已解析的,而非假设——commit_funds 会指定它选择的精确 UTXO,decommit 会指定它从头 UTXO 集中推导出的所有者和金额,send_tx 会报告它构建的交易 ID。验证在门控 之前 运行,因此你永远不会被要求确认本来会失败的事情。只读工具没有门控,立即运行。
工具参考
所有工具返回 {status, error, ...};失败时返回 {"status": "error", "error": "<message>", ...} 而不是异常。每个工具都接受 node: int = 1(1 = alice,2 = bob,3 = carol),l1_funds 和 explain_error 除外。
可观测性(只读)
工具 | 签名 | 返回 |
|
| 头标签、WS 观察到的状态、UTXO 数量、总 lovelace、快照编号、头版本、争议截止时间 |
|
| 头的 UTxO 集按地址分组,每个包含引用和值 |
|
| 参与方的 L1 地址、UTXO 数量、总 lovelace,以及每个 UTXO 的值 |
|
| 头的账本参数——完整集合加上那些有影响参数的摘要(费用、最小 UTXO、大小) |
|
| 已观察到但尚未吸收的存款——即恢复候选 |
|
| 在此连接上看到的服务器输出,可按标签过滤 |
recent_events 涵盖自服务器连接以来的事件——WS 连接不请求历史记录,因此是实时尾部而非完整日志。对于更早的内容,请使用 node_logs。
生命周期(确认门控)
工具 | 签名 | 备注 |
|
| 除非头处于 |
|
| 通过 |
|
| 在头仍打开的情况下,将一个头 UTxO 提取到 L1。从 UTxO 的地址推导所有者,并构建一个全额自转账作为 decommit 交易 |
|
| 发布最新的已确认快照并开始争议期。影响所有参与者 |
|
| 如果需要,等待 |
|
| 结算选定的子集;报告已分发的内容和剩余内容。参见限制 — 需要 2.3.0 以上版本的节点 |
|
|
|
commit_funds 每次故意只存入一个 UTXO:多 UTXO 存款在 2.3.0 上会导致 fanout 卡在 H39(参见操作说明)。
交易(确认门控)
工具 | 签名 | 备注 |
|
| 头内转账。 |
低于 1 ADA 的金额被拒绝。头将最小 UTXO 归零,因此这样的输出在 L2 上有效,但在 L1 上无法重新创建——它会永久卡住 fanout。交易在确认时根据当前 UTxO 集重新构建,因此预览不会使用过时的输入。调用在交易出现在已确认快照中后返回,而不仅仅是在被接受时。
诊断(只读)
工具 | 签名 | 备注 |
|
| 容器日志,可选择正则过滤。返回匹配的行数以及最后 |
|
| 从本地 hydra 检出中解码中止码( |
与 hydra-tui 对比
工具表面有意匹配 hydra-tui 暴露的内容,因此你在 TUI 中能做的任何事情在这里都能做:
hydra-tui | 本工具 |
|
|
提交对话框 |
|
|
|
|
|
|
|
|
|
|
|
|
|
主标签页 |
|
资金标签页 |
|
事件历史标签页 |
|
— |
|
与 TUI 一样,这不会暴露 Contest、SafeClose 或 SideLoadSnapshot。这些是协议对特定链上条件的响应,在这种条件下只有一个操作是正确的,并且时间至关重要;它们属于带有警报的确定性工具,而不是在提示符后面。
更进一步的地方:
诊断。
node_logs和explain_error在 TUI 中没有对应功能。这是最大的实际收益——一个卡住的头从“TUI 说它失败了”变成了解码的终止代码和匹配的日志行。跨节点。 TUI 会话只连接一个节点。这里每个工具都接受
node参数,因此你可以询问 alice、bob 和 carol 各自对同一个头的看法——这是发现落后节点最快的方法。L1 和 L2 统一。
l1_funds直接查询链,因此“那个 decommit 真的生效了吗?”是一个问题,而不是切换到cardano-cli的上下文切换。防护措施。 低于最小 UTXO 的输出和多 UTXO 存款在构建时被拒绝,因为两者都会在之后悄无声息地卡住 fanout。
组合操作。 多步操作在一个请求中完成:"关闭头,等待争议期结束,执行 fanout,然后显示每个人最终的 L1 余额" 是一个单一的请求。
TUI 仍然胜出之处: 它是一个实时仪表盘。MCP 是请求/响应模式,因此你得到的是快照而不是持续更新的视图——要随时间观察一个头,请保持 TUI 打开。对于重复性工作,按键也胜过模型往返,而且 TUI 的 UTxO 选择器是可视化的,而这里你需要先列出再选择。
配置
一切都在 config.py 中,可以通过环境变量覆盖:
设置 | 默认值 | 含义 |
|
| 节点索引 → WS/HTTP 端点和参与方名称 |
|
| 演示 devnet:docker compose 项目和凭据 |
|
| Hydra 仓库,用于解码终止代码 |
|
| Devnet 魔术值 |
|
| 头内输出的拒绝阈值 |
签名密钥是演示的 {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 Idletest_ops.py 断言每个改变状态的工具都返回 requires_confirmation,并且没有 confirm=True 就不会到达任何客户端(如果命令逃逸了门控,存根客户端会抛出异常),请求负载与 API 匹配,最小 UTXO 拒绝和 UTxO 验证触发,错误表解析和解码,以及所有 16 个工具都注册到服务器。
test_ops_devnet.py 驱动一个真实的头经历整个生命周期,并在每个阶段断言可观察性:门控检查 → init → commit → 六个读取工具 → 两笔头内支付 → decommit,通过资金出现在 L1 上而头保持打开来验证 → close → fanout → 回到 Idle → 日志和错误解码。如果 devnet 未启动或头不是 Idle 状态,它会跳过并给出明确消息。
操作说明
在它们让你损失一个头之前值得了解的事情。
H39 / FanoutUTxOHashMismatch 会永久卡住一个头。 Fanout 无法重现关闭的头所承诺的内容,因此头无法结算,资金被卡住。两个原因,都可预防并且在此处都得到了防范:2.3.0 上的多 UTXO 存款,以及任何低于 L1 最小 UTXO 的头输出。询问 explain_error("H39") 获取详细信息。
头将最小 UTXO 归零;L1 不会。 0.5 ADA 的输出在 L2 上交易愉快,然后无法在 L1 上重新创建。send_tx 出于此原因拒绝低于 1 ADA 的输出。
存款在存款期后被吸收,而非立即。commit_funds 会等待并报告如果吸收未发生;从未落地的存款会显示在 pending_deposits 中,并通过 recover_deposit 收回。
关闭是单方面的并影响所有人。 任何参与方都可以关闭,然后整个头必须结算。门控主要为此存在。
一个头需要每个参与方在线。 如果支付挂起,在怀疑工具之前先检查 docker compose ps。
演示 devnet 的区块生产者可能会在长时间空闲后停滞 —— cardano-cli query tip 返回相同的 slot 两次,一切都挂起。./reset_devnet.sh 修复它;devnet 按设计是可丢弃的。
无法解析的 WebSocket 输入不会返回 tag。 节点无法识别的命令会以裸的 {"input", "reason"} 对象返回,而不是带标签的事件——如果你直接对 API 编写脚本,值得了解,因为等待带标签事件的客户端会挂起。此处的客户端处理了这种情况。
限制
partial_fanout 需要节点版本高于 2.3.0。 该命令在发布之后(hydra PR #2750,commit a271cced2),固定的演示镜像拒绝它——节点列出它知道的命令,而 PartialFanout 不在其中。该工具精确检测到这一点并报告版本差距。代码路径已准备好用于从 master 构建的节点,但仅被测试到该拒绝为止。
费用为零。 tx_builder.py 硬编码了 fee=0,这对于演示的协议参数是正确的,但在其他地方都是错误的。在指向 preview/preprod 或主网之前,需要真实的费用估算和硬币选择。
Devnet 形状的假设。 三个参与方,已知的密钥名称,密钥在 cardano-node 容器内部可读,docker compose 可用于 L1 查询和日志。头 API 层是通用的;L1 辅助工具却不是。
仅 ADA。 交易构建处理纯 lovelace UTXO——没有原生代币、脚本、数据或铸造。
recover_deposit 未针对真正卡住的存款进行测试。 它遵循 API,但演示 devnet 吸收存款太可靠,无法按需产生一个。
无认证。 任何能到达服务器的人都可以操作头。这对于本地操作员工具是合适的,但对于任何暴露的服务则不适用。
扩展
添加工具: 在相关的 tools/ 模块中编写一个普通函数,返回 ok() / err() / needs_confirmation(),然后在 server.py 中注册一个薄包装器。工具模块不导入 FastMCP,因此可以直接从测试中调用——这正是两个测试套件驱动它们的方式。
添加协议命令: 使用 _command_and_wait(command, ok_tags) 向 HydraClient 添加方法,该方法发送并等待结果事件,同时将 CommandFailed 和未标记的解析拒绝视为错误。
定位到其他部署: 将 NODES 指向端点,将 HYDRA_DEMO_DIR / HYDRA_REPO 指向正确的路径。超出演示三方布局的任何内容都意味着需要重新审视 cardano.py 和 tx_builder.py 中的密钥处理以及费用。
进一步阅读
Hydra 文档 了解协议本身,以及 RUNBOOK.md 了解使用这些工具操作头的引导之旅。
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