Skip to main content
Glama
uzochukwuV

x402 Stellar MCP Server

by uzochukwuV
README.md
# x402 Stellar MCP Server

Local MCP server (stdio) that can call x402-protected HTTP resources and automatically pay in Stellar USDC.

## Features

- Payment flow (`stellar:testnet` or `stellar:pubnet`)
- Default testnet configuration
- Mainnet-ready via env switch
- Optional OpenZeppelin facilitator auth via env
- No resource whitelist: URL is provided at tool call time

## Tools Exposed

- `x402_wallet_info`: shows active wallet address/network/config
- `x402_facilitator_supported`: checks configured facilitator `/supported` endpoint
- `fetch_paid_resource`: generic paid fetch (`url`, `method`, optional body/headers)

## Prerequisites

- Node.js 20+
- A Stellar wallet funded with testnet XLM + testnet USDC
- x402 resource server running (your `app/index.js` demo)
- x402 facilitator running on `http://localhost:4022`

## Setup

```bash
npm install
cp .env.example .env
```

### Testnet 
For testnet you'll need to run a facilitator locally on port 4022. I'd recommend using the one included in the coinbase x402 repo:
https://github.com/coinbase/x402/tree/main/examples/typescript/facilitator/advanced

Update `.env` with your wallet key:

```dotenv
STELLAR_SECRET_KEY=S...
STELLAR_NETWORK=stellar:testnet
```

### Pubnet

For mainnet you'll just need an OpenZeppelin API Key for the relayer. You can get one here (Thank you for making this easy):
https://channels.openzeppelin.com/gen

```dotenv
STELLAR_NETWORK=stellar:pubnet
STELLAR_RPC_URL=https://rpc.lightsail.network/
X402_FACILITATOR_URL=https://channels.openzeppelin.com/x402
X402_FACILITATOR_API_KEY=<your-openzeppelin-api-key>
```

`X402_FACILITATOR_API_KEY` is optional in general, but required for OpenZeppelin channels.
When set, `fetch_paid_resource` auto-adds `Authorization: Bearer <key>` for requests under `X402_FACILITATOR_URL` (unless you provide `Authorization` explicitly).

## Run

```bash
npm run dev
```

The MCP server runs over stdio for Claude/Codex integrations.

## TTS Proxy

The paid `/api/tts` route can use either `elevenlabs` or `smallest`.
Set a default provider in `.env`, and optionally override it per request by sending `"provider": "elevenlabs"` or `"provider": "smallest"` in the JSON body.
You can also send `"provider": "auto"` with a routing `"priority"` of `"cheap"`, `"fast"`, or `"quality"` to let the server pick a provider dynamically.

To run the real x402-protected TTS proxy, configure:

```dotenv
STELLAR_NETWORK=stellar:testnet
X402_FACILITATOR_URL=http://localhost:4022
TTS_PROVIDER=elevenlabs
ELEVENLABS_API_KEY=<your-elevenlabs-api-key>
ELEVENLABS_MODEL_ID=eleven_flash_v2_5
ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM
ELEVENLABS_ESTIMATED_PRICE_USD=0.06
ELEVENLABS_ESTIMATED_LATENCY_MS=900
ELEVENLABS_QUALITY_SCORE=9.5
SMALLEST_API_KEY=<your-smallest-api-key>
SMALLEST_MODEL=lightning
SMALLEST_VOICE_ID=emily
SMALLEST_LANGUAGE=en
SMALLEST_ESTIMATED_PRICE_USD=0.03
SMALLEST_ESTIMATED_LATENCY_MS=500
SMALLEST_QUALITY_SCORE=8.3
ALLOW_SYSTEM_PROXY=false
PAY_TO_ADDRESS=<your-stellar-receiving-address>
```

For pubnet, also set:

```dotenv
STELLAR_NETWORK=stellar:pubnet
STELLAR_RPC_URL=https://rpc.lightsail.network/
X402_FACILITATOR_URL=https://channels.openzeppelin.com/x402
X402_FACILITATOR_API_KEY=<your-openzeppelin-api-key>
```

Then start the proxy with:

```bash
npm run start:elevenlabs
```

The protected route is:

```bash
POST http://localhost:3000/api/tts
```

Example request for automatic routing:

```json
{
  "text": "Hello from the voice marketplace",
  "provider": "auto",
  "priority": "cheap",
  "language": "en"
}
```

The response includes marketplace metadata headers like:

```text
X-TTS-Provider
X-TTS-Priority
X-TTS-Reason
X-TTS-Estimated-Price-Usd
X-TTS-Estimated-Latency-Ms
X-TTS-Quality-Score
```

This server now requires a real facilitator and will not fall back to a mock implementation.
By default it also ignores `HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY` so upstream TTS requests go direct during local testing. Set `ALLOW_SYSTEM_PROXY=true` if you intentionally want to use a proxy.

## Add To Claude / Codex

Use an MCP entry like (don't forget to change the path/):

### Codex

```bash
codex mcp add x402-stellar -- npm --silent --prefix /absolute/path/to/x402-mcp-stellar run dev
```

### Claude Code
```bash
claude mcp add x402-stellar -- npm --silent --prefix /absolute/path/to/x402-mcp-stellar run dev
```

### Claude Desktop (untested)

```json
{
  "mcpServers": {
    "x402-stellar": {
      "command": "npm",
      "args": ["--silent", "--prefix", "/absolute/path/to/x402-mcp-stellar", "run", "dev"]
    }
  }
}
```

This server loads `.env` from the project directory (`/absolute/path/to/x402-mcp-stellar/.env`).

## Claude Usage

After loading the MCP server, you can ask:

`Can you fetch the resource at http://localhost:3000/my-service, use the x402-stellar MCP server to pay for it, and print the response?`

The tool call will pass that full URL at runtime; no URL allowlist or hardcoded endpoint is required in this MCP server.

## Notes

- `@x402/stellar` is not currently published on npm, so this repo vendors the Stellar mechanism under `src/stellar`.
- Default testnet Soroban RPC is used automatically.
- Mainnet requires `STELLAR_RPC_URL`.

## License

MIT

Maintenance

ActivityInactive
ResponsivenessNo issues