Skip to main content
Glama

cardano-debug-mcp

An MCP server that lets an AI assistant such as Claude Code inspect, validate and step-debug Cardano transactions and Plutus scripts.

Give it a transaction (CBOR or a hash) and ask why it fails. The assistant can then validate it against the ledger rules, find the failing redeemer, step through the script on a CEK machine, read the script as pseudocode, explain CBOR / CDDL errors, and send you a link that opens the problem highlighted in cquisitor or de-uplc-web.

Under the hood:

Quick start

Needs Node ≥ 20. Install from npm and register the server with Claude Code:

npm install -g @cardananium/cardano-debug-mcp
claude mcp add --scope user cardano-debug -- cardano-debug-mcp

Using Codex, Cursor, VS Code, Gemini CLI or Claude Desktop instead? See Add it to other MCP clients. With Claude Code, start a new session and ask, for example, "why does this transaction fail?" with the transaction CBOR or its hash. Loading a transaction by hash uses the public Koios API, which is rate limited: for regular use add a Koios API key or a Blockfrost project id (see Add it to Claude Code). Details, other MCP clients and building from source are under Install.

Related MCP server: MCP Debugger

What you can ask

These are starting points, not a fixed list. The tools share handles (tx_id, dbg_id) and one canonical UPLC position format, so the assistant works iteratively: it picks the next call from the previous result instead of running a script.

  • "Why does this transaction fail?" (paste the CBOR or a tx hash)

  • "Which redeemer fails, and where in the script?"

  • "Step through the spend redeemer until the error and show me the environment."

  • "What does this validator check?" (the script is decompiled to readable pseudocode)

  • "Why doesn't this CBOR match the Conway CDDL?"

  • "Open the failing part in cquisitor."

A typical "why does it fail?" run:

  1. Load and validate the transaction. A phase-1 failure is explained from the ledger error, its location and hint.

  2. For a failing redeemer, read its error and traces, then read the validator as pseudocode to form a hypothesis.

  3. Open a debugging session and run until the error. Rewind to the failing term when needed, inspect the environment and frames, and stop at a trace, a builtin or a budget threshold to test the hypothesis.

  4. Report the root cause with the decisive values, the evidence and a fix, and optionally open the problem in cquisitor or de-uplc-web.

You can also steer it mid-way ("stop at the first lessThanInteger", "why is this so expensive?", "what would pass?").

Install

Two ways: from npm (nothing to build) or from source.

From npm

Requires Node ≥ 20.

npm install -g @cardananium/cardano-debug-mcp
cardano-debug-mcp --check   # verifies the install, exit code 0 = fine

From source

Requirements:

  • Node ≥ 20 and npm to run the server. The tests and npm run dev need Node ≥ 22.12.

  • git: the debugger and decompiler wasm sources are the deps/de-uplc-web submodule.

  • To build that wasm (npm run build:deps):

    • bash (the build scripts are bash; there is no native Windows build, use WSL2);

    • Rust with the wasm target: rustup target add wasm32-unknown-unknown;

    • wasm-pack (cargo install wasm-pack) for the debugger engine. It fetches the wasm-bindgen version pinned in the engine's Cargo.lock (0.2.129) by itself;

    • wasm-bindgen-cli for the decompiler, which pins a different version: cargo install wasm-bindgen-cli --version 0.2.127 --locked;

    • a clang that can emit WebAssembly (the BLS library compiles C for wasm). Apple's clang cannot: on macOS run brew install llvm (the build scripts pick it up). On Linux the distribution's clang works.

  • Network access during the build: cargo downloads the crates and two git dependencies (cardananium/aiken, cardananium/dehosk), and npm install fetches the npm packages. The first wasm build compiles the Rust crates and can take several minutes.

git clone --recurse-submodules https://github.com/cardananium/cardano-debug-mcp.git
cd cardano-debug-mcp
npm run build:deps   # builds the debugger and decompiler wasm (git submodule deps/de-uplc-web)
npm install
npm run build        # -> dist/server.js
node dist/server.js --check   # verifies the install, exit code 0 = fine

Platforms: developed on macOS. Linux should work the same way (the wasm build scripts have a Linux path). Windows is only supported through WSL2.

Add it to Claude Code

With the npm install:

claude mcp add --scope user cardano-debug -- cardano-debug-mcp
# without installing it first (fetched on the first start, which then takes longer):
claude mcp add --scope user cardano-debug -- npx -y @cardananium/cardano-debug-mcp

