Stripe MCP Integration

Connect Claude to Stripe APIs via Model Context Protocol. Use when managing customers, subscriptions, invoices, products, or searching Stripe documentation. Triggers: payment, billing, checkout, Stripe API, subscription management.

wrsmith108/stripe-mcp-skill28 installsMITSynced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: Stripe MCP Integration
description: Connect Claude to Stripe APIs via Model Context Protocol. Use when managing customers, subscriptions, invoices, products, or searching Stripe documentation. Triggers: payment, billing, checkout, Stripe API, subscription management.
license: MIT
---

# Stripe MCP Integration

Connect Claude to Stripe's payment infrastructure via the Model Context Protocol (MCP). This skill enables direct interaction with Stripe APIs for customer management, subscriptions, invoices, and documentation search.

## What This Skill Does

- **Customer Management**: Create, retrieve, update, and list customers
- **Subscription Handling**: Manage subscription lifecycles, billing cycles, and pricing
- **Invoice Operations**: Create, finalize, send, and retrieve invoices
- **Product Catalog**: Manage products and prices for your offerings
- **Documentation Search**: Query Stripe's official docs directly

---

## Quick Start

Choose your installation method:

### Option 1: Remote HTTP (Recommended)

Add to `~/.claude/settings.json`:

```json
{
  "mcpServers": {
    "stripe": {
      "type": "http",
      "url": "https://mcp.stripe.com/v1/sse"
    }
  }
}
```

Authenticate when prompted with `stripe_sk_...` key.

### Option 2: Local npm

```bash
# Install the MCP server
npm install -g @stripe/mcp

# Export your key in your shell profile first (e.g. ~/.zshrc), then open a
# fresh shell so it's in your environment before running this:
# export STRIPE_SECRET_KEY="sk_..."

# Add to settings — deliberately NOT using `-e STRIPE_SECRET_KEY=...` here.
# The command below relies on the subprocess inheriting STRIPE_SECRET_KEY
# from your shell environment.
claude mcp add stripe -- npx -y @stripe/mcp
```

