# Mina Mcp Server

> Query Mina Protocol: accounts, blocks, transactions, zkApp events/actions, archive SQL, Rosetta.

- **Type:** MCP server
- **Install:** `agentstack add mcp-minaprotocol-mina-mcp-server`
- **Verified:** Pending review
- **Seller:** [MinaProtocol](https://agentstack.voostack.com/s/minaprotocol)
- **Installs:** 0
- **Latest version:** 0.7.1
- **License:** Apache-2.0
- **Upstream author:** [MinaProtocol](https://github.com/MinaProtocol)
- **Source:** https://github.com/MinaProtocol/mina-mcp-server

## Install

```sh
agentstack add mcp-minaprotocol-mina-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# mina-mcp-server

[](https://www.npmjs.com/package/@o1-labs/mina-mcp-server)
[](LICENSE)
[](https://modelcontextprotocol.io)

MCP (Model Context Protocol) server for the [Mina Protocol](https://minaprotocol.com/) blockchain. Exposes Mina blockchain data and operations through MCP-compatible tools that can be used by AI assistants and other MCP clients.

**New here?** Jump to [Which mode do I want?](#which-mode-do-i-want) → [Connect your MCP client](#connect-your-mcp-client) → [Verify it works](#verify-it-works). For copy-paste prompts, see the [prompt cookbook](docs/examples.md).

> **Status: beta / preview.** **Live mode** talks to public Mina networks (devnet / mainnet / mesa) and needs **no local infrastructure** — run `npx @o1-labs/mina-mcp-server --mode live --network devnet`, or point your client at the [hosted sandbox](#deploying-on-flyio). **Snapshot** and **tutorial** modes are thin MCP layers over backing services (PostgreSQL, and for tutorial a local Mina lightnet) that you must stand up yourself first — see [Prerequisites](#prerequisites). A bundled SQLite snapshot for zero-infra *snapshot* mode is planned ([#28](https://github.com/MinaProtocol/mina-mcp-server/issues/28)).

## Features

- **40+ MCP tools** for querying accounts, blocks, transactions, zkApp events/actions, network/sync status, Rosetta, and archive SQL.
- **Three operating modes:**
  - **Live** — read-only proxy to a public Mina network (devnet/mainnet/mesa). **No local infra** — the zero-setup default.
  - **Tutorial** — full read/write against a local Mina lightnet (daemon, archive, test-account faucet).
  - **Snapshot** — schema-only SQL access (`query_archive_sql`, `get_archive_schema`) against a frozen archive Postgres dump.
- **Standardized Rosetta** Data API tools (live mode) alongside the native GraphQL ones.
- **Safe SQL access** — read-only queries against the archive DB with timeout protection.
- **Test-account faucet** — acquire/release pre-funded accounts (tutorial mode).
- **[Prompt cookbook](docs/examples.md)** — copy-paste prompts that drive end-to-end tool sequences.

## Which mode do I want?

| You want to… | Mode | Infra needed |
|---|---|---|
| **Query a public network** (balances, blocks, zkApp events, Rosetta) | **`live`** | None — just `npx`. **Start here.** |
| **Send transactions on a public network** with your own keys | **`live` + `--wallets`** | None (keys signed in-process) |
| **Develop against a controllable chain** (faucet, reset, write) | **`tutorial`** | Local Mina lightnet ([Prerequisites](#prerequisites)) |
| **Run analytics SQL over a historical archive dump** | **`snapshot`** | A Postgres archive dump ([Prerequisites](#prerequisites)) |

Most people want **`live`** — it needs nothing installed beyond Node.

## Connect your MCP client

**Local (recommended), via `npx` — no clone, no infra:**

```json
{
  "mcpServers": {
    "mina": {
      "command": "npx",
      "args": ["-y", "@o1-labs/mina-mcp-server", "--mode", "live", "--network", "devnet"]
    }
  }
}
```

Swap `devnet` for `mainnet` or `mesa`. For other modes, change `--mode` (and drop `--network`); see [Configuration](#configuration).

**Hosted sandbox (zero install) — point your client at the URL:**

```json
{ "mcpServers": { "mina": { "url": "https://mina-mcp-sandbox.fly.dev/mcp" } } }
```

The hosted sandbox runs **tutorial mode** against a shared lightnet (best-effort, no SLA). Use local `live` mode for real networks.

**Where the config lives, per client:**

| Client | Config | Notes |
|---|---|---|
| Claude Desktop | `claude_desktop_config.json` (Settings → Developer) | `command`/`args` shape above |
| Claude Code | `.mcp.json` in the project, or `claude mcp add` | same shape |
| Cursor | `~/.cursor/mcp.json` (or Settings → MCP) | same shape |
| Cline / Roo | the extension's MCP settings JSON | same shape |
| Windsurf | `~/.codeium/windsurf/mcp_config.json` | same shape |
| Continue | `~/.continue/config.json` under `mcpServers` | same shape |
| Zed | `settings.json` under `context_servers` | Zed uses `"command": { "path": "npx", "args": [...] }` |

All clients except Zed take the same `{ command, args }` object; only the file location differs. Hosted-URL configs work in any client that supports a remote/streamable-HTTP MCP server.

## Verify it works

After wiring it up, ask your assistant:

> **"Describe the current Mina network state."**

It should call `describe_state` and return a snapshot with `syncStatus` (e.g. `SYNCED`), the network name, and mempool size. That's your green light. (On `mesa`, expect a `PREFLIGHT` caveat in the hints.)

## Configuration

All flags have environment-variable equivalents; run `npx @o1-labs/mina-mcp-server --help` for the full surface.

```
$ mina-mcp-server --help
USAGE
  mina-mcp-server [--mode ] [options]

MODES
  live        Read-only proxy to a public network. No local infra. (use --network)
  tutorial    Read+write against a local Mina lightnet (daemon + archive + faucet).
  snapshot    Schema-only SQL access against a frozen archive Postgres dump. (default)
```

| Flag | Env var | Values (default) |
|---|---|---|
| `--mode` | `MINA_MCP_MODE` | `live` / `tutorial` / `snapshot` (`snapshot`) |
| `--network` | `MINA_MCP_NETWORK` | `devnet` / `mainnet` / `mesa` / `mesa-mut` (live only) |
| `--transport` | `MINA_MCP_TRANSPORT` | `stdio` / `http` (`stdio`) |
| `--wallets` | `MINA_MCP_WALLETS` | path to `wallets.json` (live-write) |
| `--allow-mainnet-writes` | `MINA_MCP_ALLOW_MAINNET_WRITES=1` | opt-in gate for mainnet sends |
| _(http only)_ | `MINA_MCP_HTTP_PORT` | port for `--transport http` (`3000`) |
| `--help`, `--version` | — | print help / version and exit |

## Troubleshooting

| Symptom | Fix |
|---|---|
| `npx` fails / "Unsupported engine" | Needs **Node ≥ 20.18**. Check `node --version`. |
| Tools return "not reachable" in `tutorial`/`snapshot` | The server does **not** start infra — bring up the lightnet/Postgres first ([Prerequisites](#prerequisites)). |
| Port already in use (`tutorial` lightnet) | Another lightnet/daemon is bound to 3085/8282/5432; stop it or remap ports. |
| Changes not taking effect after editing source | Re-run `npm run build` (the client runs `dist/`, not `src/`). |
| Hosted server: "Missing/!Unknown session id" | Your client must echo the `Mcp-Session-Id` header from `initialize` on every request — use a client that supports streamable-HTTP MCP. |
| `mesa` data looks unstable | `mesa` is a **preflight** network — it can reset/rename without notice. Treat its data as ephemeral. |

## Prerequisites

> Only needed for **`tutorial`** and **`snapshot`** modes. **`live` mode needs none of this.**

**Common:**

- Node.js >= 20.18
- Docker & Docker Compose (to run the backing services below)

**Snapshot mode additionally requires:**

| Component | Purpose | Default endpoint |
|-----------|---------|------------------|
| PostgreSQL with Mina archive schema + data | Source of all read queries | `localhost:5432` |

You can bring this up with `docker-compose.snapshot.yml` (ships in the repo). A snapshot dump under `./snapshots/devnet-latest` — or downloaded via the compose `download` profile — is required.

**Tutorial mode additionally requires** a full local lightnet:

| Component | Purpose | Default endpoint |
|-----------|---------|------------------|
| Mina Daemon GraphQL | Live chain queries, sending payments | `http://localhost:3085/graphql` |
| Archive-Node-API | zkApp events/actions, archive blocks | `http://localhost:8282` |
| Accounts Manager | Test account faucet | `http://localhost:8181` |
| PostgreSQL (archive DB) | Read queries | `localhost:5432` |

All four are brought up by `docker-compose.tutorial.yml`. Expect ~1–2 minutes for the network to sync before tools respond correctly.

> **Note:** if you install from npm (`npx @o1-labs/mina-mcp-server`), the docker-compose files are *not* included in the tarball — you will need to clone this repo, or copy the `docker-compose.*.yml` files out of it, to start the infra.

## Quick Start

```bash
# Install dependencies
npm install

# Build
npm run build

# Start infrastructure (pick one):

# Option A: Snapshot mode (read-only, from local dump)
SNAPSHOT_DIR=./snapshots/devnet-latest docker compose -f docker-compose.snapshot.yml up -d

# Option B: Snapshot mode (download latest dump from GCS — devnet by default)
docker compose -f docker-compose.snapshot.yml --profile download up -d
#   See "Snapshot mode against other public networks" below for mainnet/mesa.

# Option C: Tutorial mode (full lightnet)
docker compose -f docker-compose.tutorial.yml up -d
# Wait ~1-2 min for the network to sync

# Option D: Live mode (read-only, talks to a public Mina network — no local infra)
#   Picks a network with --network (devnet, mainnet, mesa). Nothing else to start.

# Run the MCP server
MINA_MCP_MODE=snapshot npm start                              # or
MINA_MCP_MODE=tutorial npm start                              # or
npm start -- --mode live --network devnet                     # no Postgres / lightnet needed
```

### Live mode against a public Mina network

Live mode is a thin read-only proxy that turns MCP tool calls into GraphQL/HTTP requests against the o1Labs-hosted public endpoints. There is **nothing to host** — run it locally next to your MCP client:

```bash
npm start -- --mode live --network devnet     # or mainnet, mesa
# equivalently:
MINA_MCP_MODE=live MINA_MCP_NETWORK=devnet npm start
```

Endpoints are best-effort services without SLAs and URLs are subject to change. Networks are classified by **stability tier**:

| Network | Stability | What it means |
|---|---|---|
| `devnet` | stable | Long-lived dev network. Expected to stick around. |
| `mainnet` | stable | Production. Expected to stick around. |
| `mesa` | **preflight** | Preview/staging network. **May be reset, renamed, or retired without notice.** Endpoints, archive-dump filenames, and even the network identity itself are not guaranteed stable. |
| `mesa-mut` | **preflight** | [Mesa Upgrade Test](https://mesa-upgrade-tracker.minaprotocol.com/status.json) — a fork of mainnet state for rehearsing the Mesa hardfork. **Tied to the upgrade rehearsal; will be reset/retired without notice.** Genesis is a mainnet-state fork, but the daemon reports networkID `mina:testnet` (testnet signature schema). No Rosetta endpoint, no faucet, and no published archive dump (snapshot mode unavailable). |

When a `LiveProvider` is constructed against a preflight network, the server emits a `[WARN] Network '' is a PREFLIGHT network…` line at startup and prepends a `PREFLIGHT` hint to `describe_state`'s `hints[]` — so any LLM consuming the output sees the caveat before reasoning about the data. If you build downstream automation against a preflight network, treat any data you gather as ephemeral and have a fallback to a stable network.

### Rosetta Data API (live mode)

When a live-mode network has a Rosetta endpoint configured (`devnet`, `mainnet`, and `mesa` do today; `mesa-mut` does not), the server registers five Rosetta Data API tools alongside the daemon/archive ones. On a network without a Rosetta endpoint the `rosetta_*` tools are not registered at all, so the advertised tool list reflects what the network can actually do. These return responses in **standardized Rosetta format** — useful for LLMs and integrations that already speak Rosetta:

| Tool | Rosetta endpoint | Use |
|---|---|---|
| `rosetta_status` | `POST /network/status` | Current / genesis / oldest block, sync state |
| `rosetta_account` | `POST /account/balance` | Balance for an address, optionally at a specific block |
| `rosetta_block` | `POST /block` | Full block (with operations) by index or hash |
| `rosetta_mempool` | `POST /mempool` | Pending transaction identifiers |
| `rosetta_mempool_transaction` | `POST /mempool/transaction` | A single pending tx with operations |

Construction API (offline signing flow) is intentionally not included in this set; it's a follow-up with its own tool-shape design (macro-vs-literal).

Each network also carries optional pointers that the MCP server doesn't proxy itself but surfaces via `describe_state.hints[]` so an LLM can hand them to a human or a Rosetta-aware client:

| Network | Faucet | Rosetta |
|---|---|---|
| `devnet` | https://faucet.minaprotocol.com | https://devnet-rosetta.gcp.o1test.net |
| `mainnet` | _(none — exchanges only)_ | https://mainnet-rosetta.gcp.o1test.net |
| `mesa` | https://faucet.minaprotocol.com | https://rosetta.mina-mesa-network.gcp.o1test.net |
| `mesa-mut` | _(none — mainnet-state fork)_ | _(none)_ |

### Mesa hardfork upgrade tracking (`mesa-mut`)

`mesa-mut` rehearses the **Mesa hardfork upgrade**. On `--network mesa-mut` the server
registers an extra tool, **`get_upgrade_status`**, which joins the upgrade tracker
([`status.json`](https://mesa-upgrade-tracker.minaprotocol.com/status.json)) with the
live daemon's current global slot to report the phase: current slot vs
`stopTransactionSlot` / `stopNetworkSlot`, slots/minutes remaining, the Mesa genesis
timestamp, and a `transactionsOpen` boolean with phase-aware `hints[]`. Check
`transactionsOpen` before submitting a send — transactions sent after
`stopTransactionSlot` are dropped.

For agent workflows, a companion Claude skill — [`.claude/skills/mesa-upgrade`](.claude/skills/mesa-upgrade/SKILL.md) —
wraps this tool with a per-phase operator runbook (what to do / not do before, during,
and after the fork).

### Live write mode (experimental — client-side signing)

Live mode can be promoted from read-only to read+write by handing the server one or more wallet keys. Sends are signed **in this process** with [`mina-signer`](https://www.npmjs.com/package/mina-signer) and submitted as pre-signed transactions to the daemon. No daemon-side wallet, no faucet on devnet/mainnet, no key material on the wire.

```bash
npm start -- --mode live --network devnet --wallets ./wallets.json
# equivalently:
MINA_MCP_MODE=live MINA_MCP_NETWORK=devnet MINA_MCP_WALLETS=./wallets.json npm start
```

> **EXPERIMENTAL — read this before pointing it at real value.**
> Wallet private keys are loaded **unencrypted** from disk into this process's memory. That's fine for ephemeral test wallets on devnet/mesa; it's **not** fine for production keys. Either:
> - only load wallets containing money you can afford to lose, **or**
> - don't use this mode for mainnet at all — use a hardware wallet or an offline signer for anything material.
>
> Pointing this at mainnet additionally requires `--allow-mainnet-writes` (or `MINA_MCP_ALLOW_MAINNET_WRITES=1`) as a deliberate speedbump against config typos.

**`wallets.json` schema**

```json
{
  "wallets": {
    "warm": {
      "keyPath": "/home/me/.mina/keys/warm.key",
      "publicKey": "B62q…",
      "caps": { "maxFeeNanomina": "100000000", "maxAmountNanomina": "5000000000" }
    },
    "demo": { "keyPath": "/home/me/.mina/keys/demo.key", "publicKey": "B62q…" }
  },
  "defaultWallet": "warm"
}
```

- `keyPath` files must contain exactly one `EK…` base58check private key (one line, no other content). Encrypted JSON key files are not supported in this revision.
- `keyPath` files **must** be `chmod 600`; the loader refuses to start otherwise.
- `publicKey` is verified at startup against the loaded key — catches "wrong key for this alias" mistakes before any tool runs.
- `caps` (optional, per wallet) bound a single transaction: `maxFeeNanomina` and `maxAmountNanomina` (decimal nanomina, 1 MINA = 1e9). A send exceeding a cap is **refused before signing** — a guardrail against a runaway/adversarial LLM draining a wallet. Memos are always capped at 32 bytes.
- `defaultWallet` is optional; if omitted, every `send_payment`/`send_delegation` call must pass `from_alias` or `from`.
- Paths may be relative to the config file's directory (so the whole bundle is portable).

**Tool surface added in live-write mode** (on top of the live-mode read tools):

| Tool | Descript

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [MinaProtocol](https://github.com/MinaProtocol)
- **Source:** [MinaProtocol/mina-mcp-server](https://github.com/MinaProtocol/mina-mcp-server)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Versions

- **0.7.1** — security scan: pending review — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-minaprotocol-mina-mcp-server
- Seller: https://agentstack.voostack.com/s/minaprotocol
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
