Skip to main content
Glama
JulioMCruz

StellarMCP

by JulioMCruz
README.md
# StellarMCP

[MCP](https://modelcontextprotocol.io) server for **Stellar**: accounts, payments, XDR, Horizon/Soroban RPC, AMM liquidity, SEP anchors, and Soroban (simulate, invoke, events, deploy, contract state). Intended for **agents and IDE integrations** (Cursor, Claude Desktop, etc.) with strict validation, normalized errors, and redacted `_debug` fields.

**All tools (names, descriptions, parameters):** **[`docs/TOOLS.md`](docs/TOOLS.md)** — auto-generated from the same `tools/list` your MCP client sees; attach or paste it when asking an agent *how to use this server*.

**Requirements:** Node.js **≥ 20**. · **Source:** [github.com/JulioMCruz/Stellar-mcp](https://github.com/JulioMCruz/Stellar-mcp)

---

## Table of contents

- [Quick start](#quick-start)
- [Sanity check (first call)](#sanity-check-first-call)
- [Run the server](#run-the-server)
- [Connect your MCP client](#connect-your-mcp-client)
- [Environment variables](#environment-variables)
- [Security](#security)
- [Tools reference](#tools-reference)
- [Example tool calls](#example-tool-calls)
- [Tools reference (detailed — docs/TOOLS.md)](docs/TOOLS.md)
- [PerkOS Stellar x402](#perkos-stellar-x402)
- [Stellar ZK proofs](#stellar-zk-proofs)
- [Soroban and Next.js scaffolds](#soroban-and-nextjs-scaffolds)
- [Soroban contract MCP generator](#soroban-contract-mcp-generator)
- [Troubleshooting](#troubleshooting)
- [Development & testing](#development--testing)

---

## Quick start

### From a clone (this repository)

```bash
git clone https://github.com/JulioMCruz/Stellar-mcp.git
cd Stellar-mcp
npm install
npm run build
```

Run the server (see [Run the server](#run-the-server)), then [connect your MCP client](#connect-your-mcp-client).

### From npm

**Package on npm:** `@juliomcruz/stellarmcp` (scoped package, when published).

The published tarball includes **`build/src`**, **`templates/`**, **generator inputs** (`src/lib/errors.ts`, `redact.ts`), **`.env.example`**, and docs — enough to run the server and `stellarmcp-generate` without cloning.

```bash
npm install @juliomcruz/stellarmcp
npx stellarmcp
# or: npx @juliomcruz/stellarmcp
```

- Env template: **`node_modules/@juliomcruz/stellarmcp/.env.example`** → copy to your project as `.env` if needed.
- MCP **stdio** when the package is a dependency (example): `"args": ["${workspaceFolder}/node_modules/@juliomcruz/stellarmcp/build/src/index.js"]`.

Prefer GitHub if you are **developing or patching** this repository ([clone](#from-a-clone-this-repository)).

---

## Sanity check (first call)

Use this to confirm wiring before deeper integration:

1. **HTTP mode:** with `MCP_TRANSPORT=http-sse` running, open `GET /health` (expect JSON with `network`, `horizonReachable`, `rpcReachable`).
2. **Any MCP host:** call tool **`stellar_get_fee_stats`** with **`{}`**. Expect fields like `baseFee`, `p99`, `recommendedFee` (see [Example tool calls](#example-tool-calls)).

If that works, Horizon is reachable and the server is usable for read-only tools without a secret key.

For **every tool name and argument shape**, use **[`docs/TOOLS.md`](docs/TOOLS.md)** (or your host’s MCP tool picker).

---

## Run the server


| Mode                | Command                                               | Notes                                                                                                               |
| ------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **stdio** (default) | `npm run start:stdio` or `node build/src/index.js`    | Best for Claude Desktop, Cursor stdio, local agents.                                                                |
| **Streamable HTTP** | `MCP_TRANSPORT=http-sse PORT=3000 npm run start:http` | MCP endpoint: `http://<host>:<PORT>/mcp`. Health: `GET /health` (JSON: network, Horizon/RPC reachability, version). |


After `npm run build`, the entrypoint is **`build/src/index.js`**.

---

## Connect your MCP client

### stdio (recommended locally)

Point your host at Node and the built entrypoint. Example shape (paths must be **absolute** or use your editor’s variable such as `${workspaceFolder}`):

```json
{
  "mcpServers": {
    "stellarmcp": {
      "type": "stdio",
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/stellarmcp/build/src/index.js"],
      "env": {
        "MCP_TRANSPORT": "stdio",
        "STELLAR_NETWORK": "testnet"
      }
    }
  }
}
```

- **Cursor:** project config `~/.cursor/mcp.json` or `.cursor/mcp.json` — see [Cursor MCP docs](https://cursor.com/docs/context/mcp) (interpolation: `${workspaceFolder}`, `${env:VAR}`).
- **Claude Desktop:** `claude_desktop_config.json` under the same `mcpServers` pattern.
- Optional: set `"envFile": "${workspaceFolder}/.env"` (stdio only in Cursor) to load secrets from a local `.env` **without** committing it.

**Never commit** real `STELLAR_SECRET_KEY` or anchor tokens.

### HTTP / SSE

1. Start the server with `MCP_TRANSPORT=http-sse` and choose `PORT`.
2. In the client, register the remote server, for example:

```json
{
  "mcpServers": {
    "stellarmcp": {
      "url": "http://localhost:3000/mcp"
    }
  }
}
```

3. Verify **`GET http://localhost:3000/health`** before debugging MCP calls.

When binding HTTP/SSE to anything other than loopback, set
`MCP_HTTP_AUTH_TOKEN` and send MCP requests with
`Authorization: Bearer <token>`. The server refuses non-loopback HTTP/SSE
startup without that token.

---

## Environment variables

**Authoritative template:** copy `[.env.example](./.env.example)` to `.env` and edit.


| Variable                         | Required | Purpose                                                                                          |
| -------------------------------- | -------- | ------------------------------------------------------------------------------------------------ |
| `MCP_TRANSPORT`                  | No       | `stdio` (default) or `http-sse`.                                                                 |
| `STELLAR_NETWORK`                | No       | `testnet` (default) or `mainnet`.                                                                |
| `STELLAR_HORIZON_URL`            | No       | Horizon base URL (**https**; host must be default-allowed or listed in `STELLAR_ALLOWED_HOSTS`). |
| `STELLAR_RPC_URL`                | No       | Soroban RPC URL (same rules as Horizon).                                                         |
| `STELLAR_SEP38_URL`              | No       | Anchor SEP-38 endpoint for quotes.                                                               |
| `STELLAR_ALLOWED_HOSTS`          | No       | Comma-separated extra hostnames allowed for the three URL vars above.                            |
| `STELLAR_TRUSTED_ANCHOR_DOMAINS` | No       | Comma-separated domains allowed for anchor/TOML and SEP flows.                                   |
| `STELLAR_SECRET_KEY`             | No       | Signing key; omit for read-only / unsigned-XDR-only operation.                                   |
| `STELLAR_AUTO_SIGN_POLICY`       | No       | `safe`, `guarded`, or `expert` — see [Security](#security).                  |
| `STELLAR_AUTO_SIGN`              | No       | Legacy if policy unset.                                                                          |
| `STELLAR_AUTO_SIGN_LIMIT`        | No       | Legacy / used with `guarded` (must be > 0).                                                      |
| `STELLAR_USDC_ISSUER`            | No       | USDC issuer for valuation in guarded signing (default is network USDC).                          |
| `PORT`                           | No       | HTTP server port (default `3000`).                                                               |
| `STELLAR_REQUEST_TIMEOUT_MS`     | No       | Upstream request timeout (max 30000).                                                            |
| `MCP_HTTP_*`                     | No       | Bind host, auth token, rate limit, concurrency, max POST body, `TRUST_PROXY` — see `.env.example`. |
| `STELLAR_META_*`                 | No       | Disk cache + XDR size limits for meta tools — see `.env.example`.                                |


Custom Horizon/RPC/SEP-38 URLs must use **https** and **non-private** hosts; unknown hosts require `STELLAR_ALLOWED_HOSTS`.

---

## Security

1. **Secrets:** Treat `STELLAR_SECRET_KEY` like production key material. Prefer env or `envFile`; never commit secrets; restrict file permissions on `.env`.
2. **Auto-sign policy** (write tools: payments, trustlines, liquidity, `set_options`, fee bump, Soroban invoke/deploy, relevant SEP flows):
   - **`safe`** (recommended): unsigned mode — write tools return **unsigned XDR** for external signing when applicable.
   - **`guarded`**: auto-sign enabled only with **`STELLAR_AUTO_SIGN_LIMIT` > 0** and USDC-based valuation rules; fails closed when value cannot be bounded.
   - **`expert`**: unlimited auto-sign — use only with full awareness of risk.
3. **Network exposure:** Keep HTTP/SSE bound to `127.0.0.1` unless you have a reason to expose it. If you expose HTTP/SSE, set `MCP_HTTP_AUTH_TOKEN`, use TLS in front, sane firewall rules, and review `MCP_HTTP_*`. **`MCP_HTTP_TRUST_PROXY=true`** only behind a **trusted** proxy that sets `X-Forwarded-For` correctly.
4. **Allowlists:** Use `STELLAR_ALLOWED_HOSTS` and `STELLAR_TRUSTED_ANCHOR_DOMAINS` when pointing at non-default infrastructure or anchors.
5. **Read-only deployments:** Omit `STELLAR_SECRET_KEY`; read and simulate tools still work; writes yield unsigned payloads or explicit errors.

---

## Tools reference

**Full detail for agents (every tool, descriptions, parameter tables from live `tools/list`):** **[`docs/TOOLS.md`](docs/TOOLS.md)** — auto-generated; refresh with `npm run docs:tools` after you change tools.

Summary below: **Read** = no transaction submission by this server; **Write** = may build/submit transactions, call Friendbot, or initiate anchor flows.

### Accounts & history


| Tool                          | Type  | Description                                                                       |
| ----------------------------- | ----- | --------------------------------------------------------------------------------- |
| `stellar_get_account`         | Read  | Balances, signers, flags, subentries, minimum balance.                            |
| `stellar_get_account_history` | Read  | Paginated transaction history (`limit`, optional `cursor`).                       |
| `stellar_fund_account`        | Write | **Testnet only** — funds via Friendbot HTTP (10k test XLM).                       |
| `stellar_generate_test_wallet` | Write | Generate a testnet wallet and optionally fund it with Friendbot.                 |
| `stellar_set_options`         | Write | Account options (signers, weights, flags); unsigned unless policy allows signing. |


### Payments & fees


| Tool                                  | Type  | Description                                          |
| ------------------------------------- | ----- | ---------------------------------------------------- |
| `stellar_submit_payment`              | Write | Payment; hash or unsigned XDR per policy.            |
| `stellar_submit_fee_bump_transaction` | Write | Fee-bump an existing transaction (sponsor pays fee). |


### Assets & AMM


| Tool                         | Type  | Description                            |
| ---------------------------- | ----- | -------------------------------------- |
| `stellar_create_trustline`   | Write | Create trustline for non-native asset. |
| `stellar_deposit_liquidity`  | Write | Deposit into classic AMM pool.         |
| `stellar_withdraw_liquidity` | Write | Withdraw from classic AMM pool.        |


### Network


| Tool                    | Type | Description                            |
| ----------------------- | ---- | -------------------------------------- |
| `stellar_get_fee_stats` | Read | Fee stats + recommended fee (stroops). |


### XDR


| Tool                      | Type | Description                                                          |
| ------------------------- | ---- | -------------------------------------------------------------------- |
| `stellar_xdr_types`       | Read | List XDR type names (optional `prefix`).                             |
| `stellar_xdr_json_schema` | Read | Draft-7 JSON Schema for a type.                                      |
| `stellar_xdr_guess`       | Read | Candidate types for a base64 XDR blob.                               |
| `stellar_xdr_encode`      | Read | JSON → base64 XDR for a named type.                                  |
| `stellar_decode_xdr`      | Read | Classic transaction XDR → JSON (uses configured network passphrase). |


### Historical meta (Horizon-first, Soroban RPC fallback, bounded XDR)


| Tool                           | Type | Description                                                         |
| ------------------------------ | ---- | ------------------------------------------------------------------- |
| `stellar_get_ledger_meta`      | Read | Closed ledger header/metadata XDR (+ optional cache metadata).      |
| `stellar_get_transaction_meta` | Read | Tx envelope/result/result-meta/fee-meta; optional `operationIndex`. |


### SEP / anchors


| Tool                        | Type  | Description                                                         |
| --------------------------- | ----- | ------------------------------------------------------------------- |
| `stellar_get_anchor_toml`   | Read  | Fetch/parse `stellar.toml` for SEP discovery.                       |
| `stellar_sep10_auth`        | Write | SEP-10 challenge → JWT (requires signer / secret where applicable). |
| `stellar_sep6_transfer`     | Write | SEP-6 deposit/withdraw initiation.                                  |
| `stellar_sep12_customer`    | Mixed | GET/PUT KYC against anchor SEP-12 server.                           |
| `stellar_sep24_interactive` | Write | SEP-24 interactive URL for deposit/withdraw.                        |
| `stellar_sep31_remittance`  | Write | SEP-31 remittance initiation.                                       |
| `stellar_get_sep38_quote`   | Read  | SEP-38 indicative quote / rate metadata.                            |


### Soroban


| Tool                         | Type  | Description                                                        |
| ---------------------------- | ----- | ------------------------------------------------------------------ |
| `stellar_soroban_simulate`   | Read  | Simulate contract call (footprint, fees, events); does not submit. |
| `stellar_soroban_invoke`     | Write | Simulate, assemble, sign/submit per policy.                        |
| `stellar_soroban_get_events` | Read  | Contract events from RPC (`startLedger`, filters, `limit`).        |
| `stellar_soroban_deploy`     | Write | Deploy WASM from disk path; submit per policy.                     |
| `stellar_soroban_read_state` | Read  | Direct `getLedgerEntries` for a contract data key.                 |


### Scaffolds


| Tool                                | Type  | Description                                                     |
| ----------------------------------- | ----- | --------------------------------------------------------------- |
| `stellar_soroban_scaffold_contract` | Write | Create a Rust Soroban contract workspace with tests and CLI docs. |
| `stellar_nextjs_wallet_scaffold`    | Write | Create Next.js Freighter wallet hook/component/env starter files. |
| `stellar_x402_perkos_guide`         | Read  | Return PerkOS/OpenZeppelin Stellar x402 architecture and rules.    |
| `stellar_x402_nextjs_scaffold`      | Write | Create a Next.js paid route and x402/Freighter payment client.     |
| `stellar_x402_oz_facilitator_scaffold` | Write | Create OpenZeppelin Relayer x402 facilitator config templates.  |
| `stellar_zkproof_guide`             | Read  | Return Stellar/Soroban ZK proof primitives, patterns, and safety rules. |


---

## Example tool calls

JSON shapes are illustrative; your MCP host sends `tools/call` with `name` + `arguments`.

### Fee stats (testnet)

```json
{ "name": "stellar_get_fee_stats", "arguments": {} }
```

### XDR: list types → schema → encode

```json
{ "name": "stellar_xdr_types", "arguments": { "prefix": "Transaction" } }
```

```json
{ "name": "stellar_xdr_json_schema", "arguments": { "type": "TransactionEnvelope" } }
```

```json
{ "name": "stellar_xdr_encode", "arguments": { "type": "TransactionEnvelope", "json": "<JSON string>" } }
```

```json
{ "name": "stellar_xdr_guess", "arguments": { "xdr": "<base64>" } }
```

```json
{ "name": "stellar_decode_xdr", "arguments": { "xdr": "<base64 classic transaction XDR>" } }
```

### Historical meta

```json
{ "name": "stellar_get_ledger_meta", "arguments": { "ledgerSequence": 123456, "maxXdrCharsPerField": 8192 } }
```

```json
{
  "name": "stellar_get_transaction_meta",
  "arguments": {
    "transactionHash": "<64-char hex>",
    "operationIndex": 0,
    "maxXdrCharsPerField": 8192
  }
}
```

For full argument schemas, use your client’s **tool list** / schema UI or inspect Zod definitions under `src/tools/`.

---

## PerkOS Stellar x402

This MCP understands the PerkOS Stellar x402 pattern from:

- `PerkOS-xyz/Stellar-x402-Demo`
- `PerkOS-xyz/Stellar-x402-Relayer`

The core flow is:

1. A client calls a paid API route.
2. The server returns HTTP 402 payment requirements.
3. The browser signs a Stellar auth entry through Freighter.
4. `@x402/fetch` retries with the `X-PAYMENT` header.
5. PerkOS Stellar Relayer verifies and settles through the OpenZeppelin Relayer x402 facilitator plugin.

Stellar USDC defaults:

- Pubnet: `stellar:pubnet`, `CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75`
- Testnet: `stellar:testnet`, `CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA`

Guide: [`docs/PERKOS_STELLAR_X402_GUIDE.md`](docs/PERKOS_STELLAR_X402_GUIDE.md).

Example:

```json
{ "name": "stellar_x402_perkos_guide", "arguments": {} }
```

```json
{
  "name": "stellar_x402_nextjs_scaffold",
  "arguments": {
    "outputDir": "./web",
    "appName": "quest_board"
  }
}
```

```json
{
  "name": "stellar_x402_oz_facilitator_scaffold",
  "arguments": {
    "outputDir": "./relayer"
  }
}
```

---

## Stellar ZK proofs

This MCP includes a read-only ZK guide for agents building with Stellar/Soroban.

Stellar's Protocol 25 / X-Ray work adds ZK-friendly host primitives for verifier contracts:

- BN254: `g1_add`, `g1_mul`, `pairing_check`
- Poseidon/Poseidon2: `poseidon`, `poseidon2`

These are verifier building blocks, not a complete privacy protocol. Agents should generate proofs off-chain with systems such as Noir, RISC Zero, Circom, or Reclaim/zkFetch-style services, then verify public inputs/proofs through Soroban contracts.

Example:

```json
{ "name": "stellar_zkproof_guide", "arguments": {} }
```

Agent rules:

- Keep witnesses/private inputs off-chain.
- Never invent proof bytes, verifying keys, trusted setup material, or private witness data.
- Bind proofs to network, contract id, statement version, domain, and public inputs.
- Test verifier contracts with known valid and invalid proof fixtures before UI wiring.
- Explain clearly in UI what remains private and what becomes public on-chain.

Primary references:

- Stellar docs: <https://developers.stellar.org/docs/build/apps/zk>
- DoraHacks Stellar Hacks ZK resources: <https://dorahacks.io/hackathon/stellar-hacks-zk/resources>
- Reclaim zkFetch Stellar example: <https://github.com/reclaimprotocol/zkfetch-stellar-example>

---

## Soroban and Next.js scaffolds

Two write tools turn this MCP server into a starter-kit assistant for Stellar apps:

- `stellar_soroban_scaffold_contract` creates a Rust `soroban-sdk` contract workspace using the current `wasm32v1-none` target flow and Stellar CLI build/deploy/bindings commands.
- `stellar_nextjs_wallet_scaffold` creates Next.js client-side wallet files for Freighter: `useStellarWallet`, `WalletButton`, network/contract env helpers, test-wallet script, HTTPS local dev notes, and binding-generation instructions.

For local test wallets, use `stellar_generate_test_wallet` or the generated `scripts/create-test-wallet.mjs --fund`. Test wallet seeds belong only in `.env.local` or a secret manager. Never commit them, and never expose them through `NEXT_PUBLIC_*`.

This follows the official Stellar flow: build Soroban contracts in Rust, deploy with Stellar CLI, generate TypeScript bindings with `stellar contract bindings typescript`, then call those bindings from the frontend. Freighter local testing should run in a secure context, so the scaffold documents `next dev --experimental-https`.

Research notes and source links: [`docs/STELLAR_NEXTJS_SOROBAN_RESEARCH.md`](docs/STELLAR_NEXTJS_SOROBAN_RESEARCH.md).

Agent coding instructions: [`docs/AGENT_SOROBAN_CODING_GUIDE.md`](docs/AGENT_SOROBAN_CODING_GUIDE.md). Repository-level rules for coding agents are in [`AGENTS.md`](AGENTS.md).

Example:

```json
{
  "name": "stellar_soroban_scaffold_contract",
  "arguments": {
    "outputDir": "./stellar-contracts",
    "contractName": "quest_board"
  }
}
```

```json
{
  "name": "stellar_nextjs_wallet_scaffold",
  "arguments": {
    "outputDir": "./web",
    "appName": "quest_board"
  }
}
```

---

## Soroban contract MCP generator

Generate a **standalone** Node MCP package (stdio) from a deployed contract’s **WASM** (`contractspecv0`) or from a **spec JSON** manifest.

### Inputs

1. **WASM** — `Spec.fromWasm` reads the custom section (same idea as `@stellar/stellar-sdk` contract specs).
2. **Spec JSON** — format `stellarmcp-contract-spec-v1` with `entries[]` of base64 `ScSpecEntry` XDR values.

### CLI (from this repo after `npm run build`)

```bash
node build/src/generator/cli.js --input path/to/contract.wasm --out ./my-contract-mcp --name my-contract-mcp --alias mytoken
# or
node build/src/generator/cli.js --input path/to/spec.json --out ./my-contract-mcp --name my-contract-mcp --alias mytoken
```

Published installs: **`stellarmcp-generate`** (same flags).

Then in the output directory:

```bash
npm install && npm run build
STELLAR_CONTRACT_ID=C... STELLAR_NETWORK=testnet node build/src/index.js
```

### Non-goals (current generator)

- No generated HTTP/SSE transport in the scaffold (stdio only).
- Exotic spec shapes may emit loose Zod at the edges; **simulation on RPC remains authoritative**.
- Multi-contract workspaces / auto-publish are out of scope for the generator CLI.

Versioning artifacts in generated code: `GENERATOR_ARTIFACT_VERSION`, `SPEC_FINGERPRINT`, etc. — regenerate when upgrading `stellarmcp` or changing the contract interface.

---

## Troubleshooting


| Issue                      | What to check                                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------------------------- |
| Client cannot start server | `node -v` ≥ 20; `npm run build`; path to `build/src/index.js` is correct.                               |
| Tools error on Horizon/RPC | `STELLAR_NETWORK` matches intended network; URLs https; hosts allowlisted if custom.                    |
| Signing / “unsigned only”  | `STELLAR_AUTO_SIGN_POLICY=safe` returns unsigned XDR; add key + policy only if you intend auto-sign.    |
| HTTP mode                  | `GET /health`; MCP at `POST`/`GET` **`/mcp`** per Streamable HTTP transport; see MCP Logs in Cursor.   |
| Meta cache                 | Writable `STELLAR_META_CACHE_DIR` or temp dir; `freshness.cacheWriteOk` may be `false` on read-only FS. |


---

## Development & testing

```bash
npm run typecheck
npm run test             # build + unit tests + docs/TOOLS.md drift check
npm run docs:tools       # regenerate docs/TOOLS.md after changing MCP tools
npm run verify:phase:c   # full maintainer gate (see package.json)
```

**Useful smokes:**

- `npm run smoke:phase1` — config + stdio + HTTP wiring.
- `npm run smoke:testnet:readonly` — real testnet reads + Soroban via MCP stdio (no secret key).
- `npm run smoke:tier1:friendbot` — Friendbot-funded flows on testnet.

---

## Inspired by stellarskills

Knowledge layer: [stellarskills](https://github.com/ggoldani/stellarskills). Execution layer: StellarMCP.

License: **MIT** (see repository).

TDQS

A3.5/5.0

Scored across 29 tools

Disambiguation4/5

Tools are largely distinct but several fetch/metadata tools (e.g., stellar_get_ledger_meta, stellar_get_transaction_meta) could cause minor confusion for an agent. However, descriptions clearly differentiate their purposes.

Naming Consistency5/5

All tools follow the stellar_verb_noun pattern consistently, using clear verbs like create, get, submit, decode. No mixing of conventions.

Tool Count4/5

29 tools is high but justified by the broad domain coverage (accounts, transactions, SEPs, Soroban, XDR, liquidity). Each tool serves a specific function without redundancy.

Completeness4/5

Covers most major Stellar operations including accounts, trustlines, payments, liquidity pools, Soroban smart contracts, and multiple SEPs. Missing path payments and account merging, but still comprehensive.

Maintenance

ActivityInactive
ResponsivenessNo issues