**Do not** run `claude mcp add stripe -e STRIPE_SECRET_KEY=sk_live_... -- npx -y @stripe/mcp`. `-e` persists whatever literal value you pass directly into `~/.claude.json` (or the equivalent config for `--scope user`/`--scope project`) in plaintext — it is not encrypted or masked at rest, and that file may not have restrictive permissions by default (check with `ls -la ~/.claude.json`; tighten with `chmod 600 ~/.claude.json` if it isn't owner-only). Export the key in your shell first and add the server without `-e` instead, as shown above.

### Option 3: Project .mcp.json

Create `.mcp.json` in your project root:

```json
{
  "mcpServers": {
    "stripe": {
      "command": "npx",
      "args": ["-y", "@stripe/mcp"],
      "env": {
        "STRIPE_SECRET_KEY": "${STRIPE_SECRET_KEY}"
      }
    }
  }
}
```

Note: whether Claude Code expands `${STRIPE_SECRET_KEY}` against your shell environment when spawning this server is not documented behavior — verify it actually authenticates (`claude mcp list` should show `stripe` connected, not a `Failed to connect` auth error) rather than assuming it works. If it doesn't resolve, fall back to Option 2's pattern (export the var, add the server without embedding a literal value).

---

## Available MCP Tools

| Tool | Description | Example Usage |
|------|-------------|---------------|
| `stripe_create_customer` | Create a new customer | `"Create customer with email user@example.com"` |
| `stripe_retrieve_customer` | Get customer by ID | `"Get customer cus_xxx"` |
| `stripe_list_customers` | List all customers | `"Show my Stripe customers"` |
| `stripe_create_product` | Create a product | `"Create product 'Pro Plan' for $29/month"` |
| `stripe_list_products` | List products | `"Show all products"` |
| `stripe_create_subscription` | Start a subscription | `"Subscribe customer to price_xxx"` |
| `stripe_cancel_subscription` | Cancel subscription | `"Cancel subscription sub_xxx"` |
| `stripe_create_invoice` | Create draft invoice | `"Create invoice for customer cus_xxx"` |
| `stripe_finalize_invoice` | Finalize for payment | `"Finalize invoice in_xxx"` |
| `stripe_search_documentation` | Search Stripe docs | `"Search Stripe docs for webhooks"` |

---

## Stripe ID Prefixes

Use these prefixes to validate IDs in your code:

| Object | Prefix | Example |
|--------|--------|---------|
| Customer | `cus_` | `cus_NffrFeUfNV2Hib` |
| Subscription | `sub_` | `sub_1MowQVLkdIwHu7ixeRlqHVzs` |
| Price | `price_` | `price_1MowQULkdIwHu7ixspc` |
| Product | `prod_` | `prod_NWjs8kKbJWmuuc` |
| Invoice | `in_` | `in_1MtHbELkdIwHu7ixl4OzzPMI` |
| Payment Intent | `pi_` | `pi_3MtwBwLkdIwHu7ix28a3tqPa` |
| Event | `evt_` | `evt_1NG8Du2eZvKYlo2CUI79vXWy` |
| Webhook Endpoint | `we_` | `we_1Mr5jALkdIwHu7ixNsD8AdJZ` |
| Checkout Session | `cs_` | `cs_test_a1b2c3d4` |

---

## Test Mode Development

### Test Cards

| Card Number | Scenario |
|-------------|----------|
| `4242424242424242` | Successful payment |
| `4000000000000002` | Card declined |
| `4000002500003155` | Requires 3D Secure |
| `4000000000009995` | Insufficient funds |
| `4000000000000341` | Attach fails |

### Stripe CLI Testing

```bash
# Install Stripe CLI
brew install stripe/stripe-cli/stripe

# Login to your account
stripe login

# Listen for webhooks locally
stripe listen --forward-to localhost:3000/api/webhooks/stripe

# Trigger test events
stripe trigger checkout.session.completed
stripe trigger customer.subscription.created
stripe trigger invoice.payment_succeeded
```

---

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `STRIPE_SECRET_KEY` | Yes | API key (`sk_test_...` or `sk_live_...`) |
| `STRIPE_WEBHOOK_SECRET` | For webhooks | Webhook signing secret (`whsec_...`) |
| `STRIPE_API_VERSION` | No | Lock API version (e.g., `2024-12-18.acacia`) |

### Secure Key Storage

Never commit keys to version control. Use environment variables or a secrets manager:

```bash
# Development: Use .env file (gitignored)
echo "STRIPE_SECRET_KEY=sk_test_..." >> .env

# Production: Use your platform's secrets manager
# - Cloud platforms: Environment variables or secret managers
# - AWS: Secrets Manager or Parameter Store
# - Self-hosted: HashiCorp Vault or similar
```

This also applies to `claude mcp add`: never pass a literal secret via `-e STRIPE_SECRET_KEY=sk_live_...`. That flag stores the value verbatim, in plaintext, in Claude Code's own config (`~/.claude.json` for `local`/`user` scope). Export the key in your shell profile instead and add the server without `-e` (see Option 2 above), so the subprocess inherits it from the environment rather than it being persisted to disk.

---

## Webhook Signature Verification

### Node.js Pattern

```typescript
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

export async function handleWebhook(request: Request) {
  const body = await request.text();
  const signature = request.headers.get('stripe-signature')!;

  let event: Stripe.Event;

  try {
    event = stripe.webhooks.constructEvent(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!
    );
  } catch (err) {
    console.error('Webhook signature verification failed:', err);
    return new Response('Webhook Error', { status: 400 });
  }

  // Handle the event
  switch (event.type) {
    case 'checkout.session.completed':
      const session = event.data.object as Stripe.Checkout.Session;
      await fulfillOrder(session);
      break;
    case 'customer.subscription.updated':
      const subscription = event.data.object as Stripe.Subscription;
      await updateSubscriptionStatus(subscription);
      break;
    // ... handle other events
  }

  return new Response('OK', { status: 200 });
}
```

### Deno/Edge Function Pattern

```typescript
import Stripe from 'npm:stripe@latest';

const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!, {
  apiVersion: '2024-12-18.acacia',
});

Deno.serve(async (req) => {
  const body = await req.text();
  const signature = req.headers.get('stripe-signature')!;

  // IMPORTANT: Deno requires async verification
  const event = await stripe.webhooks.constructEventAsync(
    body,
    signature,
    Deno.env.get('STRIPE_WEBHOOK_SECRET')!
  );

  // Handle event...
  return new Response(JSON.stringify({ received: true }));
});
```

> **Critical**: Deno and edge runtimes require `constructEventAsync()`, not `constructEvent()`.

---

## Common Webhook Events

| Event | When It Fires | Typical Action |
|-------|---------------|----------------|
| `checkout.session.completed` | Successful checkout | Grant access, send confirmation |
| `customer.subscription.created` | New subscription | Provision account, welcome email |
| `customer.subscription.updated` | Plan change, renewal | Update access level |
| `customer.subscription.deleted` | Cancellation | Revoke access, send offboarding |
| `invoice.payment_succeeded` | Successful charge | Update billing records |
| `invoice.payment_failed` | Failed charge | Notify customer, retry logic |

---

## Troubleshooting

### "No such customer" Error

```
StripeInvalidRequestError: No such customer: 'cus_xxx'
```

**Cause**: Customer ID doesn't exist or using test ID in live mode.
**Fix**: Verify the ID exists in your Stripe Dashboard. Check you're using matching test/live keys.

### Webhook Signature Mismatch

```
Webhook signature verification failed
```

**Cause**: Wrong webhook secret or modified payload.
**Fix**:
1. Get the correct secret from Stripe Dashboard → Webhooks → Signing secret
2. For local testing, use the secret printed by `stripe listen`
3. Ensure you're reading the raw body, not parsed JSON

### Rate Limiting

```
StripeRateLimitError: Too many requests
```

**Cause**: Exceeding 100 read or 100 write requests per second.
**Fix**: Implement exponential backoff, batch operations where possible, cache read results.

---

## Sub-Documentation

- [Webhook Security Patterns](docs/webhooks.md) - Secrets rotation, idempotency, retry handling
- [Testing Guide](docs/testing.md) - Test cards, CLI workflows, E2E patterns

---

## Resources

- [Stripe MCP Documentation](https://docs.stripe.com/mcp)
- [Stripe API Reference](https://docs.stripe.com/api)
- [Webhook Events Reference](https://docs.stripe.com/api/events/types)
- [Stripe CLI Documentation](https://docs.stripe.com/cli)

More AI & ML skills

← All AI & ML skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY