@chainbound/payflow-sdk
Version:
257 lines (204 loc) • 7.24 kB
Markdown
# Payflow SDK
The Payflow SDK is a Typescript library for building paid MCP servers using various micropayment protocols. It extends the [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk) to provide a unified interface for building paid MCP servers.
## Features
- [x] Easy interface to register paid tools
- [x] Support for [x402](https://www.x402.org) payment schema with USDC on Base
- [ ] Support for [x402](https://www.x402.org) with other assets and networks
- [ ] Extensible payment processing (like with [Agent Commerce Kit](https://www.agentcommercekit.com/overview/introduction), Stripe, etc.)
## Installation
```bash
npm install /payflow-sdk
# or
pnpm add /payflow-sdk
# or
yarn add /payflow-sdk
```
## Quick Start
### 1. Basic Setup
```typescript
import { PayflowMcpServer } from '@chainbound/payflow-sdk';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
// Create a server
const server = new PayflowMcpServer({
name: 'my-paid-server',
version: '1.0.0',
}, {
x402: {
version: 1,
keyId: process.env.CDP_API_KEY_ID,
keySecret: process.env.CDP_API_KEY_SECRET,
}
});
// Connect transport
const transport = new StdioServerTransport();
await server.connect(transport);
```
### 2. Register a Paid Tool
```typescript
// Simple paid tool without parameters
server.paidTool(
'hello_world',
'Says hello to the world',
{
price: 0.01, // Price in USDC
recipient: '0x1234...' // Ethereum address to receive payment
},
async () => {
return {
content: [{
type: 'text',
text: 'Hello, World!'
}]
};
}
);
```
### 3. Paid Tool with Parameters
```typescript
server.paidTool(
'generate_text',
'Generates custom text based on input',
{
price: 0.05,
recipient: '0x1234...'
},
{
prompt: z.string().describe('The text prompt to generate from'),
length: z.number().max(1000).describe('Maximum length of generated text')
},
async ({ prompt, length }) => {
// Your tool logic here
const generatedText = await someAIService.generate(prompt, length);
return {
content: [{
type: 'text',
text: generatedText
}]
};
}
);
```
## API Reference
### `PayflowMcpServer`
Extends the standard `McpServer` with paid tool capabilities.
```typescript
const server = new PayflowMcpServer(serverInfo, options?);
```
### `paidTool()`
Register a tool that requires payment before execution.
**Signatures:**
```typescript
// Basic paid tool
paidTool(name: string, options: PaymentOptions, callback: ToolCallback)
// With description
paidTool(name: string, description: string, options: PaymentOptions, callback: ToolCallback)
// With parameters schema
paidTool<Args>(name: string, options: PaymentOptions, paramsSchema: Args, callback: ToolCallback<Args>)
// With description and parameters
paidTool<Args>(name: string, description: string, options: PaymentOptions, paramsSchema: Args, callback: ToolCallback<Args>)
// With annotations
paidTool<Args>(name: string, description: string, options: PaymentOptions, paramsSchema: Args, annotations: ToolAnnotations, callback: ToolCallback<Args>)
```
### `PaymentOptions`
Configuration for payment requirements:
```typescript
type PaymentOptions = {
price: number; // Price in USDC
recipient: string; // Ethereum address to receive payment
asset?: string; // Asset address (optional, defaults to USDC)
network?: number | string; // Network (optional, defaults to Base)
}
```
## How Payments Work
1. **Client Request**: Client calls your paid tool with a `payment` parameter containing an x402 payment header
2. **Payment Verification**: SDK automatically verifies the payment against your specified requirements
3. **Tool Execution**: If payment is valid, your tool callback is executed
4. **Payment Settlement**: Payment is settled on-chain
5. **Response**: Tool result is returned with payment transaction reference
```mermaid
sequenceDiagram
participant Client
participant PayflowServer as Payflow MCP Server
participant Facilitator as x402 Facilitator
participant Blockchain as Base Network
participant ToolLogic as Your Tool Logic
Client->>PayflowServer: Call paid tool with payment header
Note over PayflowServer: Step 1: Payment Verification
PayflowServer->>PayflowServer: Decode x402 payment
PayflowServer->>PayflowServer: Generate payment requirements
PayflowServer->>Facilitator: Verify payment against requirements
Facilitator-->>PayflowServer: Payment verification result
alt Payment Invalid
PayflowServer-->>Client: Error: Invalid payment
else Payment Valid
Note over PayflowServer: Step 2: Tool Execution
PayflowServer->>ToolLogic: Execute tool callback with params
ToolLogic-->>PayflowServer: Tool execution result
Note over PayflowServer: Step 3: Payment Settlement
PayflowServer->>Facilitator: Settle payment on-chain
Facilitator->>Blockchain: Submit payment transaction
Blockchain-->>Facilitator: Transaction hash
Facilitator-->>PayflowServer: Settlement response
Note over PayflowServer: Step 4: Response
PayflowServer->>PayflowServer: Add transaction reference to result
PayflowServer-->>Client: Tool result + payment transaction
end
```
## Complete Example
```typescript
import { PayflowMcpServer } from '@chainbound/payflow-sdk';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new PayflowMcpServer({
name: 'weather-server',
version: '1.0.0',
});
// Free tool (standard MCP)
server.tool(
'get_weather_info',
'Get general weather information',
async () => ({
content: [{
type: 'text',
text: 'Weather service available. Use get_weather for specific locations.'
}]
})
);
// Paid tool for detailed weather
server.paidTool(
'get_weather',
'Get detailed weather for a specific location',
{
price: 0.02,
recipient: '0x742d35Cc6634C0532925a3b8D1d3e14C1C3E6FC8' // Your wallet address
},
{
location: z.string().describe('City name or coordinates'),
units: z.enum(['metric', 'imperial']).optional().describe('Temperature units')
},
async ({ location, units = 'metric' }) => {
// Call your weather API
const weather = await weatherAPI.getWeather(location, units);
return {
content: [{
type: 'text',
text: `Weather in ${location}: ${weather.temperature}°${units === 'metric' ? 'C' : 'F'}, ${weather.condition}`
}]
};
}
);
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
```
## Environment Setup
Your MCP server should handle these environment variables:
```bash
CDP_API_KEY_ID=your-api-key-id
CDP_API_KEY_SECRET=your-api-key-secret
```
## Client Usage
Clients need to provide payment headers when calling paid tools. The payment header should be generated using the x402 protocol with your specified price and recipient.
## License
MIT