Stables

السجل الرسمي المالية والمدفوعات

Stablecoin payments for AI agents: customers, quotes, transfers, payment routes.

التثبيت

أضف هذا إلى إعدادات MCP في عميلك (Claude Desktop: claude_desktop_config.json، وCursor: ‏.cursor/mcp.json، ويستخدم VS Code وغيره الصيغة نفسها «mcpServers»).

Remote (streamable-http)
Claude Code
claude mcp add --transport http stables 'https://mcp.stables.money/mcp'
إعداد JSON (Claude Desktop وCursor وVS Code)
{
    "mcpServers": {
        "stables": {
            "type": "http",
            "url": "https://mcp.stables.money/mcp"
        }
    }
}
NPM package stables-mcp-server
Claude Code
claude mcp add stables -e 'STABLES_API_KEY=<your stables_api_key>' -- npx -y stables-mcp-server@2.6.11
إعداد JSON (Claude Desktop وCursor وVS Code)
{
    "mcpServers": {
        "stables": {
            "command": "npx",
            "args": [
                "-y",
                "stables-mcp-server@2.6.11"
            ],
            "env": {
                "STABLES_API_KEY": "<your stables_api_key>"
            }
        }
    }
}

متغيرات البيئة

  • STABLES_API_KEY إلزامي سري Your Stables API key: sti_test_ for sandbox, sti_live_ for production

التوثيق

مأخوذ من ملف README للمشروع على GitHub ويُحدَّث أسبوعيًا. تفتح الروابط على GitHub.

المحتويات
  1. Stables MCP Server
  2. What is MCP?
  3. Features
  4. Hosted server (recommended)
  5. Running locally
  6. Agent safety
  7. Example Conversations
  8. Operating the hosted server
  9. Development
  10. Project Structure
  11. API Reference
  12. Security
  13. License
  14. Links

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 51 tools across 11 categories, one for every operation documented on docs.stables.money (a contract test checks this, see below):

Customer Management
  • create_customer - Create individual or business customers
  • create_customer_onboarding_link - Create a customer and a hosted verification link in one call
  • 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
Entitlements
  • list_available_entitlements - Products and rails a customer can still apply for
  • request_entitlements - Apply for entitlements (e.g. aed_local) for an existing customer
  • submit_entitlement_requirements - Send the extra verification Stables asks for
Compliance requests (RFIs)
  • list_rfis - The organisation's RFIs: what compliance needs before it releases a held payment or verification
  • list_customer_rfis - One customer's RFIs
  • get_rfi - One RFI, its requirements and how to answer each
  • get_rfi_evidence_form - The form an evidence requirement asks for
  • submit_rfi_evidence - Send the answers and documents for an evidence requirement
  • get_kyc_capabilities - Verification capabilities a customer holds
Documents
  • add_document - Attach an invoice, contract or other document to a transfer or a deposit
  • list_documents - Documents on a transfer or a deposit
  • get_document_download_url - Short-lived download link for a document
  • delete_document - Remove a document
Quotes
  • create_quote - Get exchange rate quotes (USDC/USDT to fiat)
  • get_quote - Check quote status and details
Transfers
  • validate_payment_method - Check payout details against a corridor's rules before transferring
  • create_transfer - Execute a transfer using an active quote, paid by deposit or from your balance
  • 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, or across all customers
  • update_virtual_account - Update virtual account settings
  • register_route_payid - Register a PayID on an AUD payment route
  • get_virtual_account_history - Get deposits and their payouts for a payment route
  • update_route_destination - Change the payout wallet on an existing route
  • list_route_whitelist / add_route_whitelist_account / update_route_whitelist_account - Source-account whitelisting for AUD routes
Balances
  • get_balance - Your organisation's balance per asset and network
  • get_balance_wallet / create_balance_wallet - The deposit wallet that tops up the balance
  • list_balance_activity - Deposits credited to the balance
  • list_pending_balance_deposits - Deposits held before crediting, and why
  • list_whitelisted_wallets - Wallets allowed to fund the balance
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

The server runs as a hosted service, so there is nothing to install. Point your MCP client at:

https://mcp.stables.money/mcp

and either send your Stables API key as a bearer token or sign in with OAuth. The key you get during onboarding is all you need: a sti_test_… key reaches sandbox, a sti_live_… key reaches production and moves real money. Clients that can't hold a key (Claude.ai, ChatGPT) sign in instead; see below.

