StellarMCP
# 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
Scored across 29 tools
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.
All tools follow the stellar_verb_noun pattern consistently, using clear verbs like create, get, submit, decode. No mixing of conventions.
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.
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.