@heysash/lemonsqueezy-mcp
v0.1.1
Published
A Model Context Protocol (MCP) server for Lemon Squeezy — 44 audited tools over the official SDK, security-first. Works with any Lemon Squeezy account.
Maintainers
Readme
lemonsqueezy-mcp

A Model Context Protocol server for Lemon Squeezy — 44 audited tools over the official SDK, security-first. Works with any Lemon Squeezy account.
An independent, unofficial integration — not affiliated with or endorsed by Lemon Squeezy.
What this is
An MCP server that lets Claude (Claude Code, Cowork, Claude Desktop) — or any
MCP-capable client — talk to your Lemon Squeezy account in plain language. Every
tool is a thin, audited wrapper around the official @lemonsqueezy/lemonsqueezy.js
SDK. The server runs locally over stdio; your API key never leaves your machine.
Features
44 MCP tools cover the full Lemon Squeezy API surface:
| Category | Read | Mutating | Total | |----------|-----:|---------:|------:| | Meta | 1 | 0 | 1 | | Stores | 2 | 0 | 2 | | Products / Variants / Prices | 6 | 0 | 6 | | Subscriptions | 2 | 4 | 6 | | Customers | 2 | 3 | 5 | | Orders | 3 | 1 | 4 | | Discounts | 3 | 2 | 5 | | License Keys | 4 | 3 | 7 | | Checkouts | 2 | 1 | 3 | | Webhooks | 2 | 3 | 5 | | Total | 27 | 17 | 44 |
Plus a security model built in (key never leaked, redacted audit log, store
allowlist, read-only mode, test_mode signalling — see below)
and two workflow skills (skills/) that chain the tools into reproducible
tasks: lemonsqueezy-tier-setup and
lemonsqueezy-webhook-test.
Install
Via npx (no install — recommended for MCP clients): see
Connect your MCP client below; npx fetches the
package on first run.
Global:
npm install -g @heysash/lemonsqueezy-mcp
lemonsqueezy-mcp # starts a stdio server (expects LEMONSQUEEZY_API_KEY in env)From source:
git clone https://github.com/heysash/lemonsqueezy-mcp.git
cd lemonsqueezy-mcp
npm install
npm run buildRequires Node.js ≥ 18.
Configure
Set your Lemon Squeezy API key. Get one from app.lemonsqueezy.com/settings/api.
LEMONSQUEEZY_API_KEY=<your Lemon Squeezy API key>Optional:
| Variable | Effect |
|----------|--------|
| LEMONSQUEEZY_ALLOWED_STORE_IDS=12345,67890 | Reject destructive tool calls that target any other store. Strongly recommended when you have a test + production store. |
| LEMONSQUEEZY_AUDIT_LOG_FILE=./audit-logs/lemonsqueezy-mcp.jsonl | Append every destructive call to a JSONL file. Stderr logging is always on. |
| LEMONSQUEEZY_READ_ONLY=true | Disable all destructive tools (create/update/delete/cancel/pause/resume/refund). Useful for audit sessions. |
Connect your MCP client
Add the server to your MCP configuration — e.g. ~/.claude.json, an .mcp.json
in your repo, or Claude Desktop's config:
{
"mcpServers": {
"lemonsqueezy-mcp": {
"command": "npx",
"args": ["-y", "@heysash/lemonsqueezy-mcp"],
"env": {
"LEMONSQUEEZY_API_KEY": "your-key-here"
}
}
}
}To run a locally built copy instead of npx, use
"command": "node", "args": ["/absolute/path/to/lemonsqueezy-mcp/dist/index.js"]
(see examples/claude-code-mcp-config.json).
Restart the client and verify with lemonsqueezy_whoami from a chat — it reports
the authenticated account and whether the key is a test or live key.
Tool catalogue
| Tool | What it does | Destructive |
|------|--------------|:-----------:|
| lemonsqueezy_whoami | Verify the API key; surfaces test_mode | — |
| lemonsqueezy_list_stores / lemonsqueezy_get_store | Stores | — |
| lemonsqueezy_list_products / lemonsqueezy_get_product | Products | — |
| lemonsqueezy_list_variants / lemonsqueezy_get_variant | Variants (pricing tiers) | — |
| lemonsqueezy_list_prices / lemonsqueezy_get_price | Prices | — |
| lemonsqueezy_list_subscriptions / lemonsqueezy_get_subscription | Subscriptions | — |
| lemonsqueezy_update_subscription | Change variant, billing anchor, proration | ✓ |
| lemonsqueezy_cancel_subscription | Cancel at period end | ✓ |
| lemonsqueezy_pause_subscription / lemonsqueezy_resume_subscription | Pause / resume | ✓ |
| lemonsqueezy_list_customers / lemonsqueezy_get_customer | Customers | — |
| lemonsqueezy_create_customer / lemonsqueezy_update_customer / lemonsqueezy_archive_customer | CRUD | ✓ |
| lemonsqueezy_list_orders / lemonsqueezy_get_order / lemonsqueezy_list_order_items | Orders | — |
| lemonsqueezy_refund_order | Issue refund | ✓ |
| lemonsqueezy_list_discounts / lemonsqueezy_get_discount / lemonsqueezy_list_discount_redemptions | Discounts | — |
| lemonsqueezy_create_discount / lemonsqueezy_delete_discount | Create / delete discount codes | ✓ |
| lemonsqueezy_list_license_keys / lemonsqueezy_get_license_key / lemonsqueezy_list_license_key_instances / lemonsqueezy_validate_license | License keys | — |
| lemonsqueezy_update_license_key / lemonsqueezy_activate_license / lemonsqueezy_deactivate_license | Mutating | ✓ |
| lemonsqueezy_list_checkouts / lemonsqueezy_get_checkout | Checkouts | — |
| lemonsqueezy_create_checkout | Create a one-off checkout URL | ✓ |
| lemonsqueezy_list_webhooks / lemonsqueezy_get_webhook | Webhooks | — |
| lemonsqueezy_create_webhook / lemonsqueezy_update_webhook / lemonsqueezy_delete_webhook | Mutating | ✓ |
API constraint: Lemon Squeezy does NOT allow creating products or variants via the REST API — they must be created in the dashboard. The
lemonsqueezy-tier-setupskill wires dashboard-created products into your config rather than creating them from scratch.
Skills
Optional Claude skills (plain markdown under skills/) that turn the
tools into reproducible workflows. Copy them into your skill registry
(cp -r skills/lemonsqueezy-* ~/.claude/skills/):
lemonsqueezy-tier-setup— discover a store's subscription tiers and emit.envlines + a summary table.lemonsqueezy-webhook-test— send signature-valid synthetic webhook payloads to your handler and check the responses. (Lemon Squeezy has no official test-webhook API — this fills the gap.)
Security model
Payment tooling handles a live API key, so security is a first-class design goal, not an afterthought:
- The API key is read only from
LEMONSQUEEZY_API_KEYand never appears in tool responses, error messages or audit logs. - Audit log entries automatically redact any field whose key matches
apiKey,api_key,authorization,token,secret,password,lemonsqueezy_api_key. - Destructive tools carry the MCP
destructiveHint: trueannotation so the client can ask for confirmation before mutating anything. - Store allowlist is enforced: with
LEMONSQUEEZY_ALLOWED_STORE_IDSset, any destructive tool that targets a store outside the list is rejected and audited asdenied. LEMONSQUEEZY_READ_ONLY=truedisables every destructive tool — recommended for shared MCP sessions.lemonsqueezy_whoamisurfaces the response-leveltest_modeflag, so a caller can confirm a key operates on test data before any write.
Develop
npm run dev # tsx-watch the server (stdio)
npm run test # vitest unit + protocol-level integration
npm run coverage # vitest run --coverage (v8), enforced ≥ 90% lines/statements
npm run lint # eslint (flat config)
npm run smoke # API-free end-to-end smoke test against the compiled binary
npm run typecheck # tsc --noEmitFor a real-API check against your own Test-Mode account,
scripts/live-verify.mjs drives the compiled server
over stdio through a plan of tool calls. Launch it with the key injected by your
secret manager — never persist or echo the key, e.g.
op run --env-file=<template> -- node scripts/live-verify.mjs <plan.json> [out.json].
See CONTRIBUTING.md for the full workflow.
Works with
Any Lemon Squeezy account, and any framework or language — the server speaks the
MCP protocol over stdio. It pairs naturally with SaaS apps that bind checkouts to
their own users via Lemon Squeezy custom_data.
Maintainer
Built and maintained by heysash Studio (Sascha Rahn).
License
MIT © heysash Studio (Sascha Rahn) — see LICENSE and NOTICE.
