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
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues