Skip to content
LogoLogo

Discovery

Let clients automatically discover your API's pricing

Overview

MPP's discovery system lets clients and agents learn what your endpoints cost before making a request. You serve a standard OpenAPI 3.1 document at /openapi.json with x-payment-info extensions that advertise one or more payment offers for each paid operation. Registries aggregate these documents so agents can find paid APIs automatically, and provide value-added services like reputation, search, and analytics.

Registries

Registries aggregate discovery documents from multiple services, making it easy for clients and agents to find paid APIs.

RegistryDescriptionHow to add
MPPScanPublic registry of MPP-enabled services with search and analyticsManually register in one click
MPP Services directoryCurated list of live services on mpp.devSubmit a PR to add your service

Agents can query the curated services directory over MCP at https://mpp.dev/mcp/services. The server is read-only and exposes tools to list services, rank services for an agent task, inspect endpoint offers, get usage recipes, look up services by payment recipient, inspect available filters, and fetch advisory OpenAPI summaries.

Services MCP

The services MCP server is the agent-facing discovery surface for the curated MPP directory:

https://mpp.dev/mcp/services

Use it when an agent needs to:

  • rank paid APIs by task, category, integration, or payment method
  • turn a selected service into a usage recipe with endpoint candidates
  • compare endpoint-level payment offers before constructing a request
  • identify which services publish offers for a payment recipient from a 402 Challenge
  • inspect catalog facets before narrowing a search
  • fetch a live OpenAPI summary or registry-derived endpoint view
{
  "mcpServers": {
    "mpp-services": {
      "url": "https://mpp.dev/mcp/services"
    }
  }
}

The MCP server is advisory and read-only. After discovery, clients call the target service directly and treat the runtime 402 Challenge as authoritative.

For agent setup, MCP Inspector smoke tests, example prompts, and recipes, see Discover MPP services on Tempo docs.

Quick start

The mppx SDK generates discovery documents from your route configuration. Add discovery() to your server and it serves /openapi.json automatically.

server.ts
import { Hono } from 'hono'
import { Mppx, discovery } from 'mppx/hono'
import { tempo } from 'mppx/server'
 
const app = new Hono()
 
const mppx = Mppx.create({
  methods: [
    tempo.charge({
      currency: '0x20c0000000000000000000000000000000000000',
      recipient: '0x...',
      testnet: true,
    }),
  ],
  secretKey: process.env.MPP_SECRET_KEY,
})
 
app.get('/v1/fortune', mppx.charge({ amount: '0.01' }), (c) => c.json({ fortune: 'You will be rich' }))
 
discovery(app, mppx, {
  auto: true,
  info: { title: 'Fortune API', version: '1.0.0' },
})

This generates a GET /openapi.json endpoint with canonical x-payment-info.offers[] entries on each paid route.

Express

server.ts
import express from 'express'
import { Mppx, discovery } from 'mppx/express'
import { tempo } from 'mppx/server'
 
const app = express()
 
const mppx = Mppx.create({
  methods: [
    tempo.charge({
      currency: '0x20c0000000000000000000000000000000000000',
      recipient: '0x...',
      testnet: true,
    }),
  ],
  secretKey: process.env.MPP_SECRET_KEY,
})
 
const pay = mppx.charge({ amount: '0.01' })
app.get('/v1/fortune', pay, (req, res) => res.json({ fortune: 'You will be rich' }))
 
discovery(app, mppx, {
  info: { title: 'Fortune API', version: '1.0.0' },
  routes: [{ handler: pay, method: 'get', path: '/v1/fortune' }],
})

Next.js

In Next.js, discovery() returns a route handler you export from an API route.

app/openapi.json/route.ts
import { discovery } from 'mppx/nextjs'
import { mppx, pay } from '../fortune/route'
 
export const GET = discovery(mppx, {
  info: { title: 'Fortune API', version: '1.0.0' },
  routes: [{ handler: pay, method: 'get', path: '/api/fortune' }],
})

How it works

