Askell MCP

Servidor MCP para la API de pagos y suscripciones de Askell. Descubre endpoints, inspecciona clientes, contratos y facturación, y llama a la API desde Cursor o Claude.

Documentación

askell-mcp

Servidor MCP para la API de pagos y suscripciones de Askell.

Conéctalo a Cursor, Claude Desktop o cualquier cliente MCP para descubrir los endpoints de Askell, inspeccionar clientes/contratos/facturación y llamar a la API. Las lecturas y escrituras son herramientas separadas para que los clientes puedan mostrar su propia interfaz de aprobación en las mutaciones.

Requisitos

  • Una cuenta de Askell y una clave API secreta (desde el panel de Askell)
  • Una de las siguientes opciones:
    • Bun ≥ 1.4.0 (para bunx), o
    • un binario precompilado desde Releases (no se necesita Bun)

Inicio rápido

1. Obtener claves API

En el panel de Askell, copia tu clave API privada (secreta). Opcionalmente también la clave pública (solo se necesita para los endpoints temporales de método de pago / estado de checkout).

2. Añadir a tu cliente MCP

Prefiere dos entradas de servidor si tienes claves de producción y sandbox. Los nombres de las herramientas son los mismos en ambos; el cliente los distingue por la clave del servidor (askell-prod vs askell-sandbox). Las instrucciones de cada instancia incluyen el entorno al que se está conectando.

Coloca las claves en archivos dotenv ignorados por git, no en JSON. Copia .env.example:

  • .env — producción (ASKELL_ENV=production y las claves de ese panel)
  • .env.sandbox — sandbox (ASKELL_ENV=sandbox y las claves de ese panel)

Bun no carga automáticamente .env.sandbox. --no-env-file evita que el proceso de sandbox también lea un .env de producción que se encuentre en el directorio de trabajo actual.

Cursor

Archivo del proyecto: .cursor/mcp.json. mcp.json.example tiene esta forma. ${workspaceFolder} es el directorio que contiene ese mcp.json (la raíz del repositorio cuando el archivo es .cursor/mcp.json). En ~/.cursor/mcp.json, usa una ruta absoluta de envFile.

Con 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"
    }
  }
}

Con un binario (descarga askell-mcp-<os>-<arch> desde Releases, luego chmod +x). Mismo envFile; el binario lee el entorno que inyecta Cursor:

{
  "mcpServers": {
    "askell-prod": {
      "command": "/absolute/path/to/askell-mcp-linux-x64",
      "envFile": "${workspaceFolder}/.env"
    }
  }
}

Recarga la ventana después de guardar.

Claude Desktop

Archivo de configuración:

  • Linux: ~/.config/Claude/claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Sin campo envFile. El directorio de trabajo del proceso de escritorio no es tu repositorio, por lo que una ruta relativa de .env no se resuelve. Con Bun, pasa una ruta absoluta de --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"]
    }
  }
}

Un binario no tiene --env-file. Coloca las claves en env (texto plano en ese archivo JSON):

{
  "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"
      }
    }
  }
}

Cierra Claude Desktop por completo y vuelve a abrirlo. Guardar el archivo no es suficiente.

Claude Code

El .mcp.json del proyecto expande ${VAR} desde el entorno del proceso que lanzó claude. No carga un archivo dotenv. Los argumentos de --env-file de Bun de la sección de Desktop funcionan aquí también; una ruta relativa es suficiente cuando inicias claude desde el repositorio. ${ASKELL_PRIVATE_API_KEY} dentro de env solo funciona cuando esa variable ya está exportada en ese entorno. Un archivo .env por sí solo no se lee.

Configuración

VariableRequeridaPredeterminadoDescripción
ASKELL_PRIVATE_API_KEYsí*—Clave API secreta (o ASKELL_SECRET_API_KEY)
ASKELL_PUBLIC_API_KEYno—Clave pública para algunos endpoints de checkout/pago
ASKELL_ENVnoproductionproduction | sandbox — selecciona el host oficial de la API
ASKELL_API_BASE_URLno—Base de API personalizada/local solamente. No la configures junto con ASKELL_ENV a menos que coincida
ASKELL_RESPONSE_MAX_BYTESno64000Tamaño máximo de respuesta devuelto al modelo
ASKELL_MUTATION_GATEnoautoauto / elicit / off — ver más abajo
ASKELL_REQUIRE_MUTATION_APPROVALno—Alias obsoleto: true→elicit, false→off

