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.
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.
| Endpoint | POST https://satsrail.com/api/v1/mcp |
|---|---|
| Transport | Streamable HTTP, POST-only. JSON-RPC 2.0; batch arrays are supported. |
| Protocol version | 2025-06-18 (negotiates down to 2025-03-26 and 2024-11-05) |
| Server info | name satsrail, version 1.2.1 |
| Capabilities | tools only — no resources, prompts, or sampling |
| GET requests | Return 405 with JSON-RPC error -32000 (this endpoint accepts POST only) rather than leaving SSE clients hanging on a dead stream |
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 type | Access |
|---|---|
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
| Method | Purpose |
|---|---|
initialize | Handshake and protocol-version negotiation; returns server info and capabilities |
tools/list | Returns all 45 tools with their JSON Schemas |
tools/call | Invokes a tool by name with arguments |
ping | Liveness 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)
| Tool | Description |
|---|---|
create_order | Create an order, auto-generating a Lightning invoice by default |
get_order | Fetch an order by ID (expandable: invoice, payment, merchant) |
list_orders | List orders with Ransack filters and pagination |
cancel_order | Cancel a pending order |
update_order | Edit a pending order, mark shipped, or mark cash-paid |
get_invoice | Fetch an invoice including its bolt11 string and on-chain address |
check_invoice_status | Live payment check against the Lightning node |
generate_invoice | Generate a fresh invoice for an existing order |
get_invoice_qr | Return the invoice as an SVG QR code |
Payments, checkout & payment requests (8)
| Tool | Description |
|---|---|
list_payments | List confirmed payments with date and amount filters |
get_payment | Fetch payment details |
list_checkout_sessions | List hosted checkout sessions |
get_checkout_session | Fetch a checkout session |
create_checkout_session pk_ | Create a hosted checkout URL; product_id derives price and tax |
create_payment_request | Create an order and invoice in one call |
get_payment_request | Fetch a payment request |
get_payment_request_status | Live status of a payment request |
Products & catalog (15)
| Tool | Description |
|---|---|
get_catalog | Product types, products, taxes, and discounts in one response |
get_catalog_version | Catalog timestamp for cheap cache invalidation |
list_products | List products with filters and pagination |
get_product | Fetch a product by UUID or slug |
create_product | Create a product |
update_product | Update a product |
delete_product | Hard-delete or archive a product |
get_product_key | Return a product's AES-256-GCM key (sensitive) |
rotate_product_key | Rotate the key, keeping the old key for a re-encryption window |
clear_product_old_key | Clear the retained old key once re-encryption is complete |
list_product_types | List product types |
get_product_type | Fetch a product type |
create_product_type | Create a product type |
update_product_type | Update a product type |
delete_product_type | Delete a product type (fails if products are assigned) |
Webhooks (5)
| Tool | Description |
|---|---|
list_webhooks | List webhook endpoints |
get_webhook | Fetch a webhook endpoint |
create_webhook | Create a webhook; returns the signing secret once |
update_webhook | Update a webhook endpoint |
delete_webhook | Delete a webhook endpoint |
Merchant & account (6)
| Tool | Description |
|---|---|
get_merchant | Current merchant profile and settings |
list_wallets | List connected wallets |
get_wallet | Fetch a wallet |
list_merchant_documents | List merchant documents (read-only) |
get_merchant_document | Fetch a merchant document (read-only) |
get_api_token_usage | Current RPM, monthly count, and rate-limit metadata for the calling token |
Access & public (2)
| Tool | Description |
|---|---|
verify_access_token | Verify an access token / macaroon; returns product, order, key, and fingerprint |
list_subscription_plans | List 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.
| Code | Meaning |
|---|---|
-32700 | Parse error — malformed JSON (HTTP 400) |
-32600 | Invalid request envelope |
-32601 | Unknown method |
-32001 | Authentication failed — missing or invalid token (HTTP 401) |
-32000 | Transport 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.