Stripe MCP: How to Use Stripe MCP Servers
In the rapidly evolving landscape of AI-assisted financial operations, the integration of payment processing platforms with large language models represents a significant advancement for developers and businesses. Stripe MCP (Model Context Protocol) servers establish a secure bridge between conversational AI models and Stripe's robust payment infrastructure, enabling AI assistants to process payments, manage customers, handle subscriptions, and analyze transaction data—all through natural language interfaces. This technical implementation transforms AI assistants from simple text generators into powerful financial operation agents capable of executing secure payment workflows while maintaining proper authentication, authorization, and compliance controls.
Introduction
The Model Context Protocol provides a standardized framework for connecting AI models with external tools and data sources. Stripe MCP servers implement this protocol to create a secure, authenticated interface between AI assistants and Stripe's comprehensive payment ecosystem. By leveraging Stripe's extensive API capabilities, MCP servers enable language models to programmatically create payment intents, manage customers, handle subscriptions, process refunds, and analyze transaction patterns—all while maintaining PCI compliance and enforcing proper security measures for sensitive financial operations.
https://github.com/modelcontextprotocol/servers/tree/main/src/stripe (opens in a new tab)
Technical Architecture of Stripe MCP
MCP Protocol Foundation
Stripe MCP operates within the Model Context Protocol architecture, which defines several key components:
-
Transport Layer:
- STDIO (Standard Input/Output): Direct process communication
- SSE (Server-Sent Events): HTTP-based asynchronous communication
- WebSocket: Bidirectional real-time communication
-
Resource Types:
- Prompts: Templated payment workflow patterns
- Tools: Executable Stripe API operations
- Resources: Customer, payment, and account information
-
Serialization Format: JSON for structured data exchange between client and server
Stripe MCP Architecture
The Stripe MCP server implements a multi-layered architecture optimized for payment operations:
stripe-mcp/
├── src/
│ ├── auth/
│ │ ├── api-key-manager.ts # API key management
│ │ ├── webhook-validator.ts # Webhook signature validation
│ │ └── permission-manager.ts # Operation permission controls
│ ├── services/
│ │ ├── payment-service.ts # Payment operations
│ │ ├── customer-service.ts # Customer operations
│ │ ├── subscription-service.ts # Subscription operations
│ │ └── refund-service.ts # Refund operations
│ ├── tools/
│ │ ├── payment-tools.ts # Payment processing tools
│ │ ├── customer-tools.ts # Customer management tools
│ │ ├── subscription-tools.ts # Subscription management tools
│ │ └── analytics-tools.ts # Payment analytics tools
│ ├── resources/
│ │ ├── account-resources.ts # Account information resources
│ │ └── balance-resources.ts # Account balance resources
│ └── server.ts # MCP server implementation
├── config/
│ └── stripe-config.ts # Configuration schema
└── package.json # Dependencies and scripts
The core technical components include:
- API Client Manager: Handles authenticated Stripe API communication
- Request Validator: Validates and sanitizes incoming requests
- Error Handler: Transforms Stripe API errors into user-friendly messages
- Tool Implementations: Translates MCP commands to Stripe API calls
- Webhook Processor: Handles asynchronous payment event notifications
Setup and Installation
Prerequisites
To implement Stripe MCP, ensure you have:
- Node.js 16+ environment
- Stripe account with API keys
- Basic understanding of Stripe's payment flows
- An MCP-compatible client (e.g., Claude Desktop, Cursor, VS Code)
Authentication Configuration
Before installation, obtain the required Stripe API credentials:
- Create or access your Stripe account at https://dashboard.stripe.com (opens in a new tab)
- Navigate to Developers > API keys
- Copy your "Secret key" (starts with
sk_
) - For webhook validation, note your webhook signing secret (starts with
whsec_
)
Installation Methods
Option 1: Using npm
npm install -g stripe-mcp
Option 2: Using Smithery
npx -y @smithery/cli install stripe-mcp --client claude
Option 3: Manual Installation from Source
git clone https://github.com/modelcontextprotocol/servers.git
cd servers/src/stripe
npm install
npm run build
Configuration
The Stripe MCP server requires specific configuration parameters:
-
API Credentials:
STRIPE_API_KEY
: Your Stripe secret keySTRIPE_WEBHOOK_SECRET
: Webhook signing secret (optional)STRIPE_API_VERSION
: Stripe API version to target
-
Security Controls:
STRIPE_ALLOWED_OPERATIONS
: Comma-separated list of allowed operationsSTRIPE_MAX_AMOUNT
: Maximum transaction amount allowedSTRIPE_VERIFICATION_REQUIRED
: Require additional verification for high-value transactions
-
Operational Settings:
STRIPE_CURRENCY
: Default currency for paymentsSTRIPE_REQUEST_TIMEOUT
: API request timeout in millisecondsSTRIPE_IDEMPOTENCY_ENABLED
: Enable idempotency keys for requests
Example configuration in stripe-config.json
:
{
"api": {
"key": "sk_test_abcdefghijklmnopqrstuvwxyz",
"webhookSecret": "whsec_abcdefghijklmnopqrstuvwxyz",
"version": "2023-10-16",
"timeout": 30000
},
"security": {
"allowedOperations": ["payments", "customers", "subscriptions"],
"maxAmount": 10000,
"verificationRequired": true
},
"defaults": {
"currency": "usd",
"idempotencyEnabled": true,
"autoCapture": true
}
}
Integration with MCP Clients
Claude Desktop Integration
To integrate with Claude Desktop, edit the configuration file:
- macOS:
~/Library/Application\ Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%/Claude/claude_desktop_config.json
Add the following configuration:
{
"mcpServers": {
"stripe": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-stripe"],
"env": {
"STRIPE_API_KEY": "sk_test_abcdefghijklmnopqrstuvwxyz",
"STRIPE_CURRENCY": "usd",
"STRIPE_ALLOWED_OPERATIONS": "payments,customers,subscriptions"
}
}
}
}
VS Code Integration
For VS Code with GitHub Copilot, add to settings.json:
{
"github.copilot.chat.mcpServers": [
{
"name": "stripe",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-stripe"],
"env": {
"STRIPE_API_KEY": "sk_test_abcdefghijklmnopqrstuvwxyz",
"STRIPE_CURRENCY": "usd"
}
}
]
}
Core Functionality and Technical Usage
Available Tools
The Stripe MCP server exposes several specialized tools for payment processing:
1. Payment Operations
-
stripe_create_payment: Creates a payment intent
interface CreatePaymentOptions { amount: number; // Amount in smallest currency unit (cents for USD) currency?: string; // 3-letter ISO currency code customerId?: string; // Stripe customer ID paymentMethodId?: string; // Stripe payment method ID description?: string; // Payment description metadata?: Record<string, string>; // Custom metadata receiptEmail?: string; // Email for receipt statementDescriptor?: string; // Statement descriptor (max 22 chars) capture?: boolean; // Auto-capture the payment }
-
stripe_confirm_payment: Confirms a payment intent
interface ConfirmPaymentOptions { paymentIntentId: string; // Stripe payment intent ID paymentMethodId?: string; // Optional payment method to use returnUrl?: string; // URL for redirect after 3D Secure }
-
stripe_cancel_payment: Cancels a payment intent
interface CancelPaymentOptions { paymentIntentId: string; // Stripe payment intent ID cancellationReason?: 'duplicate' | 'fraudulent' | 'requested_by_customer' | 'abandoned'; }
2. Customer Operations
-
stripe_create_customer: Creates a customer
interface CreateCustomerOptions { email?: string; name?: string; phone?: string; description?: string; address?: { line1?: string; line2?: string; city?: string; state?: string; postal_code?: string; country?: string; }; metadata?: Record<string, string>; paymentMethodId?: string; // Attach a payment method }
-
stripe_update_customer: Updates a customer
interface UpdateCustomerOptions { customerId: string; email?: string; name?: string; phone?: string; description?: string; address?: { line1?: string; line2?: string; city?: string; state?: string; postal_code?: string; country?: string; }; metadata?: Record<string, string>; defaultPaymentMethodId?: string; }
3. Subscription Operations
-
stripe_create_subscription: Creates a subscription
interface CreateSubscriptionOptions { customerId: string; priceId: string; // Stripe price ID quantity?: number; trialPeriodDays?: number; metadata?: Record<string, string>; couponId?: string; paymentBehavior?: 'default_incomplete' | 'allow_incomplete' | 'error_if_incomplete' | 'pending_if_incomplete'; }
-
stripe_cancel_subscription: Cancels a subscription
interface CancelSubscriptionOptions { subscriptionId: string; cancelAtPeriodEnd?: boolean; // End at billing period or immediately proration?: boolean; // Prorate charges invoice?: boolean; // Create invoice for remaining time }
4. Analytics Operations
-
stripe_list_payments: Retrieves payment history
interface ListPaymentsOptions { limit?: number; startingAfter?: string; endingBefore?: string; created?: { gt?: number; // Unix timestamp gte?: number; lt?: number; lte?: number; }; customerId?: string; status?: 'succeeded' | 'pending' | 'canceled'; }
-
stripe_get_balance: Retrieves account balance
interface GetBalanceOptions { detailed?: boolean; // Include pending transactions }
Technical Usage Patterns
Complete Payment Flow
// 1. Create a customer
const customer = await tools.stripe_create_customer({
email: "customer@example.com",
name: "John Doe",
phone: "+15555555555",
description: "New customer from MCP integration"
});
// 2. Create a payment intent
const paymentIntent = await tools.stripe_create_payment({
amount: 2500, // $25.00
currency: "usd",
customerId: customer.id,
description: "Purchase of premium service",
metadata: {
orderId: "order_12345",
product: "premium-subscription"
},
receiptEmail: customer.email,
capture: false // For manual capture later
});
// 3. Attach payment method to customer (assuming we have a payment method ID)
const paymentMethodId = "pm_card_visa"; // Example test payment method
await tools.stripe_attach_payment_method({
customerId: customer.id,
paymentMethodId: paymentMethodId,
setAsDefault: true
});
// 4. Confirm the payment intent with the payment method
const confirmedPayment = await tools.stripe_confirm_payment({
paymentIntentId: paymentIntent.id,
paymentMethodId: paymentMethodId
});
// 5. Check payment status
if (confirmedPayment.status === 'requires_action') {
console.log(`3D Secure URL: ${confirmedPayment.next_action.redirect_to_url.url}`);
} else if (confirmedPayment.status === 'succeeded') {
console.log(`Payment successful. Transaction ID: ${confirmedPayment.id}`);
} else if (confirmedPayment.status === 'requires_capture') {
// 6. Capture the payment if it's authorized but not captured
const capturedPayment = await tools.stripe_capture_payment({
paymentIntentId: confirmedPayment.id,
amountToCapture: confirmedPayment.amount // Capture full amount
});
console.log(`Payment captured. Transaction ID: ${capturedPayment.id}`);
}
Subscription Management
// 1. Create a customer
const customer = await tools.stripe_create_customer({
email: "subscriber@example.com",
name: "Jane Doe",
paymentMethodId: "pm_card_visa" // Example test payment method
});
// 2. Create a subscription
const subscription = await tools.stripe_create_subscription({
customerId: customer.id,
priceId: "price_1234567890", // Example price ID for a subscription plan
trialPeriodDays: 14,
metadata: {
referralSource: "mcp_demo",
campaignId: "spring_2023"
}
});
console.log(`Subscription created. Status: ${subscription.status}`);
console.log(`Trial ends: ${new Date(subscription.trial_end * 1000)}`);
console.log(`Current period ends: ${new Date(subscription.current_period_end * 1000)}`);
// 3. After some time, update the subscription (e.g., change quantity)
const updatedSubscription = await tools.stripe_update_subscription({
subscriptionId: subscription.id,
quantity: 2,
proration: true
});
console.log(`Subscription updated. New amount: ${updatedSubscription.items.data[0].plan.amount * updatedSubscription.items.data[0].quantity}`);
// 4. Eventually, cancel the subscription at period end
const canceledSubscription = await tools.stripe_cancel_subscription({
subscriptionId: subscription.id,
cancelAtPeriodEnd: true
});
console.log(`Subscription will be canceled on: ${new Date(canceledSubscription.cancel_at * 1000)}`);
Advanced Implementation Considerations
Secure API Key Management
Stripe MCP implements robust key security measures:
class ApiKeyManager {
private apiKey: string;
private readonly keyPattern = /^(sk|pk|rk)_(test|live)_[a-zA-Z0-9]{24,}$/;
constructor(apiKey: string) {
if (!this.validateApiKey(apiKey)) {
throw new Error("Invalid Stripe API key format");
}
this.apiKey = apiKey;
}
private validateApiKey(key: string): boolean {
if (!this.keyPattern.test(key)) {
return false;
}
// Check key type for specific operations
const keyType = key.substring(0, 2);
if (keyType === 'pk') {
console.warn("Using publishable key has limited capabilities");
} else if (keyType === 'sk') {
// Verify if using test or live key
const envType = key.substring(3, 7);
if (envType === 'live') {
console.warn("Using live key - real charges will be made");
}
}
return true;
}
getAuthHeader(): Record<string, string> {
return {
Authorization: `Bearer ${this.apiKey}`
};
}
}
Idempotency Implementation
To prevent duplicate payment transactions:
class IdempotencyManager {
private readonly idempotencyKeyPrefix = 'mcp_stripe';
generateIdempotencyKey(operation: string, uniqueIdentifier: string): string {
const timestamp = new Date().toISOString();
const rawKey = `${this.idempotencyKeyPrefix}_${operation}_${uniqueIdentifier}_${timestamp}`;
// Create a deterministic hash for the operation
return crypto
.createHash('sha256')
.update(rawKey)
.digest('hex');
}
getIdempotencyHeader(operation: string, identifier: string): Record<string, string> {
return {
'Idempotency-Key': this.generateIdempotencyKey(operation, identifier)
};
}
}
Webhook Integration for Asynchronous Events
For handling payment status updates:
class WebhookHandler {
private readonly webhookSecret: string;
constructor(webhookSecret: string) {
this.webhookSecret = webhookSecret;
}
verifySignature(body: string, signature: string): boolean {
try {
const event = Stripe.webhooks.constructEvent(
body,
signature,
this.webhookSecret
);
return true;
} catch (err) {
console.error(`Webhook signature verification failed: ${err.message}`);
return false;
}
}
async handleWebhook(event: Stripe.Event): Promise<void> {
// Process different event types
switch (event.type) {
case 'payment_intent.succeeded':
await this.handlePaymentSucceeded(event.data.object);
break;
case 'payment_intent.payment_failed':
await this.handlePaymentFailed(event.data.object);
break;
case 'customer.subscription.created':
await this.handleSubscriptionCreated(event.data.object);
break;
// Handle more event types...
}
}
// Implement specific event handlers...
}
Troubleshooting Common Technical Issues
API Authentication Problems
If experiencing authentication issues:
async function diagnoseApiConnection(): Promise<DiagnosticResult> {
try {
// Try a simple API call that doesn't modify data
const response = await axios.get('https://api.stripe.com/v1/account', {
headers: {
Authorization: `Bearer ${process.env.STRIPE_API_KEY}`
}
});
return {
success: true,
apiVersion: response.headers['stripe-version'],
accountType: response.data.business_type,
message: "API connection successful"
};
} catch (error) {
// Parse Stripe error
if (error.response) {
const statusCode = error.response.status;
const errorType = error.response.data?.error?.type;
const errorMessage = error.response.data?.error?.message;
if (statusCode === 401) {
return {
success: false,
message: "Authentication failed: Invalid API key",
details: errorMessage
};
} else if (errorType === 'invalid_request_error') {
return {
success: false,
message: "Invalid request error",
details: errorMessage
};
} else {
return {
success: false,
message: `API error (${statusCode})`,
details: errorMessage
};
}
}
return {
success: false,
message: "Connection error",
details: error.message
};
}
}
Payment Failure Analysis
For debugging payment rejections:
function analyzePaymentFailure(error: Stripe.StripeError): PaymentFailureAnalysis {
const declineCode = error.decline_code;
const errorCode = error.code;
const errorType = error.type;
// Common decline codes and their user-friendly explanations
const declineReasons = {
'insufficient_funds': "The customer's card has insufficient funds to complete the purchase.",
'lost_card': "The card has been reported lost.",
'stolen_card': "The card has been reported stolen.",
'expired_card': "The card has expired.",
'incorrect_cvc': "The CVC number is incorrect.",
'processing_error': "An error occurred while processing the card.",
'incorrect_number': "The card number is incorrect."
};
// Determine if retry might help
const retryableErrors = [
'processing_error',
'rate_limit_error',
'api_connection_error'
];
// Determine recommended action
let recommendedAction = '';
if (retryableErrors.includes(errorType)) {
recommendedAction = "Retry the payment after a brief delay.";
} else if (declineCode === 'insufficient_funds') {
recommendedAction = "Ask the customer to use a different payment method.";
} else if (declineCode === 'expired_card' || declineCode === 'incorrect_number' || declineCode === 'incorrect_cvc') {
recommendedAction = "Ask the customer to check their card details.";
} else if (errorType === 'card_error') {
recommendedAction = "The card was declined. Try a different payment method.";
} else {
recommendedAction = "Contact support for assistance.";
}
return {
declineCode,
userFriendlyReason: declineReasons[declineCode] || "The payment was declined.",
isRetryable: retryableErrors.includes(errorType),
recommendedAction,
rawError: error.message
};
}
Conclusion
Stripe MCP servers represent a powerful technical bridge between conversational AI and secure payment processing infrastructure. By implementing the Model Context Protocol with Stripe's comprehensive API ecosystem, these servers enable AI assistants to manage financial transactions, handle customer data, process subscriptions, and provide valuable payment insights—all while maintaining strict security controls and PCI compliance.
This implementation establishes a foundation for building secure, scalable payment operations that can be triggered through natural language interaction. As both MCP and Stripe's APIs continue to evolve, we can anticipate further advancements in security features, payment capabilities, and integration options.
For developers seeking to extend their AI systems with payment processing capabilities, Stripe MCP offers a standardized, secure approach that abstracts the complexity of payment APIs while providing AI assistants with powerful tools to execute and manage transactions on behalf of businesses. By following the technical patterns outlined in this article, developers can quickly build sophisticated, AI-powered financial operation systems that leverage the security and reliability of Stripe's battle-tested payment infrastructure.