Recurly

Lightweight, dependency-free, in-memory Recurly API v3 fake for testing code that uses the Recurly subscription/billing API.

Default port: 4870

Quick start

import { RecurlyServer } from "./services/recurly/src/server.js";

const server = new RecurlyServer(4870);
await server.start();
// ... run your app/tests ...
await server.stop();

Auth is HTTP Basic with the API key as the username (empty password), matching the real Recurly v3 API:

const basic = Buffer.from("parlel:").toString("base64");
const res = await fetch("http://127.0.0.1:4870/accounts", {
  method: "POST",
  headers: { Authorization: `Basic ${basic}`, "Content-Type": "application/json" },
  body: JSON.stringify({ code: "alice", email: "alice@parlel.dev" }),
});

Access via MCP / preview URL

Reachable at its preview URL (http://127.0.0.1:4870) and through the parlel MCP server as the recurly tool. Set RECURLY_BASE_URL=http://127.0.0.1:4870 and any non-empty RECURLY_API_KEY.

Implemented operations

Resources carry an object discriminator ("account", "plan", "subscription").

Error envelope

{ "error": { "type": "validation", "message": "..." } }

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
Accounts CRUD✅ Supported
Plans list/create/get✅ Supported
Subscriptions list/create✅ Supported
Purchases✅ Supported
Basic auth (api key as username)✓ By design — Intentional for a local, zero-cost test emulator
Invoices / line items / coupons / billing-info⟳ Roadmap
Real charging / dunning⟳ Roadmap — Purchases auto-paid

Manifest

See services/recurly/manifest.json — name recurly, port 4870, protocol http, healthcheck /health, env RECURLY_API_KEY, RECURLY_BASE_URL.

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

RECURLY_API_KEY=parlel
RECURLY_BASE_URL=http://parlel-bridge:4870
<!-- parlel:testenv:end -->