From a source checkout:

claude mcp add --scope user cardano-debug -- node /path/to/cardano-debug-mcp/dist/server.js

Use an absolute path for a source checkout. --scope user makes the server available in every project. Without it Claude Code adds it to the current project only (local scope, kept in ~/.claude.json); --scope project writes a .mcp.json that you can commit.

In the commands below, replace node /path/to/cardano-debug-mcp/dist/server.js by cardano-debug-mcp for the npm install.

The public Koios API works without a key but is rate limited: loading several transactions by hash in a row, or a large one, can hit the limit (the server then answers rate_limited and says what to do). For regular use get an API key from Koios (koios.rest) or a project id from Blockfrost (blockfrost.io):

claude mcp add --scope user --env KOIOS_API_KEY=... cardano-debug -- node /path/to/cardano-debug-mcp/dist/server.js
# or Blockfrost (one project id per network: _MAINNET, _PREPROD, _PREVIEW)
claude mcp add --scope user --env BLOCKFROST_PROJECT_ID_MAINNET=... --env CARDANO_DEBUG_PROVIDER=blockfrost cardano-debug -- node /path/to/cardano-debug-mcp/dist/server.js

Or in .mcp.json (for the npm install use "command": "cardano-debug-mcp" and drop args):

{
  "mcpServers": {
    "cardano-debug": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/cardano-debug-mcp/dist/server.js"],
      "env": { "KOIOS_API_KEY": "${KOIOS_API_KEY:-}" },
      "timeout": 600000
    }
  }
}

Keep the :- in ${KOIOS_API_KEY:-}. When the variable is not set, a bare ${KOIOS_API_KEY} is passed to the server as that literal text, which Koios rejects as a key (HTTP 401); with :- the key is empty and the server runs anonymously. timeout is the limit of one tool call in milliseconds; the environment variables MCP_TOOL_TIMEOUT (tool calls) and MCP_TIMEOUT (server start-up) set the defaults.

Start a new Claude Code session, then check with claude mcp list or /mcp that cardano-debug is connected. Other clients: the next section.

Add it to other MCP clients

The server speaks MCP over stdio and takes no arguments, so any client that can start a stdio server can use it. The command is cardano-debug-mcp (npm install) or node /absolute/path/to/cardano-debug-mcp/dist/server.js (source checkout); the settings in Configuration, such as KOIOS_API_KEY, go in the client's env for the server. The examples use the npm install.

Codex (CLI and IDE extension):

codex mcp add cardano-debug -- cardano-debug-mcp
# with a Koios key
codex mcp add cardano-debug --env KOIOS_API_KEY=... -- cardano-debug-mcp
codex mcp list

Or in ~/.codex/config.toml (a project can keep its own .codex/config.toml, which Codex reads for projects you have marked as trusted):

[mcp_servers.cardano-debug]
command = "cardano-debug-mcp"
startup_timeout_sec = 30
tool_timeout_sec = 180
env = { KOIOS_API_KEY = "..." }

Codex stops a tool call after 60 s by default; a long validation, decompilation or debug_run can take longer, so raise tool_timeout_sec.

Cursor: ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

{ "mcpServers": { "cardano-debug": { "command": "cardano-debug-mcp" } } }

VS Code (GitHub Copilot, agent mode): .vscode/mcp.json in the workspace. The top-level key is servers, not mcpServers:

{ "servers": { "cardano-debug": { "type": "stdio", "command": "cardano-debug-mcp" } } }

Gemini CLI: ~/.gemini/settings.json (or .gemini/settings.json in a project):

{ "mcpServers": { "cardano-debug": { "command": "cardano-debug-mcp" } } }

Claude Desktop: claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows), then restart the app:

{ "mcpServers": { "cardano-debug": { "command": "cardano-debug-mcp" } } }

Notes for all of them:

  • Apps started from a launcher or the Dock often do not see your shell PATH (an nvm install, for example). If the client cannot find cardano-debug-mcp, put the absolute path from which cardano-debug-mcp in command, or use node with the absolute path of dist/server.js.

  • Windows is only supported through WSL2, as above: run the client and the server in the same place.

  • The prompts (/cardano-debug:debug_tx and so on) are how Claude Code lists MCP prompts; other clients show them in their own way or not at all. The tools do not depend on them. Clients also differ in how much of the server's built-in instructions they hand to the model: the tool descriptions and the docs tool carry the same routing.

  • Check the connection in the client (codex mcp list, the MCP settings of Cursor or VS Code), or run cardano-debug-mcp --check in a terminal.