Your server exposes a GET /openapi.json endpoint that returns an OpenAPI document. Paid operations include an x-payment-info extension with one or more payment offers, and the document root can include x-service-info for service-level metadata.

/openapi.json
{
  "openapi": "3.1.0",
  "info": { "title": "My API", "version": "1.0.0" },
  "x-service-info": {
    "categories": ["ai"],
    "docs": {
      "homepage": "https://example.com",
      "apiReference": "https://example.com/docs",
      "llms": "/llms.txt"
    }
  },
  "paths": {
    "/v1/generate": {
      "post": {
        "x-payment-info": {
          "offers": [
            {
              "amount": "1000000",
              "currency": "0x20c0000000000000000000000000000000000001",
              "description": "Generate text with Tempo",
              "intent": "charge",
              "method": "tempo"
            },
            {
              "amount": "100",
              "currency": "usd",
              "description": "Generate text with Stripe",
              "intent": "charge",
              "method": "stripe"
            }
          ]
        },
        "responses": {
          "200": { "description": "Successful response" },
          "402": { "description": "Payment Required" }
        }
      }
    },
    "/v1/models": {
      "get": {
        "responses": {
          "200": { "description": "Successful response" }
        }
      }
    }
  }
}

x-payment-info

Add this extension to any operation that requires payment. Prefer the canonical multi-offer shape:

FieldTypeDescription
offersOffer[]Ordered list of payment offers the client can choose from

offers[]

FieldTypeDescription
amountstring | nullPayment amount in base units
currencystringCurrency code or token address
descriptionstringHuman-readable description of the charge
intentstringPayment intent (charge or session)
methodstringPayment method identifier (tempo, stripe)

x-service-info

Optional root-level metadata about the service:

FieldTypeDescription
categoriesstring[]Free-form service categories (for example, ai, payments)
docs.homepagestringLink to the service homepage
docs.apiReferencestringLink to API documentation
docs.llmsstringLink to an llms.txt file for AI consumption

Build manually

You can author a discovery document by hand following the discovery specification. The document is a standard OpenAPI 3.1 file with two extensions:

Create the OpenAPI skeleton

Start with a standard OpenAPI 3.1 document:

openapi.json
{
  "openapi": "3.1.0",
  "info": {
    "title": "My API",
    "version": "1.0.0"
  },
  "paths": {}
}

Add x-payment-info to paid operations

For each endpoint that requires payment, add the x-payment-info extension with an offers array. Add more objects to offers[] when the client can choose between alternative payment methods or currencies. Amounts are in base units (for example, 1000000 for $1.00 with 6 decimals).

openapi.json
{
  "paths": {
    "/v1/generate": {
      "post": {
        "summary": "Generate text",
        "x-payment-info": {
          "offers": [
            {
              "amount": "1000000",
              "currency": "0x20c0000000000000000000000000000000000001",
              "intent": "charge",
              "method": "tempo"
            }
          ]
        },
        "responses": {
          "200": { "description": "Successful response" },
          "402": { "description": "Payment Required" }
        }
      }
    }
  }
}

Add x-service-info (optional)

Add service-level metadata to the document root:

openapi.json
{
  "x-service-info": {
    "categories": ["ai", "text-generation"],
    "docs": {
      "homepage": "https://example.com",
      "apiReference": "https://example.com/docs/api",
      "llms": "https://example.com/llms.txt"
    }
  }
}

Serve at /openapi.json

Serve the document at GET /openapi.json with appropriate caching:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=300

CLI

Generate a static discovery document from a config module:

terminal
$ npx mppx discover generate ./discovery.config.ts

Validate an existing discovery document from a file or URL:

terminal
$ npx mppx discover validate https://example.com/openapi.json

Validation

Common validation issues:

IssueSeverityDescription
Missing 402 responseErrorOperations with x-payment-info must include a 402 response
Invalid amount formatErrorEach offers[].amount value must be a non-negative integer string
Missing requestBodyWarningPOST/PUT/PATCH operations without a requestBody definition
Invalid URI in docsErrordocs links must be valid URIs or absolute paths

Specification