askell-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@askell-mcpShow me the contract overview for contract 9876"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
askell-mcp
MCP server for the Askell payment and subscription API.
Connect it to Cursor, Claude Desktop, or any MCP client to discover Askell endpoints, inspect customers/contracts/billing, and call the API. Reads and writes are separate tools so clients can show their own approval UI on mutations.
Requirements
An Askell account and secret API key (from the Askell dashboard)
One of:
Related MCP server: datagate-mcp
Quick start
1. Get API keys
In the Askell dashboard, copy your private (secret) API key. Optionally also the public key (only needed for temporary payment-method / checkout status endpoints).
2. Add to your MCP client
Prefer two server entries if you have both production and sandbox keys. Tool names are the same on both; the client distinguishes them by the server key (askell-prod vs askell-sandbox). Each instance's instructions include the environment it is talking to.
Put keys in gitignored dotenv files, not in JSON. Copy .env.example:
.env— production (ASKELL_ENV=productionand that dashboard's keys).env.sandbox— sandbox (ASKELL_ENV=sandboxand that dashboard's keys)
Bun does not auto-load .env.sandbox. --no-env-file stops the sandbox process from also reading a production .env that happens to sit in the cwd.
Cursor
Project file: .cursor/mcp.json. mcp.json.example is this shape. ${workspaceFolder} is the directory that contains that mcp.json (the repo root when the file is .cursor/mcp.json). In ~/.cursor/mcp.json, use an absolute envFile path.
With Bun:
{
"mcpServers": {
"askell-prod": {
"command": "bunx",
"args": ["--no-env-file", "x", "askell-mcp"],
"envFile": "${workspaceFolder}/.env"
},
"askell-sandbox": {
"command": "bunx",
"args": ["--no-env-file", "x", "askell-mcp"],
"envFile": "${workspaceFolder}/.env.sandbox"
}
}
}With a binary (download askell-mcp-<os>-<arch> from Releases, then chmod +x). Same envFile; the binary reads the environment Cursor injects:
{
"mcpServers": {
"askell-prod": {
"command": "/absolute/path/to/askell-mcp-linux-x64",
"envFile": "${workspaceFolder}/.env"
}
}
}Reload the window after saving.
Claude Desktop
Config file:
Linux:
~/.config/Claude/claude_desktop_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
No envFile field. The desktop process cwd is not your repo, so a relative .env path does not resolve. With Bun, pass an absolute --env-file:
{
"mcpServers": {
"askell-prod": {
"command": "bunx",
"args": ["--no-env-file", "--env-file=/absolute/path/.env", "x", "askell-mcp"]
},
"askell-sandbox": {
"command": "bunx",
"args": ["--no-env-file", "--env-file=/absolute/path/.env.sandbox", "x", "askell-mcp"]
}
}
}A binary has no --env-file. Put the keys in env (plaintext in that JSON file):
{
"mcpServers": {
"askell-prod": {
"command": "/absolute/path/to/askell-mcp-linux-x64",
"env": {
"ASKELL_ENV": "production",
"ASKELL_PRIVATE_API_KEY": "your_production_secret_api_key",
"ASKELL_PUBLIC_API_KEY": "your_production_public_api_key_optional"
}
}
}
}Quit Claude Desktop completely and reopen it. Saving the file is not enough.
Claude Code
Project .mcp.json expands ${VAR} from the environment of the process that launched claude. It does not load a dotenv file. The Bun --env-file args from the Desktop section work here as well; a relative path is fine when you start claude from the repo. ${ASKELL_PRIVATE_API_KEY} inside env only works when that variable is already exported in that environment. A .env file alone is not read.
Configuration
Variable | Required | Default | Description |
| yes* | — | Secret API key (or |
| no | — | Public key for a few checkout/payment endpoints |
| no |
|
|
| no | — | Custom/local API base only. Do not set together with |
| no |
| Max response size returned to the model |
| no |
|
|
| no | — | Deprecated alias: |
ASKELL_ENV picks a stable host (same v1/v2 surface):
production —
https://askell.is/apisandbox —
https://sandbox.askell.is/api(isolated tenant; keys from that dashboard)
Point a second MCP server entry at sandbox (ASKELL_ENV=sandbox) rather than switching env on one process. Keys do not work across hosts. Áskell Test Gateway is a payment acquirer (fake cards) on either host — not the same as the sandbox API. Official prose at docs.askell.is still documents Test Gateway and may omit the sandbox host.
ASKELL_MUTATION_GATE:
auto(default) — confirmation form only if this request's_metaenvelope declared form elicitation (MCP 2026-07-28). 2025-era clients (Cursor, most hosts) do not send that envelope, so the mutation runs and their own “allow this tool” UI is the gate.elicit— always return an elicitation form. The SDK refuses the call if the client cannot fulfil it (2026 envelope / 2025 initialize via the legacy shim).off— never ask (eval / trusted automation).
If both ASKELL_MUTATION_GATE and ASKELL_REQUIRE_MUTATION_APPROVAL are set, ASKELL_MUTATION_GATE wins.
What you can do
Typical agent workflow:
Discover —
askell_list_operations/askell_describe_operation(from bundled OpenAPI v1 + v2)Support tasks — customer/contract/billing helpers below
Anything else —
askell_callfor GET/HEAD,askell_mutatefor POST/PUT/PATCH/DELETE
Tools
Tool | Description |
| Search bundled OpenAPI operations |
| Params and body schema for one operation |
| GET/HEAD any v1/v2 endpoint |
| POST/PUT/PATCH/DELETE any v1/v2 endpoint |
| Follow paginated list endpoints |
| v1 customer + subscriptions |
| v2 subscription contract + billing runs |
| v2 billing run (+ optional contract) |
| List configured webhooks ( |
Resources
URI | Content |
| OpenAPI v1 |
| OpenAPI v2 |
| Webhook event reference |
API notes (short)
v1 — legacy paths like
/customers/,/subscriptions/(no/v2prefix). Contracts-only accounts refuse new legacy subscriptions (400,code: legacy_subscriptions_disabled). A subscription whose billing moved to a contract refuses cancel/activate/set_expiry/PATCH (code: subscription_managed_by_contract, followv2_endpoint).v2 — current model: catalogs, quotes, checkouts, contracts, billing runs, coupons/promotion codes, fulfillment orders under
/v2/v2 contract changes —
reference(max 128, no commas) on create/patch/list filter. Item updateapply_at=now|period_end; cancel a scheduled change withPOST .../scheduled-changes/{id}/cancel/. Move the billing anchor withPOST .../change-anchor/, not PATCH. PATCH accepts onlymetadata,reference,payment_processor_override— ignore the description'sdelivery_address/ accounting fields; they are not onV2SubscriptionContractPatch.v2 refunds — billing-run charges are not Payments.
POST /v2/billing-runs/{id}/refund/(full amount, no body).202means stillsucceeded; do not resend immediately.POST /payments/{uuid}/refund/is one-off only.payment.*may carrybilling_run_id.v2 discounts — catalog CRUD
/v2/coupons/+/v2/promotion-codes/(coupon = definition, promotion code = what the customer types). Contract:GET/POST /v2/subscription-contracts/{id}/discount|apply-code|remove-discount(one active). Quotes takepromotion_codeand, for an existing buyer,customer(id) so combo discounts + promo restrictions apply. First-period totals already include coupon + combo;quote.recurring_*include combo but not the coupon (discount.recurring_final_amountwhile the coupon is active). Recurringfinalizeneeds a verified payment method even when due-now is 0. Not the v1discount0–100 field.v2 fulfillment —
GET /v2/fulfillment-orders/for backfill;POST .../{id}/fulfill/(optional tracking body) andPOST .../{id}/cancel/mark shipped/cancelled. Webhooks:fulfillment_order.created,shipment_booked(extrashipment_id),fulfilled,cancelled. Same body asGET.Paths use trailing slashes
Prefer v2 for new integrations; v1 remains for existing ones
Docs: docs.askell.is · OpenAPI: v1 · v2
License
Contributing
See CONTRIBUTING.md for local development, tests, and releases.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for Modern Treasury — payment orders, transactions, counterparties and ledgers.
MCP server for Recurly — accounts, subscriptions, invoices, plans; cancel & pause subs.
MCP server for Codat — companies, connections, invoices, bills and financial statements.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for Sherweb Partner API - distributor billing, service provider management, customer subscriptions, and payable charges12Apache 2.0
- AlicenseBqualityCmaintenanceMCP server for the DataGate billing platform API, providing read-only tools to manage customers, invoices, products, agreements, sites, and payments.13MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for the Stripe API with 10 tools covering payments, customers, invoices, and subscriptions. Generated with MCPForge. Destructive and financial operations require human approval.22 npmMIT
- FlicenseAqualityCmaintenanceA demo MCP server exposing billing operations (invoices, customers) with no built-in safety, designed as a test target for NitroWatch governance. It allows reading, sending, archiving, and permanently deleting accounts/invoices without confirmation.5-