MCP Server

A hosted, remote MCP server. No install, no local process — connect any Model Context Protocol client with a URL and an API key, and your agent gets the full SatsRail payment API as tools.

Streamable HTTP JSON-RPC 2.0 45 tools protocol 2025-06-18
POST https://satsrail.com/api/v1/mcp

Endpoint & Transport

The portal serves the MCP surface directly as a first-class API namespace over the MCP Streamable HTTP transport. There is nothing to install: the server that used to ship as the standalone satsrail-mcp npm package now lives in the API itself, so tools never drift from the endpoints they call.

EndpointPOST https://satsrail.com/api/v1/mcp
TransportStreamable HTTP, POST-only. JSON-RPC 2.0; batch arrays are supported.
Protocol version2025-06-18 (negotiates down to 2025-03-26 and 2024-11-05)
Server infoname satsrail, version 1.2.1
Capabilitiestools only — no resources, prompts, or sampling
GET requestsReturn 405 with JSON-RPC error -32000 (this endpoint accepts POST only) rather than leaving SSE clients hanging on a dead stream
The MCP surface is JSON-RPC, not REST, so it is intentionally absent from the OpenAPI spec. This page is its reference.

Authentication

Every request carries a standard SatsRail API token in the Authorization header — the same keys the rest of the merchant API uses. The token is forwarded to each underlying API call, so merchant scope, security groups, and rate limits are enforced exactly as they are for REST.

Authorization: Bearer sk_live_your_key
Key typeAccess
sk_live_…Full merchant access, production
sk_test_…Full merchant access, test mode
pk_…Passes the MCP gate but is limited downstream to checkout-session creation only

A missing or invalid token returns HTTP 401 with JSON-RPC error -32001. Create keys in your dashboard — the API tokens page also renders a ready-to-paste "Connect an AI assistant (MCP)" config card with your token pre-filled. There is no OAuth flow today; the bearer header is the only credential.

Connect Your Client

Modern MCP clients connect to a remote server with a URL and a header. Pick your client below. Stdio-only clients bridge through mcp-remote.

One command adds the server to Claude Code:

claude mcp add --transport http satsrail https://satsrail.com/api/v1/mcp \
  --header "Authorization: Bearer sk_test_your_key"

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

{
  "mcpServers": {
    "satsrail": {
      "type": "http",
      "url": "https://satsrail.com/api/v1/mcp",
      "headers": { "Authorization": "Bearer sk_live_your_key" }
    }
  }
}

Add to .cursor/mcp.json in your project:

{
  "mcpServers": {
    "satsrail": {
      "type": "http",
      "url": "https://satsrail.com/api/v1/mcp",
      "headers": { "Authorization": "Bearer sk_live_your_key" }
    }
  }
}

Add to Windsurf's MCP config (~/.codeium/windsurf/mcp_config.json):

{
  "mcpServers": {
    "satsrail": {
      "type": "http",
      "url": "https://satsrail.com/api/v1/mcp",
      "headers": { "Authorization": "Bearer sk_live_your_key" }
    }
  }
}

For clients that only speak stdio, bridge to the hosted endpoint with mcp-remote:

{
  "mcpServers": {
    "satsrail": {
      "command": "npx",
      "args": ["mcp-remote", "https://satsrail.com/api/v1/mcp",
               "--header", "Authorization: Bearer sk_live_your_key"]
    }
  }
}

Protocol Methods

MethodPurpose
initializeHandshake and protocol-version negotiation; returns server info and capabilities
tools/listReturns all 45 tools with their JSON Schemas
tools/callInvokes a tool by name with arguments
pingLiveness check
Example — tools/call

Request:

curl -X POST https://satsrail.com/api/v1/mcp \
  -H "Authorization: Bearer sk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "create_order",
      "arguments": {
        "total_amount_cents": 2500,
        "currency": "usd",
        "generate_invoice": true
      }
    }
  }'

