Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Enables AI agents to manage stablecoin payments including customer management, quotes, transfers, virtual accounts, and webhooks via the Stables API.

README.md

Stables MCP Server

An MCP (Model Context Protocol) server that exposes the Stables fiat-to-crypto API to AI agents. This allows AI assistants like Claude, ChatGPT, Cursor, Codex, and other MCP-compatible clients to manage customers, create USDC and USDT quotes, execute approved transfers, and handle virtual accounts programmatically.

Use it to build stablecoin payment workflows for AI agents and agentic commerce: payouts, virtual account deposits, treasury movement, fiat off-ramping, and webhook reconciliation.

What is MCP?

MCP (Model Context Protocol) is an open standard that provides a standardized way to connect AI applications to external tools and data sources. Think of it like a "USB-C port for AI" - any AI that supports MCP can use any MCP server.

Features

This MCP server provides 26 tools across 7 categories:

Customer Management

  • create_customer - Create individual or business customers
  • get_customer - Get customer details and verification status
  • list_customers - List all customers
  • get_verification_link - Generate KYC verification links
  • update_customer - Update customer details and entitlements
  • update_customer_metadata - Update customer metadata key-value pairs

Quotes

  • create_quote - Get exchange rate quotes (USDC/USDT to fiat)
  • get_quote - Check quote status and details

Transfers

  • create_transfer - Execute a transfer using an active quote
  • get_transfer - Check transfer status
  • list_transfers - List transfers with filters

Virtual Accounts

  • create_virtual_account - Create virtual bank accounts for fiat deposits
  • list_virtual_accounts - List virtual accounts for a customer
  • update_virtual_account - Update virtual account settings
  • get_virtual_account_history - Get deposits and their payouts for a payment route
  • update_route_destination - Change the payout wallet on an existing route

Sandbox

  • simulate_route_deposit - Simulate a fiat deposit into a payment route (sandbox only)
  • simulate_transfer_deposit - Simulate the inbound crypto an off-ramp transfer awaits (sandbox only)

API Keys

  • create_api_key - Create a new API key
  • list_api_keys - List all API keys
  • get_api_key - Get API key details
  • revoke_api_key - Revoke an API key

Webhooks

  • create_webhook - Subscribe to events via webhook
  • list_webhooks - List all webhook subscriptions
  • delete_webhook - Delete a webhook subscription
  • list_webhook_deliveries - Recent delivery attempts, status codes and retry state

Installation

# Install from npm
npm install -g stables-mcp-server

# Or clone and build from source
git clone https://github.com/stables-money/mcp-server.git
cd mcp-server
npm install
npm run build

Configuration

The server requires the following environment variables:

| Variable | Required | Description | |----------|----------|-------------| | STABLES_API_KEY | Yes | Your Stables API key | | STABLES_API_URL | No | API base URL. Defaults to the environment your key belongs to (see below). Must use HTTPS. |

Which environment you're talking to

Stables keys carry their environment: sti_test_… is a sandbox key, sti_live_… is a production key, and the API refuses a key that arrives at the wrong environment. So you don't have to set a URL — leave STABLES_API_URL unset and the key decides:

| Your key | Where requests go | |----------|-------------------| | sti_test_… | https://api.sandbox.stables.money | | sti_live_… | https://api.stables.moneyreal money | | sti_local_… or anything else | production, unless you set STABLES_API_URL |

Setting STABLES_API_URL always wins, which is how you reach staging, dev or a local deployment.

Start with a sandbox key. An agent holding a live key can move real money on your behalf; see agent safety.

Usage

With Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "stables": {
      "command": "npx",
      "args": ["stables-mcp-server"],
      "env": {
        "STABLES_API_KEY": "your-api-key",
        "STABLES_API_URL": "https://api.sandbox.stables.money"
      }
    }
  }
}

Then restart Claude Desktop.

With Cursor, Codex, ChatGPT, or another MCP client

Use the same command and environment variables in any MCP-compatible client:

{
  "mcpServers": {
    "stables": {
      "command": "npx",
      "args": ["stables-mcp-server"],
      "env": {
        "STABLES_API_KEY": "your-api-key",
        "STABLES_API_URL": "https://api.sandbox.stables.money"
      }
    }
  }
}

Agent safety

