Skip to content

francktrouillez/recurly-mcp

Repository files navigation

recurly-mcp

CI npm version License: MIT Node.js

A read-only MCP (Model Context Protocol) server that exposes the Recurly v2021-02-25 API to LLM clients. Works with any MCP-compatible client (Claude Desktop, Claude Code, Cursor, Cline, Codex CLI, Continue.dev, etc.).

Thirty resource-grouped tools cover every read (GET) endpoint Recurly exposes — accounts, subscriptions, invoices, transactions, line items, plans, coupons, items, usage, exports, external products/subscriptions, and the rest — plus a generic recurly_request escape hatch for anything not directly modeled.

This server is read-only by construction: the HTTP client only ever issues GET. There is no code path that can create, update, or delete Recurly data — including via the escape hatch.

Unofficial. Not affiliated with or endorsed by Recurly.

Install

Claude Code (one-liner)

claude mcp add recurly --scope user \
  --env RECURLY_API_KEY=YOUR_PRIVATE_API_KEY \
  -- npx -y recurly-mcp

Restart Claude Code and the recurly_* tools become available.

Run the binary directly (optional)

The server is normally spawned by your MCP client over stdio. To test it stand-alone:

RECURLY_API_KEY=your_private_api_key npx recurly-mcp

It will wait for JSON-RPC messages on stdin. Useful for debugging the install only.

Configuration

All configuration is via environment variables.

Var Required Default Purpose
RECURLY_API_KEY yes Private API key. Sent as the HTTP Basic auth username (empty password).
RECURLY_REGION no us us or eu — selects the API host.
RECURLY_HOST no https://v3.recurly.com Override the API origin entirely (local mocks, proxies). Overrides RECURLY_REGION.
RECURLY_API_VERSION no v2021-02-25 Recurly API version sent in the Accept header. The tool paths/params here are modeled on v2021-02-25.
RECURLY_TIMEOUT_MS no 15000 Per-request timeout.
RECURLY_MAX_RETRIES no 2 Retries on 429 and 5xx (honors Retry-After, equal-jitter backoff).

Get a private API key from the Recurly dashboard → Integrations → API Credentials. Use a key scoped to read-only access where possible — this server never writes, but defense in depth is good.

MCP client config

The MCP entry below is the same for every MCP client — only the config file location differs.

{
  "mcpServers": {
    "recurly": {
      "command": "npx",
      "args": ["-y", "recurly-mcp"],
      "env": {
        "RECURLY_API_KEY": "your_private_api_key_here"
      }
    }
  }
}

Where to put it, by client:

Client Location
Claude Desktop (macOS) ~/Library/Application Support/Claude/claude_desktop_config.json
Claude Code ~/.claude.json — or use claude mcp add recurly --scope user --env RECURLY_API_KEY=… -- npx -y recurly-mcp
Cursor .cursor/mcp.json (per-project) or ~/.cursor/mcp.json (user-wide)
Cline (VS Code) VS Code Settings → Cline → MCP servers (UI), or cline_mcp_settings.json
Codex CLI ~/.codex/config.json under mcpServers
Continue.dev .continue/config.json under experimental.modelContextProtocolServers

For the EU data region, add "RECURLY_REGION": "eu" to env.

Tools

Every action is read-only. Each tool takes an action discriminator plus the parameters for that action.

Tool Actions
recurly_sites list, get
recurly_accounts list, get, get_balance, get_acquisition, list_acquisitions, list_child_accounts, list_notes, get_note, list_entitlements
recurly_billing_info get, list, get_one
recurly_shipping_addresses list, get
recurly_coupons list, get, list_unique_coupon_codes, get_unique_coupon_code
recurly_coupon_redemptions list_for_account, list_active_for_account, get_for_account, list_for_invoice, list_for_subscription, get_for_subscription
recurly_credit_payments list, get, list_for_account
recurly_invoices list, get, get_pdf, list_line_items, list_related, list_for_account
recurly_line_items list, get, list_for_account
recurly_subscriptions list, get, get_change, get_preview_renewal, list_invoices, list_line_items, list_for_account
recurly_transactions list, get, list_for_account
recurly_custom_field_definitions list, get
recurly_items list, get
recurly_measured_units list, get
recurly_plans list, get, list_add_ons, get_add_on
recurly_add_ons list, get
recurly_shipping_methods list, get
recurly_usage list, get
recurly_export get_dates, get_files
recurly_dunning_campaigns list, get
recurly_invoice_templates list, get, list_accounts
recurly_external_products list, get, list_references, get_reference
recurly_external_subscriptions list, get, list_invoices, list_payment_phases, get_payment_phase, list_for_account
recurly_external_invoices list, get, list_for_account
recurly_external_accounts list, get
recurly_general_ledger_accounts list, get
recurly_performance_obligations list, get
recurly_price_segments list, get
recurly_business_entities list, get, list_invoices
recurly_gift_cards list, get
recurly_request Escape hatch — a raw GET to any Recurly API path.

Tools return raw Recurly JSON payloads with no field-stripping. list actions add a _pagination metadata object so the model can iterate pages.

IDs and codes

Most ID parameters accept either the opaque Recurly object ID (e.g. e28zov4fw0v2) or a prefixed human key:

  • accounts/plans/items/coupons/…: code-<your_code>
  • sites: subdomain-<name>
  • invoices: number-<invoice_number>
  • subscriptions/transactions: uuid-<uuid>

Values are URL-encoded before interpolation, so codes containing special characters work, and path-traversal segments are rejected.

Pagination

Recurly uses cursor-based pagination. list actions accept limit (1–200), order (asc/desc), sort, cursor, ids, begin_time, end_time, plus resource-specific filters (state, type, etc.). Responses include Recurly's native has_more/next, and this server adds a _pagination hint:

{ "object": "list", "has_more": true, "next": "/accounts?cursor=…", "data": [ ],
  "_pagination": { "has_more": true, "next_cursor": "" } }

Pass _pagination.next_cursor back as cursor to fetch the next page.

Invoice PDFs

recurly_invoices get_pdf returns the PDF as a base64 wrapper rather than a mangled string:

{ "object": "binary_file", "content_type": "application/pdf", "encoding": "base64", "byte_length": 12345, "data": "JVBERi0…" }

Coverage notes

  • Write operations are intentionally not modeled. This is a read-only server; the client cannot issue anything but GET.
  • Filters beyond the common set are reachable via recurly_request ({ "path": "/...", "query": { … } }) if a specific list endpoint accepts a parameter not modeled on its typed tool.

Development

npm install
npm test                 # vitest, 154 tests
npm run typecheck
npm run lint
npm run build            # emits dist/
npm run validate         # spawns the built server, checks tool schemas (expects 31 tools)
npm run dev              # tsx src/bin.ts (for local stdio testing)

Contributing

Issues and pull requests welcome at https://github.com/francktrouillez/recurly-mcp/issues.

Bug reports are most useful with: the tool and action you called, the params (with secrets redacted), and the response.

License

MIT

About

Unofficial, read-only MCP (Model Context Protocol) server for the Recurly API. Works with Claude, Cursor, Cline, Codex CLI, and any MCP-compatible client.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors