DEV Community

Phil Maher
Phil Maher

Posted on

How We Built an MCP Server + x402 Payment System for 217K Vintage Film Clips


Stockfilm is an archive of 217,000+ authentic vintage home movie clips from the 1930s-1980s. Real 8mm and Super 8 film shot by ordinary families, professionally
restored and scanned to 4K. Not AI-generated — every frame is real archival film.

We just shipped two integrations that let AI agents discover and license this footage autonomously:

  1. An MCP server so Claude, GPT, Cursor, and other AI tools can search and browse clips natively
  2. x402 protocol support so agents can pay for and license clips with USDC in a single HTTP request

Here's how we built it and what we learned.


## The Problem

AI agents are increasingly assembling media for creative projects — documentaries, ad campaigns, social content, training datasets. But licensing stock footage still
requires a human clicking through a website, adding clips to a cart, and paying with a credit card.

We wanted to make Stockfilm's archive accessible to AI agents the same way APIs are accessible to code: call an endpoint, get a result.

## Why MCP + x402

We needed two things:

  • Discovery — How does an agent even know Stockfilm exists and what it can do?
  • Payment — How does an agent pay $10 for a clip without a credit card?

MCP (Model Context Protocol) solves discovery. It's a standard that lets AI agents discover and call tools. When you connect an MCP
server to Claude or Cursor, the agent sees your tools and can call them based on the user's request.

x402 solves payment. It uses HTTP status code 402 ("Payment Required") to create a pay-per-request flow. The agent hits an endpoint, gets a 402
with payment instructions, pays USDC on Solana or Base, retries with proof, and gets the resource. No API keys, no accounts, no sign-up.

Together: MCP for discovery, x402 for payment.

## Architecture

Our existing infrastructure is a Rust/Axum API server with:

  • PostgreSQL full-text search across 217K clips
  • Visual similarity search via embeddings
  • Solana USDC/SOL and Lightning BTC payment verification
  • HMAC-SHA256 signed requests for the full licensing workflow

The new MCP and x402 layers sit alongside the existing API — they don't replace it, they provide additional access paths.

  Agent (Claude, Cursor, etc.)
    │
    ├── MCP (Streamable HTTP) ──→ api.stockfilm.com/mcp
    │                                    │
    │                              6 tools (search, details,
    │                              similar, rough-cut, rights,
    │                              license)
    │
    └── x402 (HTTP 402) ────────→ api.stockfilm.com/x402/clip/{id}/license
                                         │
                                   402 → pay USDC → 200 + download URL
Enter fullscreen mode Exit fullscreen mode

## The MCP Server (Rust + rmcp)

We used the official Rust MCP SDK rmcp (v1.2) with the Streamable HTTP transport. The server is embedded directly
in our existing Axum application — no separate service.

### 6 Tools

| Tool | Cost | What It Does |
|------|------|-------------|
| search_vintage_footage | Free | Text search with year/location filters |
| get_clip_details | Free | Full metadata, thumbnail, pricing |
| find_similar_footage | Free | Visual similarity by clip ID |
| build_rough_cut | Free | Auto-assemble a timed video timeline |
| check_clip_rights | Free | Usage eligibility (commercial, editorial, etc.) |
| license_clip | $10 USDC | Returns x402 endpoint for payment |

Each tool delegates to existing internal APIs. The MCP server is a thin translation layer, not a separate data store.

### Key Implementation Details

Tool definitions use rmcp's proc macros with full annotations for quality scoring:

  #[tool(
      description = "Search Stockfilm's archive of 217,000+ authentic vintage clips...",
      annotations(
          title = "Search Vintage Footage",
          read_only_hint = true,
          destructive_hint = false,
          idempotent_hint = true,
          open_world_hint = true
      )
  )]
  async fn search_vintage_footage(
      &self,
      Parameters(req): Parameters<SearchRequest>,
  ) -> String {
      // calls internal search API
  }
Enter fullscreen mode Exit fullscreen mode