Response (abridged):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{ "type": "text", "text": "{ \"id\": \"...\", \"status\": \"pending\", \"invoice\": { \"bolt11\": \"lnbc250u1p...\" } }" }],
    "isError": false
  }
}

Tool Catalog

45 tools cover the full merchant surface. All target the /m/ merchant namespace except list_subscription_plans, which is public. Tools marked pk_ also work with publishable keys.

Orders & invoices (9)

ToolDescription
create_orderCreate an order, auto-generating a Lightning invoice by default
get_orderFetch an order by ID (expandable: invoice, payment, merchant)
list_ordersList orders with Ransack filters and pagination
cancel_orderCancel a pending order
update_orderEdit a pending order, mark shipped, or mark cash-paid
get_invoiceFetch an invoice including its bolt11 string and on-chain address
check_invoice_statusLive payment check against the Lightning node
generate_invoiceGenerate a fresh invoice for an existing order
get_invoice_qrReturn the invoice as an SVG QR code

Payments, checkout & payment requests (8)

ToolDescription
list_paymentsList confirmed payments with date and amount filters
get_paymentFetch payment details
list_checkout_sessionsList hosted checkout sessions
get_checkout_sessionFetch a checkout session
create_checkout_session pk_Create a hosted checkout URL; product_id derives price and tax
create_payment_requestCreate an order and invoice in one call
get_payment_requestFetch a payment request
get_payment_request_statusLive status of a payment request

Products & catalog (15)

ToolDescription
get_catalogProduct types, products, taxes, and discounts in one response
get_catalog_versionCatalog timestamp for cheap cache invalidation
list_productsList products with filters and pagination
get_productFetch a product by UUID or slug
create_productCreate a product
update_productUpdate a product
delete_productHard-delete or archive a product
get_product_keyReturn a product's AES-256-GCM key (sensitive)
rotate_product_keyRotate the key, keeping the old key for a re-encryption window
clear_product_old_keyClear the retained old key once re-encryption is complete
list_product_typesList product types
get_product_typeFetch a product type
create_product_typeCreate a product type
update_product_typeUpdate a product type
delete_product_typeDelete a product type (fails if products are assigned)

Webhooks (5)

ToolDescription
list_webhooksList webhook endpoints
get_webhookFetch a webhook endpoint
create_webhookCreate a webhook; returns the signing secret once
update_webhookUpdate a webhook endpoint
delete_webhookDelete a webhook endpoint

Merchant & account (6)

ToolDescription
get_merchantCurrent merchant profile and settings
list_walletsList connected wallets
get_walletFetch a wallet
list_merchant_documentsList merchant documents (read-only)
get_merchant_documentFetch a merchant document (read-only)
get_api_token_usageCurrent RPM, monthly count, and rate-limit metadata for the calling token

Access & public (2)

ToolDescription
verify_access_tokenVerify an access token / macaroon; returns product, order, key, and fingerprint
list_subscription_plansList available subscription plans (public — no auth required)

Errors, Rate Limits & Auditing

Protocol-level problems return JSON-RPC errors. Failures from the underlying API surface as tool results with isError: true carrying the API's error message — they do not break the protocol stream.

CodeMeaning
-32700Parse error — malformed JSON (HTTP 400)
-32600Invalid request envelope
-32601Unknown method
-32001Authentication failed — missing or invalid token (HTTP 401)
-32000Transport error — e.g. a GET to the endpoint (HTTP 405)

Rate limiting: a JSON-RPC request is charged once against your plan's API limits, not once per tool — the MCP layer dispatches in-process below the throttle. Monitor usage with get_api_token_usage. Auditing: every tools/call is logged (tool name, token, merchant, success) — arguments and results are never stored. Protocol chatter like initialize and tools/list is not logged.

Quick Test

Confirm the connection and count the tools:

curl -s https://satsrail.com/api/v1/mcp \
  -H "Authorization: Bearer sk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools | length'
# => 45

Give your agent a payment rail

Get an API key, paste one config block, and your agent can accept Bitcoin over Lightning.