Claude Code
claude mcp add --transport http stables https://mcp.stables.money/mcp --header "Authorization: Bearer ${STABLES_API_KEY}"
Cursor, VS Code, Windsurf and other clients with a url field
{
  "mcpServers": {
    "stables": {
      "url": "https://mcp.stables.money/mcp",
      "headers": {
        "Authorization": "Bearer sti_test_..."
      }
    }
  }
}
Codex
[mcp_servers.stables]
url = "https://mcp.stables.money/mcp"
bearer_token_env_var = "STABLES_API_KEY"
Claude.ai, ChatGPT and other clients that sign in with OAuth

Add https://mcp.stables.money/mcp as a custom connector with no key. The client discovers the server's OAuth endpoints, registers itself, and sends you to a Stables page that asks two things: whether to connect sandbox or production, and permission for that client. You then sign in with your Stables dashboard account (and pick an organisation if you belong to several).

You choose Read only (the default) or Read and make changes; with read only, the agent can look but every tool that changes something is refused until you reconnect and allow changes. Agents connected this way can never create or revoke API keys. Every tool is labelled read-only or destructive, so clients such as Claude ask you before each change. Auth0 asks for your credentials (and a second factor) every time (an existing browser session is never reused for an agent connection) and, when you belong to several organisations, which one to use. On success the server creates an API key in that organisation, named after the client and the account that signed in (for example Claude via MCP (you@company.com)), and uses it for every call the client makes. Revoke it any time under Developer → API keys in the dashboard, which disconnects the client. Nothing else is stored: the sign-in token is used once to create the key and then dropped.

  • Claude.ai / Claude Desktop: Settings → Connectors → Add custom connector, URL https://mcp.stables.money/mcp, leave the OAuth client fields on their defaults.
  • ChatGPT: Settings → Connectors → Create (developer mode), MCP server URL https://mcp.stables.money/mcp, authentication OAuth.
  • Claude Code without a key: claude mcp add --transport http stables https://mcp.stables.money/mcp, then /mcp to sign in.

The OAuth endpoints are standard: /.well-known/oauth-protected-resource/mcp, /.well-known/oauth-authorization-server, /authorize, /oauth/token, /oauth/register. Client ID Metadata Documents and dynamic registration are both accepted; PKCE (S256) is required.

Running locally

The same server also runs as a local process over stdio, which is what npx stables-mcp-server does. Use this for a sti_local_… key against your own deployment, or when your client cannot reach the internet.

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:

VariableRequiredDescription
STABLES_API_KEYYesYour Stables API key
STABLES_API_URLNoAPI 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 keyWhere requests go
sti_test_…https://api.sandbox.stables.money
sti_live_…https://api.stables.money — real money
sti_local_… or anything elseproduction, 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

Operating the hosted server

