# x402 Monetization

> An MCP server with x402 payment middleware for USDC micropayments

[Source repository](https://github.com/xmcp-dev/templates/tree/main/x402)

Monetize MCP tools with x402 using USDC micropayments on Base.

## Features

- x402 payment middleware for per-tool pricing
- Free and paid tools in the same server
- Custom price overrides per tool
- USDC payments on Base (Sepolia for testing, mainnet for production)
- Example tools: `greet` (paid, $0.01), `hash-string` (paid, $0.05), `random-number` (free)

## Getting Started

### Prerequisites

You need a wallet address to receive USDC payments.

### 1. Create the project

```bash
npx create-xmcp-app --example x402
```

### 2. Environment setup

```bash
cp .env.example .env
```

Edit `.env` with your wallet address:

```bash
X402_WALLET=0xYOUR_WALLET_ADDRESS

# Optional: custom facilitator URL
# X402_FACILITATOR=https://x402.org/facilitator
```

### 3. Install & run

```bash
pnpm install
pnpm dev
```

## How It Works

The middleware is configured in `src/middleware.ts` with default pricing:

- **Default price:** `0.01` USDC per tool call
- **Currency:** USDC
- **Network:** `base-sepolia` (switch to `base` for production)
- **Facilitator:** `https://x402.org/facilitator`

### Making Tools Paid

Wrap tools with `paid()` from `@xmcp-dev/x402`:

```typescript
import { paid } from "@xmcp-dev/x402";

// Uses middleware default price ($0.01)
export default paid(async function greet({ name }) {
  return `Hello, ${name}!`;
});

// Custom price override ($0.05)
export default paid(
  { price: 0.05 },
  async function hashString({ input }) {
    const encoder = new TextEncoder();
    const data = encoder.encode(input);
    const hashBuffer = await crypto.subtle.digest("SHA-256", data);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
  }
);
```

Tools without the `paid()` wrapper are free.

## Deploy

```bash
pnpm build
node dist/http.js
```

For production, update your middleware to use `base` instead of `base-sepolia`.

## Learn More

- [xmcp Documentation](https://xmcp.dev/docs)
- [x402 Integration Guide](https://xmcp.dev/docs/integrations/x402)
