MCP Spotlight: Stripe MCP Server — The Payments Bridge With Restricted API Keys, Customer-Portal Scope Isolation, and the Money-Movement Default for Agents
Server: @stripe/mcp by Stripe
License: MIT · Tools: ~30 (customers, payment intents, subscriptions, products, invoices, refunds, disputes, payouts)
Coverage: The Stripe payments platform — customers, payment methods, intents, subscriptions, products, prices, invoices, refunds, disputes, payouts, balance, reports
Transport: stdio (NPX) · Auth: Restricted API Key (per-resource, scoped permissions) + OAuth
Security: PCI-scope minimization · customer-portal scope isolation · webhook-first event model
GitHub: github.com/stripe/agent-toolkit
Docs: docs.stripe.com/mcp · stripe.com/agents
Every agent that handles money eventually needs Stripe. The naive "give the agent a full secret API key" approach violates PCI scope and grants write access to every customer, every subscription, every payout. The "wrap Stripe's REST API as 200+ MCP tools" approach bloats the context window past usability. The "give the agent nothing" approach blocks the entire payment-automation category.
The official Stripe MCP Server by Stripe is the bridge that resolves this. ~30 focused tools covering the payments lifecycle — customers, payment intents, subscriptions, products, invoices, refunds, disputes — built with restricted API keys for per-resource scope isolation. MIT-licensed, official Stripe-maintained. This is the server Stripe itself ships for its agent ecosystem.
This is the payment-automation default for AI agents in 2026. Small surface, hard security guarantees, ubiquitous use.
The Architecture: Payments-First Tool Design
The Stripe MCP Server's tool surface is organized around how payment flows actually work:
| Category | Tools | Purpose |
|---|---|---|
| Customers | ~5 tools: list, get, create, update, delete | Customer lifecycle |
| Payment Intents | ~5 tools: list, get, create, update, capture | Payment lifecycle |
| Subscriptions | ~5 tools: list, get, create, update, cancel | Recurring revenue |
| Products & Prices | ~4 tools: list, get, create, update | Catalog management |
| Invoices | ~4 tools: list, get, create, finalize | Invoicing |
| Refunds | ~3 tools: list, get, create | Refund flow |
| Disputes | ~3 tools: list, get, update | Chargeback management |
| Payouts | ~2 tools: list, get | Bank settlement |
| Balance | ~1 tool: get_balance | Account balance |
| Reports | ~1 tool: get_report | Financial reporting |
| Search | ~1 tool: search | Full-text discovery |
The tools are focused. The agent gets the high-leverage primitives — payment intents, subscriptions, customers, products — and composes them into payment workflows.
The Killer Feature: Restricted API Keys
The single biggest security innovation: Stripe Restricted API Keys. These are not your standard sk_live_... secret key. Restricted keys are:
- Per-resource scoped — limit to specific customers, specific products, specific subscriptions
- Per-action scoped —
read,write, or both, per resource - Per-environment scoped — separate keys for test mode, live mode, and per environment
- Time-bounded — optional expiration dates
- Cancellable — revoked instantly without affecting other keys
The canonical restricted key for an agent looks like:
{
"name": "support-bot-agent",
"scope": {
"customer": "read",
"customer_payment_method": "read",
"payment_intent": "read",
"subscription": "read",
"refund": "write"
},
"resources": {
"customer": "cus_*",
"subscription": "sub_*"
}
}
This agent can:
- Read all customer data
- Read all payment methods
- Read all payment intents
- Read all subscriptions
- Write refunds (create new ones, read existing)
It cannot:
- Modify customer data
- Create or modify subscriptions
- Modify payment intents
- Create disputes or payouts
- Access balance or reports
The blast radius is bounded by design. A compromised agent can issue refunds (within the refund policy) but cannot move money to attackers, cannot escalate privileges, cannot touch unrelated customer data.
For multi-tenant SaaS setups (one Stripe account per customer), restricted keys go further — one key per tenant, scoped to that tenant's resources only. The agent's authorization is per-tenant, principle-of-least-privilege.
The PCI Scope Advantage
The MCP server design dramatically reduces PCI scope. By exposing a structured tool surface instead of raw API access:
- No raw card data — the agent never sees card numbers, CVCs, or expiration dates
- Tokenized payments — payments flow through Stripe Elements, Stripe Checkout, or Stripe's mobile SDKs. The agent operates on
payment_intentobjects, not raw card data. - No card storage — Stripe handles all sensitive data; the agent operates on tokens and references
- No raw API endpoints — the MCP surface hides the underlying REST calls; the agent doesn't construct raw requests that might inadvertently include sensitive fields
For agents operating in PCI-DSS environments, this is the right primitive. The agent doesn't touch cardholder data. Stripe's compliance regime is inherited.
For EU-DSGVO/GDPR environments, restricted keys enforce data minimization — the agent gets only the customer fields it needs, not the entire customer record.
The Payment Intent Workflow
The canonical agent-driven payment flow:
User: "Issue a refund for the customer's last failed payment."
Agent:
1. search(query="customer_email = 'kevin@centerbit.co'")
→ Returns the customer record
2. list_payment_intents(customer="cus_...", limit=5)
→ Returns recent payment intents
3. get_payment_intent(id="pi_...")
→ Full payment intent with last_payment_error, amount, status
4. Confirm with the user (HITL gate):
"Issue a refund of $49.00 for payment pi_... (Reason: 'requested_by_customer')"
5. create_refund(payment_intent="pi_...", reason="requested_by_customer")
→ Returns the refund
6. Returns the refund ID + receipt URL
The flow is structured, scoped, and HITL-gated. The agent reads the data, proposes the action, the human approves, the refund is created.
For subscription flows:
User: "Cancel the customer's subscription, effective immediately, prorate the remaining time."
Agent:
1. search → customer record
2. list_subscriptions(customer="cus_...")
→ Returns the active subscription
3. cancel_subscription(id="sub_...", prorate=true, invoice_now=true)
→ Cancels, creates prorated invoice
4. Returns the cancellation confirmation
The Subscription Lifecycle
For SaaS businesses, subscriptions are the core revenue model. The MCP server covers the full lifecycle:
create_product(name="Pro Plan", description="...")
→ Returns the product
create_price(product="prod_...", unit_amount=4900, currency="usd",
recurring={"interval": "month"})
→ Returns the recurring price
create_customer(email="kevin@centerbit.co", name="Kevin Schmidt")
→ Returns the customer
create_subscription(customer="cus_...", items=[{"price": "price_..."}])
→ Returns the subscription
For upgrades, downgrades, cancellations:
update_subscription(
id="sub_...",
items=[{"id": "si_...", "price": "price_new_..."}], // swap to new price
proration_behavior="create_prorations" // or "none", "always_invoice"
)
For pausing (a common SaaS pattern):
update_subscription(id="sub_...", pause_collection={"behavior": "void"})
→ Stops billing, keeps subscription active
The Invoice Flow
For invoice-based billing:
User: "Create an invoice for the customer with the line items from the last quote."
Agent:
1. search → customer
2. create_invoice(
customer="cus_...",
collection_method="send_invoice",
days_until_due=30
)
3. create_invoice_item(invoice="in_...", price="price_...", quantity=2)
4. finalize_invoice(invoice="in_...")
→ Generates the invoice, ready to send
5. send_invoice(invoice="in_...")
→ Emails the invoice to the customer
6. Returns the invoice ID + URL
For recurring invoices (subscriptions), the subscription's invoice_settings handle the automation. The agent only intervenes for one-off invoices.
The Refund + Dispute Pattern
For the most sensitive operations — moving money back — the MCP server exposes:
Refunds
create_refund(
payment_intent="pi_...",
amount=4900, // optional, default = full refund
reason="requested_by_customer", // requested_by_customer, duplicate, fraudulent
metadata={"agent_run_id": "run_...", "operator": "kevin@centerbit.co"}
)
→ Returns the refund
The metadata parameter is critical for audit trails — every refund the agent creates carries a reference to the agent run, the operator, and the context. Facio's audit log cross-references this metadata.
Disputes
For chargebacks:
list_disputes(limit=10, status="needs_response")
→ Returns open disputes
get_dispute(id="dp_...")
→ Returns the dispute with evidence requirements
update_dispute(
id="dp_...",
evidence={
"customer_name": "Kevin Schmidt",
"customer_email_address": "kevin@centerbit.co",
"shipping_address": "...",
"uncategorized_text": "Order shipped on 2026-06-15, tracking XXXX..."
}
)
→ Submits evidence, responds to the dispute
For agents managing high-volume chargebacks, the MCP server is the right primitive. The agent reads the dispute, gathers evidence (from internal systems via other MCP servers), submits the response.
The Webhook-First Event Model
For any real-time payment flow, Stripe webhooks are the trigger. The MCP server exposes:
list_webhook_endpoints— see configured webhookscreate_webhook_endpoint— subscribe to events- Event types:
payment_intent.succeeded,invoice.paid,customer.subscription.deleted,charge.dispute.created, etc.
The recommended pattern:
User: "Set up a webhook so our agent is notified when a payment fails."
Agent:
1. create_webhook_endpoint(
url="https://fac.io/api/stripe-webhook",
enabled_events=[
"payment_intent.payment_failed",
"invoice.payment_failed",
"customer.subscription.deleted",
"charge.dispute.created"
],
description="Agent notification on payment failure"
)
2. Returns the webhook ID + signing secret
The agent then receives events via Facio's webhook receiver, processes them through HITL gates, and acts (issue refund, notify customer, update CRM).
The Balance + Payouts + Reports
For financial reconciliation:
get_balance()
→ Returns:
{
"available": [{"amount": 1250000, "currency": "usd"}],
"pending": [{"amount": 234000, "currency": "usd"}],
"connect_reserved": [...]
}
list_payouts(limit=10)
→ Returns bank settlement history
list_balance_transactions(limit=20, type="charge")
→ Returns the ledger of recent transactions
For agents running finance workflows (reconciliation, anomaly detection, cash-flow forecasting), this is the right primitive.
Facio Integration
{
"mcpServers": {
"stripe": {
"command": "npx",
"args": ["-y", "@stripe/mcp"],
"env": {
"STRIPE_SECRET_KEY": "${credentials.STRIPE_RESTRICTED_KEY}"
}
}
}
}
Critical: use a Restricted API Key, not the full sk_live_... secret key. Facio's secret broker stores the restricted key; the agent never sees the raw value.
Facio's audit trail captures every Stripe MCP call with the tool, the resource ID, the parameters, the result, and the metadata (which includes the agent run ID for cross-referencing). For a regulated team (financial compliance, PCI-DSS, SOX), this is the complete payment-operation record: "Agent at 14:32 UTC created refund re_... for payment_intent pi_..., reason 'requested_by_customer', amount $49.00, agent_run_id run_1234, operator kevin@centerbit.co."
For HITL workflows, the Stripe MCP server's destructive surface is significant — money moves here:
| Tool | Severity | Suggested Gate |
|---|---|---|
list_*, get_*, search, get_balance | Read | None — autonomous |
create_customer, update_customer | Write, contextual | Soft confirm |
create_payment_intent (test mode) | Write, contextual | Soft confirm |
create_payment_intent (live mode) | Write, destructive in effect | Hard confirm + reason required |
create_refund (test mode) | Write, contextual | Soft confirm |
create_refund (live mode) | Write, destructive (money out) | Hard confirm + reason required |
cancel_subscription (live mode) | Write, destructive (cancels revenue) | Hard confirm + reason required |
update_subscription (with proration) | Write, contextual | Soft confirm |
create_invoice, finalize_invoice, send_invoice | Write, contextual | Soft confirm |
update_dispute, submit_evidence | Write, contextual | Soft confirm (deadline-driven) |
create_payout (rare, partner-level) | Write, destructive | Hard confirm + reason required |
delete_customer | Write, destructive | Hard confirm + reason required (GDPR implications) |
The create_refund and cancel_subscription tools deserve special attention — money flows out. Facio should require hard confirmation with the operator reviewing the amount, the customer, the reason, and any contextual metadata before the action proceeds.
For multi-account setups (one Stripe account per business unit, per product, per region), the pattern is one MCP server per account with its own restricted key. The agent switches context per account.
For multi-tenant SaaS setups, the recommended pattern is one Stripe account per customer (Stripe Connect: Standard or Express accounts), one restricted key per tenant, scoped to that tenant's resources. Full tenant isolation at the credential level.
Quickstart
# 1. Create a Restricted API Key in the Stripe Dashboard
# https://dashboard.stripe.com/apikeys
# Set scope (read/write per resource)
# Set resource patterns (e.g., cus_* for specific customers)
# 2. Install the MCP server
npm install -g @stripe/mcp
# 3. Configure your MCP client
{
"mcpServers": {
"stripe": {
"command": "npx",
"args": ["-y", "@stripe/mcp"],
"env": {
"STRIPE_SECRET_KEY": "rk_live_..." // restricted key, not sk_live
}
}
}
}
# 4. First prompts
# "Find the customer with email kevin@centerbit.co"
# "Show me the customer's active subscriptions"
# "Issue a $49 refund for the last failed payment, reason 'requested_by_customer'"
# "Cancel the customer's subscription with proration"
# "Show me this month's payouts and balance"
Use Cases
Customer support automation: "Look up the customer, find the issue, propose the resolution." Search → read → propose → HITL confirm.
Refund processing: "Process the refund request from ticket #1234 — verify the payment, propose the amount, require HITL approval." Search → read → propose → confirm → execute.
Subscription management: "Cancel the customer's subscription, prorate the remaining time, send the cancellation email." Lifecycle management with HITL gates.
Billing inquiry: "Why was this customer charged $99? Show me the invoice breakdown." Invoice retrieval + breakdown explanation.
Failed payment recovery: "Find customers with payment_intent.payment_failed in the last 7 days. For each, retry with a different payment method or send a recovery email." Webhook-driven retry workflow.
Churn analysis: "Which subscriptions were canceled in the last 30 days, and what were the reasons?" Cancellation analysis.
Revenue reconciliation: "Compare our Stripe payouts against our bank deposits for last month. Flag any discrepancies." Multi-source reconciliation.
Dispute management: "Show me open disputes that need evidence. For each, gather supporting documents and submit." Evidence-gathering automation.
Invoice generation: "Generate monthly invoices for all customers on net-30 terms, send them." Recurring invoice automation.
Subscription upgrades: "Upgrade customer from Basic to Pro, prorate, send confirmation." Subscription swap with proration.
Catalog management: "Add a new product with monthly and annual price tiers." Product + price creation.
Customer onboarding: "When a new customer signs up, create their Stripe customer record and a trial subscription." Multi-step onboarding flow.
Multi-currency support: "Create a EUR-priced subscription for our European customers, separate from the USD version." Currency-aware catalog.
Refund analytics: "Show me the top 10 refund reasons this quarter, grouped by product." Refund data analysis.
Webhook-driven automation: "When a payment succeeds, send a receipt and trigger the fulfillment workflow." Real-time event processing.
Tax handling: "For each new subscription, configure tax collection based on the customer's billing address." Tax automation via Stripe Tax.
Compliance auditing: "List all refunds issued in the last 90 days, grouped by operator and reason. Verify HITL approval was obtained for each." Compliance reporting.
Subscription pause: "Pause the customer's subscription for 3 months while they're traveling, no billing during the pause." Subscription pause pattern.
Trial management: "Convert the customer's trial to a paid subscription, send a welcome email." Trial conversion automation.
The Restricted-Key Pattern
The Stripe MCP server's defining innovation — Restricted API Keys instead of full secret keys — is the design lesson every "money-movement" MCP server should learn.
Why restricted keys win:
- PCI scope minimization — the agent never has full account access
- Per-resource scoping — limit to specific customers, specific products
- Per-action scoping — read-only vs read-write, per resource
- Time-bounded — keys can expire
- Cancellable — revoked instantly without affecting other integrations
- Auditable — every key has a name, a description, an owner
For any agent that handles money — refunds, cancellations, payouts, disputes, balance — restricted keys are the only acceptable primitive. Full secret keys give too much power; OAuth tokens are too coarse; per-tenant isolated accounts are the most secure but heaviest setup.
The pattern scales:
| Use Case | Recommended Key |
|---|---|
| Customer support agent | read on customers, subscriptions, payment_intents; write on refunds (capped) |
| Subscription management agent | read on customers; write on subscriptions |
| Dispute management agent | read on disputes, charge; write on dispute evidence |
| Analytics agent | read on everything, no write access |
| Refund-only agent | read on payment_intents; write on refunds (capped amount) |
| Admin agent | full access (rare, multi-tenant operator only) |
For multi-tenant SaaS, the per-tenant isolated account pattern is the gold standard. Each tenant has their own Stripe account (via Connect), the agent uses tenant-specific restricted keys, and a tenant compromise can't affect other tenants.
Bottom Line
The Stripe MCP Server is the payment-automation default for AI agents in 2026. ~30 focused tools, restricted API key support, PCI-scope minimization, webhook-first event model, MIT-licensed, official Stripe-maintained.
For any agent that handles money — refunds, subscriptions, cancellations, disputes, payouts, balance reconciliation, customer billing — this is the bridge. The agent operates on Stripe's data via structured tools, scoped by restricted keys, gated by Facio's HITL approval, audited by Facio's tamper-evident log.
For the broader MCP ecosystem, the Stripe pattern is the design lesson every "financial-API" MCP server should copy. Full secret keys are too powerful. Restricted keys with per-resource + per-action scoping are the right default. When the credentials are least-privilege, the agent's blast radius is bounded.
npx -y @stripe/mcp with STRIPE_SECRET_KEY=rk_live_... (a restricted key) and your agent has payments.
MCP Spotlight is a series covering servers that give AI agents real capabilities. Every server is evaluated for design clarity, ecosystem impact, and integration fit with Facio's HITL-first agent runtime.