Tools

Tool

What it does

tx_load

Load a transaction from CBOR, a tx hash (fetched from Koios / Blockfrost) or a saved bundle; returns a tx_id for the other tools

tx_inspect

Browse a loaded transaction by section: inputs, outputs, redeemers, scripts, datums, certificates, governance…

tx_validate

Phase-1 and phase-2 validation with per-redeemer budgets and the reasons a transaction is rejected

tx_redeemer

One redeemer in detail: error, traces, script context, script, links

tx_add_witnesses

Add vkey witnesses and validate again

bundle_export

Save a transaction with its chain context for offline replay

debug_open

Start a CEK debugging session for a redeemer, for a script with arguments, or for a bare program; reopen rebuilds a lost session

debug_run

Run until the error, the end, a term, a line, a trace, a builtin or a budget; breakpoints; stop_before for the state just before a failure

debug_inspect

Look at the machine: position, frames, environment, values, script context, traces, budget

debug_source

The UPLC listing around the current position, or a search in it (find)

debug_profile

Where the budget goes: hot terms, lines and builtins

debug_close

Close sessions

script_decompile

A script as readable pseudocode (or as UPLC)

script_locate

Translate between term ids and UPLC lines

cbor_decode

Decode any bytes as a ledger type, raw CBOR with byte spans, or "closest match"; as='spans' lists every node's offset

cbor_validate

