Back to Browse

Askell MCP Server

Developer ToolsUse Caution4.8MCP RegistryLocal
Free

Server data from the Official MCP Registry

MCP server for the Askell payment and subscription API (Bun + stdio)

About

MCP server for the Askell payment and subscription API (Bun + stdio)

Security Report

4.8
Use Caution4.8High Risk

askell-mcp is a well-structured MCP server for the Askell payment API with proper authentication, appropriate network access, and sound code quality. The server correctly handles API credentials via environment variables, implements appropriate input validation through Zod schemas, and separates read/write operations. Minor code quality observations exist around error handling and logging, but permissions align with its stated purpose as a developer tool for API interaction. Supply chain analysis found 5 known vulnerabilities in dependencies (0 critical, 5 high severity). Package verification found 1 issue.

6 files analyzed · 11 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

HTTP Network Access

Connects to external APIs or services over the internet.

env_vars

Check that this permission is expected for this type of plugin.

File System Read

Reads files on your machine. Normal for tools that analyze or process local data.

process_spawn

Check that this permission is expected for this type of plugin.

What You'll Need

Set these up before or after installing:

Secret API key from the Askell dashboardRequired

Environment variable: ASKELL_PRIVATE_API_KEY

production (default) or sandboxOptional

Environment variable: ASKELL_ENV

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-neschadin-askell-mcp": {
      "env": {
        "ASKELL_ENV": "your-askell-env-here",
        "ASKELL_PRIVATE_API_KEY": "your-askell-private-api-key-here"
      },
      "args": [
        "-y",
        "askell-mcp"
      ],
      "command": "npx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

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:
    • Bun ≥ 1.4.0 (for bunx), or
    • a prebuilt binary from Releases (no Bun needed)

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=production and that dashboard's keys)
  • .env.sandbox — sandbox (ASKELL_ENV=sandbox and 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.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %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

VariableRequiredDefaultDescription
ASKELL_PRIVATE_API_KEYyes*—Secret API key (or ASKELL_SECRET_API_KEY)
ASKELL_PUBLIC_API_KEYno—Public key for a few checkout/payment endpoints
ASKELL_ENVnoproductionproduction | sandbox — selects the official API host
ASKELL_API_BASE_URLno—Custom/local API base only. Do not set together with ASKELL_ENV unless it matches
ASKELL_RESPONSE_MAX_BYTESno64000Max response size returned to the model
ASKELL_MUTATION_GATEnoautoauto / elicit / off — see below
ASKELL_REQUIRE_MUTATION_APPROVALno—Deprecated alias: true→elicit, false→off

ASKELL_ENV picks a stable host (same v1/v2 surface):

  • production — https://askell.is/api
  • sandbox — 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 _meta envelope 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:

  1. Discover — askell_list_operations / askell_describe_operation (from bundled OpenAPI v1 + v2)
  2. Support tasks — customer/contract/billing helpers below
  3. Anything else — askell_call for GET/HEAD, askell_mutate for POST/PUT/PATCH/DELETE

Tools

ToolDescription
askell_list_operationsSearch bundled OpenAPI operations
askell_describe_operationParams and body schema for one operation
askell_callGET/HEAD any v1/v2 endpoint
askell_mutatePOST/PUT/PATCH/DELETE any v1/v2 endpoint
askell_paginate_allFollow paginated list endpoints
askell_customer_overviewv1 customer + subscriptions
askell_contract_overviewv2 subscription contract + billing runs
askell_billing_run_triagev2 billing run (+ optional contract)
askell_list_webhooksList configured webhooks (hmac_secret redacted)

Resources

URIContent
askell://spec/v1OpenAPI v1
askell://spec/v2OpenAPI v2
askell://docs/webhook-eventsWebhook event reference

API notes (short)

  • v1 — legacy paths like /customers/, /subscriptions/ (no /v2 prefix). 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, follow v2_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 update apply_at=now|period_end; cancel a scheduled change with POST .../scheduled-changes/{id}/cancel/. Move the billing anchor with POST .../change-anchor/, not PATCH. PATCH accepts only metadata, reference, payment_processor_override — ignore the description's delivery_address / accounting fields; they are not on V2SubscriptionContractPatch.
  • v2 refunds — billing-run charges are not Payments. POST /v2/billing-runs/{id}/refund/ (full amount, no body). 202 means still succeeded; do not resend immediately. POST /payments/{uuid}/refund/ is one-off only. payment.* may carry billing_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 take promotion_code and, 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_amount while the coupon is active). Recurring finalize needs a verified payment method even when due-now is 0. Not the v1 discount 0–100 field.
  • v2 fulfillment — GET /v2/fulfillment-orders/ for backfill; POST .../{id}/fulfill/ (optional tracking body) and POST .../{id}/cancel/ mark shipped/cancelled. Webhooks: fulfillment_order.created, shipment_booked (extra shipment_id), fulfilled, cancelled. Same body as GET.
  • Paths use trailing slashes
  • Prefer v2 for new integrations; v1 remains for existing ones
  • Docs: docs.askell.is · OpenAPI: v1 · v2

License

MIT

Contributing

See CONTRIBUTING.md for local development, tests, and releases.

Reviews

No reviews yet

Be the first to review this server!