The hosted server is the Cloudflare Worker in src/worker.ts (wrangler.toml). It needs:

  • OAUTH_KV: a KV namespace for OAuth clients, grants and tokens. Tokens and secrets are stored as hashes; a grant's API key is encrypted with a key only that grant's token can unwrap.
  • Vars MCP_PUBLIC_URL, AUTH0_DOMAIN, AUTH0_CLIENT_ID: the public origin, the Auth0 custom domain, and the "Stables MCP" regular-web application (callback https://mcp.stables.money/callback).
  • Secret AUTH0_CLIENT_SECRET: that application's secret.
  • Secret MCP_GATEWAY_SIGNING_SECRET: shared with the API gateway's IP authoriser. The Worker has no fixed egress IP, so it signs each forwarded request (X-Stables-Mcp-Signature), and production accepts the signature in place of the source-IP check. Without it, production calls through the hosted server are rejected by the gateway; sandbox is unaffected.
wrangler secret put AUTH0_CLIENT_SECRET
wrangler secret put MCP_GATEWAY_SIGNING_SECRET

Without OAUTH_KV the Worker runs bearer-key only, which is how the unit tests exercise it.

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 (7)
│       ├── entitlements.ts   # Entitlement tools (3)
│       ├── compliance.ts     # RFI and KYC capability tools (6)
│       ├── documents.ts      # Transfer and deposit document tools (4)
│       ├── quotes.ts         # Quote tools (2)
│       ├── transfers.ts      # Transfer tools (4)
│       ├── virtual-accounts.ts # Payment route tools (9)
│       ├── balances.ts       # Balance 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.

ParameterTypeRequiredDescription
emailstringYesCustomer's email
customerType"individual" \"business"YesType of customer
firstNamestringNoFirst name (for individuals)
lastNamestringNoLast name (for individuals)
companyNamestringNoCompany name (for businesses)
entitlementsstring[]NoEntitlements to request (e.g., ["base_payout", "virtual_account"])
get_customer

Get customer details.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
list_customers

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

Generate a KYC verification link.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
ttlInSecsnumberNoLink expiry in seconds (default: 1800)
successUrlstringNoRedirect URL after successful verification
rejectUrlstringNoRedirect URL after rejected verification
update_customer

Update customer details or entitlements.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
emailstringNoUpdated email
phonestringNoUpdated phone
firstNamestringNoUpdated first name
lastNamestringNoUpdated last name
entitlementsstring[]NoUpdated entitlements
update_customer_metadata

Update customer metadata key-value pairs.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
metadataobjectYesKey-value pairs to set
Quote Tools
create_quote

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

ParameterTypeRequiredDescription
fromCurrency"USDC" \"USDT"YesSource cryptocurrency
fromAmountstringYesAmount to convert
fromNetwork"ethereum" \"polygon" \"polygon-amoy"YesBlockchain network
toCurrencystringYesDestination currency (e.g., "EUR")
toCountrystringYesDestination country code (e.g., "GR")
paymentMethodType"SWIFT" \"LOCAL"YesPayment method for payout
get_quote

Get quote details.

ParameterTypeRequiredDescription
quoteIdstringYesQuote ID
Transfer Tools
create_transfer

Execute a transfer from a quote.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
quoteIdstringYesQuote ID to execute
accountHolderNamestringNoBank account holder name
ibanstringNoIBAN
accountNumberstringNoBank account number
bankNamestringNoBank name
bankCountrystringNoBank country code
bankCurrencystringNoPayout currency
accountType"savings" \"checking" \"payment"NoAccount type
swiftCodestringNoSWIFT/BIC code
routingNumberstringNoABA routing number (US)
sortCodestringNoSort code (UK)
ifscCodestringNoIFSC code (India)
bsbCodestringNoBSB code (Australia)
get_transfer

Get transfer status.

ParameterTypeRequiredDescription
transferIdstringYesTransfer ID
list_transfers

List transfers with filters.

ParameterTypeRequiredDescription
statusstringNoFilter by status
typestringNoFilter by type
customerIdstringNoFilter by customer
pageSizenumberNoResults per page
pageTokenstringNoPagination token
Virtual Account Tools
create_virtual_account

Create a virtual bank account.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
sourceCurrencystringYesCurrency (e.g., "USD")
depositHandlingModestringNo"auto_payout", "hold", or "manual"
destinationAddressstringNoCrypto wallet address
destinationPaymentRailstringNoBlockchain network
destinationCurrencystringNoStablecoin (default: "usdc")
list_virtual_accounts

List virtual accounts for a customer.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
statusstringNoFilter by status
limitnumberNoMax results
update_virtual_account

Update virtual account settings.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
virtualAccountIdstringYesVirtual account ID
depositHandlingModestringYesNew deposit handling mode
get_virtual_account_history

Get activity history for a virtual account.

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
virtualAccountIdstringYesVirtual account ID
limitnumberNoMax events to return
eventTypestringNoFilter by event type
API Key Tools
create_api_key

Create a new API key.

ParameterTypeRequiredDescription
namestringYesDescriptive name for the key
metadataobjectNoOptional metadata
list_api_keys

List all API keys.

ParameterTypeRequiredDescription
pageSizenumberNoResults per page
pageTokenstringNoPagination token
get_api_key

Get API key details.

ParameterTypeRequiredDescription
apiKeyIdstringYesAPI key ID
revoke_api_key

Revoke an API key (permanent).

ParameterTypeRequiredDescription
apiKeyIdstringYesAPI key ID
Webhook Tools
create_webhook

Subscribe to events via webhook.

ParameterTypeRequiredDescription
namestringYesWebhook name
urlstringYesHTTPS endpoint URL
eventTypesstring[]YesEvents to subscribe to
secretstringNoHMAC-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.

ParameterTypeRequiredDescription
webhookIdstringYesWebhook 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

الأسئلة الشائعة

ما هو Stables؟

Stablecoin payments for AI agents: customers, quotes, transfers, payment routes.

كيف أثبّت Stables؟

يعمل كخادم بعيد. في Claude Code: claude mcp add --transport http stables 'https://mcp.stables.money/mcp'. وفي العملاء الآخرين، الصق إعداد JSON من هذه الصفحة في إعدادات MCP الخاصة بهم.

هل يحتاج Stables إلى مفتاح API؟

نعم. يتطلب STABLES_API_KEY، وتضبطها في إعداداته.

هل Stables مفتوح المصدر؟

نعم. شيفرته متاحة على GitHub بترخيص MIT.

من يصون Stables؟

ينشره stables-money. يدرجه AI.tn لكنه لا يصونه ولا يوصي به.

من سجل MCP الرسمي. الإدراج ليس توصية: راجع شيفرة الخادم وصلاحياته قبل منحه الوصول إلى بياناتك.