Check CBOR against a CDDL schema (the ledger's Shelley to Conway schemas and the upcoming Dijkstra one are built in) with byte offsets and hints

cddl_check

Check that a CDDL schema parses and resolves; outline and rule lookup

ui_link

Build a link into cquisitor or de-uplc-web that highlights the problem with hints (a long link is also saved to link_file); optionally open it in the browser

docs

Built-in reference for the assistant (see below)

Larger results are also available as cardano-debug:// resources (decoded transactions, script contexts, UPLC listings, pseudocode, profiles, CDDL schemas…).

A tool rejects an argument it does not have and names the valid ones (with a "did you mean"), so a misspelled or invented argument is never silently ignored.

Built-in knowledge

The server carries reference docs written for the assistant, so it does not have to guess: transaction anatomy, ScriptContext and script arguments, UPLC and the CEK machine, validation errors (a catalogue of every error and warning the validator reports), a debugging playbook, and CBOR / CDDL diagnostics. The assistant reads them with the docs tool, one section at a time. Only as a last resort, when the docs and tools leave a deciding question open (for example the chain disagrees with the validator), it is told to read the cardano-ledger source.

After explaining why a transaction, script or bytes fail, the assistant offers to show the spot in cquisitor or de-uplc-web (a byte offset, a field of a big transaction, a UPLC term, a branch of a script), and builds and opens the link when you agree, or at once when you ask to see it. Governance action ids are shown as CIP-129 gov_action1… with a Cardanoscan link.

Prompts

Prompt

Use it to

debug_tx

find out why a transaction fails, step by step

explain_script

explain what a script checks

replay_bundle

debug a saved bundle offline

diagnose_cbor

explain what is wrong with some bytes

In Claude Code they appear as /cardano-debug:debug_tx and so on.

Configuration

All settings are environment variables; none is required. Numbers are plain digits (90000, not 90s or 60_000); a value that cannot be read, or that is out of range, is reported on stderr and replaced by the default (or cut to the maximum).

Variable

Meaning

Default

KOIOS_API_KEY

Koios API key (empty = anonymous)

anonymous

BLOCKFROST_PROJECT_ID_MAINNET / _PREPROD / _PREVIEW

Blockfrost project ids

unset

CARDANO_DEBUG_PROVIDER

koios or blockfrost

koios

CARDANO_DEBUG_OFFLINE

1 or true: never call a provider (bundles, the cache and CBOR input still work)

unset

CARDANO_DEBUG_CACHE_DIR

disk cache for chain data and bundles (see Chain data cache)

~/.cache/cardano-debug-mcp

CARDANO_DEBUG_CQUISITOR_URL

cquisitor instance links point at

https://cardananium.github.io/cquisitor

CARDANO_DEBUG_DE_UPLC_URL

de-uplc-web instance links point at

https://cardananium.github.io/de-uplc-web

CARDANO_DEBUG_NO_OPEN

1 or true: ui_link never opens a browser

unset

CARDANO_DEBUG_LOG

debug for verbose logs (stderr)

info

Variable

Meaning

Default and range

CARDANO_DEBUG_KOIOS_URL_MAINNET / _PREPROD / _PREVIEW

Koios endpoint override (e.g. self-hosted)

public Koios

CARDANO_DEBUG_BLOCKFROST_URL_MAINNET / _PREPROD / _PREVIEW

Blockfrost endpoint override

public Blockfrost

CARDANO_DEBUG_EVAL_TIMEOUT_MS

time limit for one validation

90000 (1 to 300000)

CARDANO_DEBUG_LIB_TIMEOUT_MS

time limit for other library calls

10000 (1 to 120000)

CARDANO_DEBUG_RUN_TIMEOUT_MS

default debug_run / debug_profile time limit

60000 (1 to 110000)

CARDANO_DEBUG_DECOMPILE_TIMEOUT_MS

time limit for one decompilation

120000 (1 to 300000)

CARDANO_DEBUG_WORKER_READY_TIMEOUT_MS

time a worker may take to load its wasm

60000 (1 to 300000)

CARDANO_DEBUG_TX_STORE_MAX

loaded transactions kept

32 (1 to 1024)

CARDANO_DEBUG_SESSION_MAX

open debugging sessions kept

8 (1 to 64)

CARDANO_DEBUG_WORKER_HEAP_MB

heap limit per worker

1024 (128 to 8192)

CARDANO_DEBUG_MAX_MESSAGE_BYTES

largest JSON-RPC message accepted

134217728 (1048576 to 1073741824)

API keys are read only from the environment and never echoed back.

Chain data cache

Everything fetched from Koios or Blockfrost is cached under CARDANO_DEBUG_CACHE_DIR, per provider:

  • transaction bytes fetched by hash: kept for good;

  • the last live chain context of each loaded transaction, saved as a bundle (also the files bundle_export writes): kept for good and removed last. This is how a pending transaction that is not on chain yet survives a restart;

  • the chain context a validation reads: 1 hour (10 minutes while the transaction is not on chain);

  • UTxO rows: 10 minutes. Other provider rows (accounts, pools, DReps…): 5 minutes. The latest epoch parameters: 1 hour; the parameters of one past epoch: for good.

The cache is limited to 512 MB: the least recently modified files go first, bundles last. It is only an accelerator, so deleting the directory is always safe.

Pass refresh=true to tx_load or tx_validate to bypass every cache and fetch again. Use it when a transaction that was pending has been confirmed since, when its inputs were spent or created after you first loaded it (a cached context keeps the tip slot and spent flags of that moment), or to retry after a provider error.

Troubleshooting

  • Logs. The server logs to stderr; stdout carries only JSON-RPC. Start Claude Code with claude --debug to see the messages of MCP servers, or run node dist/server.js in a terminal to see its start-up messages (it then waits for JSON-RPC on stdin; press Ctrl-D to quit).

  • The server does not connect. claude mcp list or /mcp in Claude Code shows its status. Run cardano-debug-mcp --check (from source: node /path/to/cardano-debug-mcp/dist/server.js --check): it verifies the Node version, the build files and wasm, the cache directory, the provider configuration and that the library worker starts, prints one line each, and exits 1 on any failure. A missing or stale dist/ (after git pull, or a build that stopped half way) is fixed by npm run build:deps && npm run build. The server itself prints one such line and exits when the build is incomplete.

  • Which build is running. node dist/server.js --version prints the package version, the build time, the commit and the de-uplc-web / dehosk revisions; the same is in the cardano-debug://server/info resource.

  • Old behaviour after an update. The server is a long-running process: restart Claude Code (or reconnect the server in /mcp) after every npm run build.

  • "unknown parameter …". A tool refuses an argument it does not have and lists the valid ones; the assistant normally corrects itself on the next call.

  • Answers come back as a file reference. Claude Code limits one tool result to 25,000 tokens by default: narrow the request (the tools page with offset / limit and zoom with path / depth, and the assistant knows to use them) or raise MAX_MCP_OUTPUT_TOKENS.

  • rate_limited, or provider_error on a load by hash. The public Koios API is throttled and can be overloaded. Get an API key from Koios (KOIOS_API_KEY) or a project id from Blockfrost (BLOCKFROST_PROJECT_ID_MAINNET / _PREPROD / _PREVIEW, with CARDANO_DEBUG_PROVIDER=blockfrost or provider=blockfrost in the call), set it in the server's environment and restart the server. Without any key you can still load a transaction from a bundle (CARDANO_DEBUG_OFFLINE=1).

Update

From npm:

npm update -g @cardananium/cardano-debug-mcp
cardano-debug-mcp --check

From source:

git pull
git submodule update --init
npm install
npm run build:deps   # needed when deps/de-uplc-web moved; harmless otherwise
npm run build
node dist/server.js --check

Then restart Claude Code. (From source, npm run build empties dist/ first: close Claude Code sessions that use this checkout before building.)

Uninstall

claude mcp remove cardano-debug              # add --scope user if you added it with that scope
rm -rf ~/.cache/cardano-debug-mcp            # the chain data cache (or your CARDANO_DEBUG_CACHE_DIR)
npm uninstall -g @cardananium/cardano-debug-mcp   # if you installed it from npm

Other clients: delete the cardano-debug entry from the file you added it to (codex mcp remove cardano-debug in Codex). For a source install, delete the cloned repository.

How it works

Each engine (validator, debugger, decompiler) runs in its own worker thread behind a watchdog, so a wasm crash or a runaway script never takes the server down. Chain data is fetched from Koios or Blockfrost with retries and cached on disk; a transaction fetched by hash is replayed against the chain state at the point it was included. Debugger positions are {term_id, uplc_line} in one canonical UPLC listing per script, and the stepper uses the same protocol version and cost models as the validator, so its budget matches the validator's on the same path. When the client closes stdin the server still answers the calls it already received (for up to 5 seconds), stops the workers and exits; on SIGTERM or SIGINT it stops the workers and exits at once.

Development

npm test             # builds, then the unit tests and the end-to-end tests over stdio
npm run test:unit    # builds first (some unit tests start the built workers)
npm run test:e2e     # builds first
npm run typecheck
npm run dev          # run from source with tsx (Node ≥ 22.12)
npm run smoke        # starts dist/server.js and checks the tool list, a debugging session and a decompile; exit 1 on any failure
node dist/server.js --check
npx @modelcontextprotocol/inspector node dist/server.js

Running the tests: the test commands rebuild dist/ (it is emptied first), so do not run them while an MCP client uses the server from the same checkout. The tests start the server with a clean environment (your KOIOS_*, BLOCKFROST_* and CARDANO_DEBUG_* variables are not passed on) and a scratch cache. No test calls a chain API: tests that load a transaction by hash talk to a local Koios stub (test/helpers/koiosStub.ts). The Node 20 compatibility run needs Node 20.14.0 under nvm, or CARDANO_DEBUG_E2E_NODE20=/path/to/node; without it that run is reported as skipped.

Test data (transactions, scripts, addresses and chain snapshots) is built by the toolkit in test/fixtures/synthetic (deterministic keys, validator-fitted fees and ex-units, scripts written in Aiken and UPLC) and described by test/fixtures/manifest.json; tests read hashes and numbers from the manifest. npm run fixtures:build regenerates the files, npm run fixtures:check verifies that the committed ones are up to date, npm run fixtures:compile recompiles the scripts (needs two Aiken compilers, see test/fixtures/synthetic/README.md).

To use a newer de-uplc-web, check out the commit in deps/de-uplc-web, then run npm run build:deps && npm run build.

License

Apache-2.0. The bundled ledger CDDL schemas come from cardano-ledger (Apache-2.0); see NOTICE and src/assets/cddl/ATTRIBUTION.md.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI assistants to query and analyze AI agent sessions from observability providers like Shepherd (AIOBS) and Langfuse, allowing users to debug agent runs, compare sessions, track performance, and analyze LLM usage patterns.
    18
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to perform step-through debugging of Python, JavaScript/Node.js, and Rust programs using the Debug Adapter Protocol, with support for breakpoints, variable inspection, and stack traces.
    28
    173
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to debug code inside VS Code by setting breakpoints, stepping through execution, inspecting variables, and evaluating expressions across multiple languages.
    551
    MIT