Connect Stripe to Claude Desktop in 5 Minutes

On this page

Stripe has a well-documented REST API. This tutorial connects it to Claude Desktop so you can ask Claude about charges, balances, and customers.

What you need

  • Node.js 18+ (or Python 3.10+)
  • A Stripe account with an API key
  • Claude Desktop installed

1. Install paso

npm install -g usepaso

2. Create the declaration

Create usepaso.yaml:

version: "1.0"

service:
  name: Stripe
  description: Payment processing and billing management
  base_url: https://api.stripe.com/v1
  auth:
    type: bearer

capabilities:
  - name: get_balance
    description: Get the current account balance
    method: GET
    path: /balance
    permission: read

  - name: list_charges
    description: List recent charges with optional filters
    method: GET
    path: /charges
    permission: read
    inputs:
      limit:
        type: integer
        default: 10
        description: Number of charges to return (1-100)
        in: query
        constraints:
          max_value: 100
      created_gte:
        type: string
        description: Filter charges created after this Unix timestamp
        in: query

  - name: get_charge
    description: Get details for a specific charge
    method: GET
    path: /charges/{charge_id}
    permission: read
    inputs:
      charge_id:
        type: string
        required: true
        description: The charge ID (e.g. ch_1234)
        in: path

  - name: list_customers
    description: List customers with optional email filter
    method: GET
    path: /customers
    permission: read
    inputs:
      limit:
        type: integer
        default: 10
        description: Number of customers to return (1-100)
        in: query
        constraints:
          max_value: 100
      email:
        type: string
        description: Filter by customer email
        in: query

  - name: create_refund
    description: Refund a charge
    method: POST
    path: /refunds
    permission: write
    consent_required: true
    inputs:
      charge:
        type: string
        required: true
        description: The charge ID to refund
      amount:
        type: integer
        description: Amount to refund in cents (partial refund). Omit for full refund.

permissions:
  read:
    - get_balance
    - list_charges
    - get_charge
    - list_customers
  write:
    - create_refund
  forbidden:
    - delete_customer
    - update_account

Five capabilities. Four reads, one write with consent required. Destructive operations are in forbidden.

3. Validate

usepaso validate --strict
valid (Stripe, 5 capabilities, 0 regrets)

4. Test

usepaso test --all --dry-run
ok get_balance      GET https://api.stripe.com/v1/balance
ok list_charges     GET https://api.stripe.com/v1/charges?limit=10
ok get_charge       GET https://api.stripe.com/v1/charges/{charge_id}
ok list_customers   GET https://api.stripe.com/v1/customers?limit=10
ok create_refund    POST https://api.stripe.com/v1/refunds

5 passed. 5 capabilities total.

All requests build correctly. No API calls were made.

5. Connect to Claude Desktop

One command. paso writes the config for you.

usepaso connect claude-desktop
Added "Stripe" in Claude Desktop config.
  Config: ~/Library/Application Support/Claude/claude_desktop_config.json

Restart Claude Desktop to connect.

Restart Claude Desktop.

6. Try it

Open Claude Desktop and ask:

  • “What’s my current Stripe balance?” Claude calls get_balance and returns your available and pending amounts.
  • “Show me the last 5 charges.” Claude calls list_charges with limit=5.
  • “Find charges from customer alice@example.com.” Claude calls list_customers to find the customer, then list_charges filtered by customer.
  • “Refund charge ch_3ABC123.” Claude shows a confirmation dialog (because consent_required: true), then calls create_refund.

A note on API key scope

Use a restricted API key. Stripe lets you create keys with specific permissions:

  1. Go to Stripe Dashboard > Developers > API keys
  2. Create a restricted key
  3. Enable only the permissions your MCP server needs (Read for charges, customers, balance. Write for refunds.)
  4. Use this restricted key as USEPASO_AUTH_TOKEN

A restricted key combined with paso’s permission model gives you two layers of access control. The key limits what the API allows. paso limits what the agent can call.

Extend it

Add more capabilities as you need them. Each one is a few lines of YAML:

  - name: list_invoices
    description: List invoices with optional status filter
    method: GET
    path: /invoices
    permission: read
    inputs:
      limit:
        type: integer
        default: 10
        in: query
      status:
        type: enum
        values: [draft, open, paid, void, uncollectible]
        description: Filter by invoice status
        in: query

Add it to the capabilities list, run usepaso validate, restart Claude Desktop. No TypeScript. No new handler functions.

Questions

Can I use a test mode key? Yes. Use sk_test_... instead of sk_live_.... All requests go to Stripe’s test environment. Good for trying this out without touching real data.

What about webhook events? paso exposes REST endpoints as MCP tools. Webhooks are push-based and don’t map to the request-response model. For webhook handling, use Stripe’s SDK or a separate service.

Can I do this with Stripe’s OpenAPI spec instead? Yes. usepaso init --from-openapi can generate the declaration from Stripe’s public OpenAPI spec. The spec has hundreds of endpoints, so you’ll want to curate the output. See OpenAPI to MCP in 60 Seconds.

Related:

Read the quick start.