Stables is financial infrastructure. Agents should create quotes, prepare payment objects, and reconcile webhooks, but should require explicit human approval before creating transfers or other money movement. Check customer KYC/KYB status and entitlements before transactional actions, and treat sanctions, unsupported jurisdiction, verification, or compliance failures as hard stops.

With MCP Inspector (for testing)

# Set environment variables
export STABLES_API_KEY=your-api-key
export STABLES_API_URL=https://api.sandbox.stables.money

# Run the inspector
npm run inspect

Direct Execution

STABLES_API_KEY=your-api-key node build/index.js

Example Conversations

Creating a customer and getting a quote

User: "Create a customer for john@example.com and get a quote to convert 1000 USDT to EUR"

AI (using MCP tools):

  1. Calls create_customer with email and type
  2. Calls create_quote with source USDT + network, destination EUR + country, and destinationNetwork (swift or bank)
  3. Returns customer details and quote information

Checking transfer status

User: "What's the status of all my pending transfers?"

AI (using MCP tools):

  1. Calls list_transfers with status=created or status=in_progress (statuses are lowercase)
  2. Returns a formatted list of in-flight transfers

Setting up auto-payout

User: "Create a payment route for customer abc123 that pays AUD deposits out to my Polygon USDT wallet 0x..."

AI (using MCP tools):

  1. Calls create_virtual_account with the customer ID, AUD source currency, and the Polygon destination (the payout address is mandatory)
  2. Returns the deposit instructions to share with the customer

Paying out to a European beneficiary

User: "Pay 500 EUR to this German bank account"

AI (using MCP tools):

  1. Collects the extra beneficiary details EUR requires — recipientType, a full address, and dateOfBirth for individuals — before doing anything else
  2. Calls create_quote, then create_transfer once a human approves

Development

# Watch mode for development
npm run dev

# Build for production
npm run build

# Run tests
npm test

# Run linter
npm run lint

# Format code
npm run format

# Test with MCP Inspector
npm run inspect

Project Structure

stables-mcp-server/
├── src/
│   ├── index.ts              # Main entry point
│   ├── lib/
│   │   ├── stables-client.ts # Stables API client (with retries, timeouts)
│   │   └── stables-client.test.ts
│   └── tools/
│       ├── customers.ts      # Customer management tools (6)
│       ├── quotes.ts         # Quote tools (2)
│       ├── transfers.ts      # Transfer tools (3)
│       ├── virtual-accounts.ts # Virtual account tools (6)
│       ├── api-keys.ts       # API key tools (4)
│       ├── webhooks.ts       # Webhook tools (3)
│       └── sandbox.ts        # Sandbox deposit simulation (2)
├── package.json
├── tsconfig.json
├── vitest.config.ts
├── eslint.config.js
└── README.md

API Reference

Customer Tools

create_customer

Create a new customer for KYC and transfers.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email | string | Yes | Customer's email | | customerType | "individual" \| "business" | Yes | Type of customer | | firstName | string | No | First name (for individuals) | | lastName | string | No | Last name (for individuals) | | companyName | string | No | Company name (for businesses) | | entitlements | string[] | No | Entitlements to request (e.g., ["base_payout", "virtual_account"]) |

get_customer

Get customer details.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID |

list_customers

List all customers for the authenticated tenant. No parameters required.

get_verification_link

Generate a KYC verification link.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | ttlInSecs | number | No | Link expiry in seconds (default: 1800) | | successUrl | string | No | Redirect URL after successful verification | | rejectUrl | string | No | Redirect URL after rejected verification |

update_customer

Update customer details or entitlements.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | email | string | No | Updated email | | phone | string | No | Updated phone | | firstName | string | No | Updated first name | | lastName | string | No | Updated last name | | entitlements | string[] | No | Updated entitlements |

update_customer_metadata

Update customer metadata key-value pairs.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | metadata | object | Yes | Key-value pairs to set |

Quote Tools

create_quote

Get a quote for currency exchange (crypto to fiat).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | fromCurrency | "USDC" \| "USDT" | Yes | Source cryptocurrency | | fromAmount | string | Yes | Amount to convert | | fromNetwork | "ethereum" \| "polygon" \| "polygon-amoy" | Yes | Blockchain network | | toCurrency | string | Yes | Destination currency (e.g., "EUR") | | toCountry | string | Yes | Destination country code (e.g., "GR") | | paymentMethodType | "SWIFT" \| "LOCAL" | Yes | Payment method for payout |