The server metadata includes title, description, icon, and website URL so directories like Smithery and Glama can display rich listings:

  impl ServerHandler for StockfilmMcp {
      fn get_info(&self) -> ServerInfo {
          ServerInfo::new(
              ServerCapabilities::builder()
                  .enable_tools()
                  .enable_prompts()
                  .enable_resources()
                  .build(),
          )
          .with_server_info(
              Implementation::new("stockfilm", "1.0.0")
                  .with_title("Stockfilm — Authentic Vintage Footage")
                  .with_description("Search and license 217,000+ clips...")
                  .with_icons(vec![Icon::new("https://stockfilm.com/stockfilm-logo.png")])
                  .with_website_url("https://stockfilm.com"),
          )
      }
  }
Enter fullscreen mode Exit fullscreen mode

### Connecting

  # Claude Code
  claude mcp add --transport http stockfilm https://api.stockfilm.com/mcp

  # Claude Desktop
  # Add to claude_desktop_config.json:
  {
    "mcpServers": {
      "stockfilm": {
        "command": "npx",
        "args": ["-y", "mcp-remote", "https://api.stockfilm.com/mcp"]
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

## The x402 Integration

x402 V2 uses three HTTP headers. All contain base64-encoded JSON:

| Header | Direction | Purpose |
|--------|-----------|---------|
| PAYMENT-REQUIRED | Server → Client | Payment options (price, networks, recipient addresses) |
| PAYMENT-SIGNATURE | Client → Server | Signed payment authorization |
| PAYMENT-RESPONSE | Server → Client | Settlement result (tx hash) |

### The Flow

  1. Agent calls GET /x402/clip/{id}/license
  2. Server returns 402 with PAYMENT-REQUIRED header containing payment options for Solana USDC and Base USDC
  3. Agent's x402 client signs a payment authorization
  4. Agent retries with PAYMENT-SIGNATURE header
  5. Server sends proof to a facilitator for verification and settlement
  6. Server returns 200 with license details and download URL

### Free Endpoints

Search, clip details, and rights checks are completely free — no payment, no auth, no API keys:

  # Search
  curl "https://api.stockfilm.com/x402/search?q=christmas+morning+1960s&limit=5"

  # Clip details
  curl "https://api.stockfilm.com/x402/clip/120818702"

  # Rights check
  curl "https://api.stockfilm.com/x402/clip/120818702/rights?intended_use=commercial"
Enter fullscreen mode Exit fullscreen mode

The money is in licensing, not search queries. Free search maximizes the funnel.

### Payment Verification

We use an external facilitator for payment verification and settlement rather than running our own Solana RPC infrastructure. The facilitator handles the on-chain
verification so we don't need expensive RPC subscriptions.

We support two networks:

  • Solana mainnet — USDC to FERR1XDCsvLRzU8U29baMY4XvZ8kwk52tUjqy3SaDRtQ
  • Base mainnet — USDC to 0x4AeeD280b6006Aa354e09427AF4F49bD09f9447B

The agent's x402 client picks whichever chain it has funds on.

## What We Learned

1. MCP metadata matters. Directories like Smithery score your server on tool descriptions, parameter descriptions, annotations, icons, and capabilities. Ship all
of it from day one.

2. x402 is simpler than building your own payment flow. We already had a 6-step licensing pipeline (search → rights → quote → payment intent → execute → download).
x402 collapses this to 2 steps (search → pay+license). The protocol handles the complexity.

3. Free search is the right call. Every clip search is a potential license. Gating search behind payment or auth reduces the funnel to zero.

4. Embed, don't separate. The MCP server and x402 endpoints run inside our existing Axum process. No new containers, no new deployments, no new databases. Just new
routes.

5. The rmcp Rust SDK is production-ready. We had working MCP tools in under an hour. The #[tool] proc macros, Parameters<T> wrapper, and
StreamableHttpService work exactly as documented.

## The Numbers

  • 217,000+ clips in the archive
  • 6 MCP tools
  • 4 x402 endpoints
  • $10 per clip license (144p format)
  • $0/month additional infrastructure cost
  • 2 networks — Solana + Base USDC

## Try It

  # Connect the MCP server to Claude
  claude mcp add --transport http stockfilm https://api.stockfilm.com/mcp

  # Or search directly
  curl "https://api.stockfilm.com/x402/search?q=1960s+family+vacation&limit=5"
Enter fullscreen mode Exit fullscreen mode

Top comments (0)