ASKELL_ENV elige un host estable (misma superficie v1/v2):

  • production — https://askell.is/api
  • sandbox — https://sandbox.askell.is/api (inquilino aislado; claves de ese panel)

Apunta una segunda entrada de servidor MCP a sandbox (ASKELL_ENV=sandbox) en lugar de cambiar el entorno en un solo proceso. Las claves no funcionan entre hosts. Áskell Test Gateway es un adquirente de pagos (tarjetas falsas) en cualquiera de los hosts — no es lo mismo que la API de sandbox. La documentación oficial en docs.askell.is todavía documenta Test Gateway y puede omitir el host de sandbox.

ASKELL_MUTATION_GATE:

  • auto (predeterminado) — formulario de confirmación solo si el sobre _meta de esta solicitud declaró elicitación de formulario (MCP 2026-07-28). Los clientes de la era 2025 (Cursor, la mayoría de los hosts) no envían ese sobre, por lo que la mutación se ejecuta y su propia interfaz de "permitir esta herramienta" es la puerta.
  • elicit — siempre devolver un formulario de elicitación. El SDK rechaza la llamada si el cliente no puede cumplirla (sobre 2026 / inicialización 2025 a través del shim heredado).
  • off — nunca preguntar (evaluación / automatización confiable).

Si tanto ASKELL_MUTATION_GATE como ASKELL_REQUIRE_MUTATION_APPROVAL están configurados, ASKELL_MUTATION_GATE gana.

Lo que puedes hacer

Flujo de trabajo típico de un agente:

  1. Descubrir — askell_list_operations / askell_describe_operation (desde OpenAPI v1 + v2 incluido)
  2. Tareas de soporte — ayudas de cliente/contrato/facturación a continuación
  3. Cualquier otra cosa — askell_call para GET/HEAD, askell_mutate para POST/PUT/PATCH/DELETE

Herramientas

HerramientaDescripción
askell_list_operationsBuscar operaciones OpenAPI incluidas
askell_describe_operationParámetros y esquema del cuerpo para una operación
askell_callGET/HEAD cualquier endpoint v1/v2
askell_mutatePOST/PUT/PATCH/DELETE cualquier endpoint v1/v2
askell_paginate_allSeguir endpoints de listas paginadas
askell_customer_overviewCliente v1 + suscripciones
askell_contract_overviewContrato de suscripción v2 + ejecuciones de facturación
askell_billing_run_triageEjecución de facturación v2 (+ contrato opcional)
askell_list_webhooksListar webhooks configurados (hmac_secret redactado)

Recursos

URIContenido
askell://spec/v1OpenAPI v1
askell://spec/v2OpenAPI v2
askell://docs/webhook-eventsReferencia de eventos de webhook

Notas de la API (breves)

  • v1 — rutas heredadas como /customers/, /subscriptions/ (sin prefijo /v2)
  • v2 — modelo actual: catálogos, cotizaciones, checkouts, contratos, ejecuciones de facturación, cupones/códigos de promoción, órdenes de cumplimiento bajo /v2/
  • Descuentos v2 — CRUD de catálogo /v2/coupons/ + /v2/promotion-codes/ (cupón = definición, código de promoción = lo que escribe el cliente). Contrato: GET/POST /v2/subscription-contracts/{id}/discount|apply-code|remove-discount (uno activo). Las cotizaciones toman promotion_code y, para un comprador existente, customer (id) para que se apliquen descuentos combinados + restricciones de promoción. Los totales del primer período ya incluyen cupón + combinado; quote.recurring_* incluyen combinado pero no el cupón (discount.recurring_final_amount mientras el cupón esté activo). El finalize recurrente necesita un método de pago verificado incluso cuando el monto a pagar ahora es 0. No es el campo discount 0–100 de v1.
  • Cumplimiento v2 — GET /v2/fulfillment-orders/ para backfill; POST .../{id}/fulfill/ (cuerpo de seguimiento opcional) y POST .../{id}/cancel/ marcan como enviado/cancelado. Mismo cuerpo que los webhooks de fulfillment_order.*.
  • Las rutas usan barras diagonales finales
  • Prefiere v2 para nuevas integraciones; v1 permanece para las existentes
  • Documentación: docs.askell.is · OpenAPI: v1 · v2

Licencia

MIT

Contribuciones

Consulta CONTRIBUTING.md para desarrollo local, pruebas y versiones.