get_quote

Get quote details.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | quoteId | string | Yes | Quote ID |

Transfer Tools

create_transfer

Execute a transfer from a quote.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | quoteId | string | Yes | Quote ID to execute | | accountHolderName | string | No | Bank account holder name | | iban | string | No | IBAN | | accountNumber | string | No | Bank account number | | bankName | string | No | Bank name | | bankCountry | string | No | Bank country code | | bankCurrency | string | No | Payout currency | | accountType | "savings" \| "checking" \| "payment" | No | Account type | | swiftCode | string | No | SWIFT/BIC code | | routingNumber | string | No | ABA routing number (US) | | sortCode | string | No | Sort code (UK) | | ifscCode | string | No | IFSC code (India) | | bsbCode | string | No | BSB code (Australia) |

get_transfer

Get transfer status.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | transferId | string | Yes | Transfer ID |

list_transfers

List transfers with filters.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | status | string | No | Filter by status | | type | string | No | Filter by type | | customerId | string | No | Filter by customer | | pageSize | number | No | Results per page | | pageToken | string | No | Pagination token |

Virtual Account Tools

create_virtual_account

Create a virtual bank account.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | sourceCurrency | string | Yes | Currency (e.g., "USD") | | depositHandlingMode | string | No | "auto_payout", "hold", or "manual" | | destinationAddress | string | No | Crypto wallet address | | destinationPaymentRail | string | No | Blockchain network | | destinationCurrency | string | No | Stablecoin (default: "usdc") |

list_virtual_accounts

List virtual accounts for a customer.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | status | string | No | Filter by status | | limit | number | No | Max results |

update_virtual_account

Update virtual account settings.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | virtualAccountId | string | Yes | Virtual account ID | | depositHandlingMode | string | Yes | New deposit handling mode |

get_virtual_account_history

Get activity history for a virtual account.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | customerId | string | Yes | Customer ID | | virtualAccountId | string | Yes | Virtual account ID | | limit | number | No | Max events to return | | eventType | string | No | Filter by event type |

API Key Tools

create_api_key

Create a new API key.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | Yes | Descriptive name for the key | | metadata | object | No | Optional metadata |

list_api_keys

List all API keys.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | pageSize | number | No | Results per page | | pageToken | string | No | Pagination token |

get_api_key

Get API key details.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | apiKeyId | string | Yes | API key ID |

revoke_api_key

Revoke an API key (permanent).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | apiKeyId | string | Yes | API key ID |

Webhook Tools

create_webhook

Subscribe to events via webhook.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | Yes | Webhook name | | url | string | Yes | HTTPS endpoint URL | | eventTypes | string[] | Yes | Events to subscribe to | | secret | string | No | HMAC-SHA256 signing secret |

Available event types:

  • WEBHOOK_EVENT_TYPE_CUSTOMER_CREATED
  • WEBHOOK_EVENT_TYPE_CUSTOMER_UPDATED
  • WEBHOOK_EVENT_TYPE_KYC_STATUS_CHANGED
  • WEBHOOK_EVENT_TYPE_PAYMENT_CREATED
  • WEBHOOK_EVENT_TYPE_PAYMENT_STATUS_CHANGED
  • WEBHOOK_EVENT_TYPE_QUOTE_CREATED
  • WEBHOOK_EVENT_TYPE_QUOTE_EXPIRED
  • WEBHOOK_EVENT_TYPE_VA_DEPOSIT_RECEIVED
  • WEBHOOK_EVENT_TYPE_VA_PAYOUT_COMPLETED
  • WEBHOOK_EVENT_TYPE_VA_PAYOUT_FAILED
  • WEBHOOK_EVENT_TYPE_ALL

list_webhooks

List all webhook subscriptions. No parameters required.

delete_webhook

Delete a webhook subscription.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | webhookId | string | Yes | Webhook subscription ID |

Security

  • API keys are only read from environment variables
  • HTTPS required for API URL (enforced at startup)
  • No debug logging to stderr (would corrupt MCP STDIO transport)
  • All inputs are validated with Zod schemas
  • Request timeouts (30s) prevent hung connections
  • Automatic retries with exponential backoff for transient failures

License

MIT

Links

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Finance & Payments servers.