How to Accept Stripe's Machine Payments Protocol (MPP) in Your MCP Server
Monetize your MCP server by accepting per-tool-call payments using Stripe's Machine Payments Protocol. This guide covers pricing schemas, payment verification, and webhook handling.
Accept Stripe's Machine Payments Protocol in Your MCP Server
Stripe's Machine Payments Protocol (MPP) allows developers to instantly monetize custom MCP servers. By exposing premium tools (like proprietary database searches, GPU-heavy calculations, or paid APIs), you can charge AI agents per tool call. The transaction is handled machine-to-machine, with Stripe managing the ledger, fraud detection, and settlement.
Architecture Flow
AI Agent (Client) → MPP-enabled MCP Server → Your Business Logic
↓
Stripe verifies machine wallet
Charges settled per tool call
Funds deposited to your Stripe accountPrerequisites
- ▸A verified Stripe merchant account.
- ▸Node.js 18+ for building the MCP Server.
- ▸Familiarity with Express or similar Node.js HTTP frameworks to handle webhooks.
Step 1: Enable MPP on Your Stripe Account
- ▸Go to Stripe Dashboard → Settings → Machine Payments.
- ▸Enable MPP for your account.
- ▸Create a Merchant MPP Profile to establish your server identity in the Stripe MPP registry.
- ▸Note your
mpp_merchant_id.
Step 2: Install the MPP Server SDK
npm install @stripe/mcp-mpp-server stripe expressStep 3: Add Pricing Metadata to Your Tools
The MPP protocol extends the standard MCP tool schema with an x-mpp-pricing field. This allows the AI agent to explicitly see how much a tool costs before it decides to invoke it.
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { MPPMiddleware } from '@stripe/mcp-mpp-server';
const server = new Server(
{ name: 'my-paid-mcp-server', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'search_records',
description: 'Search our proprietary database of records. Costs 5 cents.',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' },
limit: { type: 'number', description: 'Max results' }
},
required: ['query']
},
'x-mpp-pricing': {
model: 'per_call',
amount: 5, // 5 cents per call
currency: 'usd',
unit: 'cent'
}
}
]
};
});Step 4: Add the MPP Middleware
Wrap your tool execution logic in the MPP Middleware. The middleware intercepts incoming JSON-RPC tool calls, communicates with Stripe to verify the agent's wallet has sufficient funds, places a hold on the funds, executes your tool, and then captures the charge.
import Stripe from 'stripe';
import { MPPMiddleware, MPPConfig } from '@stripe/mcp-mpp-server';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
const mppConfig: MPPConfig = {
stripe,
merchantId: process.env.MPP_MERCHANT_ID!,
pricing: {
search_records: { amount: 5, currency: 'usd', unit: 'cent' }
},
onPaymentSuccess: async (toolName, walletId, chargeId) => {
console.log(`Charged ${walletId} for ${toolName}: charge ${chargeId}`);
}
};
const mpp = new MPPMiddleware(mppConfig);
server.setRequestHandler(CallToolRequestSchema, mpp.wrap(async (request) => {
const { name, arguments: args } = request.params;
if (name === 'search_records') {
const results = await myDatabase.search(args.query, args.limit ?? 10);
return { content: [{ type: 'text', text: JSON.stringify(results) }] };
}
throw new Error(`Unknown tool: ${name}`);
}));Step 5: Handle Webhooks for Settlement Events
To properly reconcile payments in your database, listen for Stripe webhooks.
import express from 'express';
const app = express();
app.post('/stripe/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['stripe-signature']!;
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
} catch (err) {
return res.status(400).send(`Webhook Error: ${err.message}`);
}
if (event.type === 'machine_payment.succeeded') {
const payment = event.data.object;
// Log payment success record in DB using payment.id
}
res.json({ received: true });
});
app.listen(3001);Best Practices & Troubleshooting
- ▸Pricing Transparency: Always include the cost of the tool in the plain text
descriptionfield of the tool, in addition to thex-mpp-pricingschema. LLMs read the description directly to decide if a tool is "worth" calling. - ▸Idempotency: If the connection between the MCP Client and your Server drops after the payment succeeds but before the JSON-RPC response is delivered, the agent may retry the tool call. Ensure your database operations are idempotent to avoid double-charging or corrupting data.
- ▸Payment Declined Error: If the middleware rejects a request with a payment error, it is almost always because the agent's Machine Wallet budget has run dry. The middleware automatically handles formatting the
402 Payment RequiredJSON-RPC error back to the agent. - ▸Webhook Signature Mismatch: Ensure you are using
express.raw({ type: 'application/json' })for the webhook endpoint. Stripe requires the exact raw body buffer to verify the cryptographic signature.
Using with OpenAI Codex
You can use this MCP server with the OpenAI Codex CLI by adding it to your configuration:
codex mcp add --name stripe --command "npx -y @modelcontextprotocol/server-stripe" --env STRIPE_SECRET_KEY=sk_your_keyFor a full list of recommended servers, see Best MCP Servers for OpenAI Codex.
Related Guides
How to Set Up the Brave Search MCP Server for Web Research
Enable your AI agent to search the web using Brave Search API through MCP. Perfect for research, fact-checking, and gathering real-time information.
APIsHow to Use Stripe's Machine Payments Protocol (MPP) as an MCP Client
Learn how to configure your AI agent as an MCP client that can automatically pay per tool usage using Stripe's Machine Payments Protocol — enabling access to premium, monetized MCP servers.
APIsHow to Use the Fetch MCP Server for API Integration
Enable your AI agent to fetch content from any URL or API endpoint. Perfect for reading documentation, consuming REST APIs, and gathering web content.