Skip to content
LogoLogo

Proxy

Paid API proxy

Gates upstream API services behind MPP 402 payments. The proxy handles routing, Credential injection, and payment verification—you configure which endpoints require payment and which are free passthrough.

Install

Usage

Import Proxy and a service preset from mppx/proxy, then create an Mppx server instance from mppx/server to define payment intents.

server.ts
import { ,  } from 'mppx/proxy'
import { ,  } from 'mppx/server'
 
const  = .({ : [.()] })
 
const  = .({
  : [
    ({
      : ..!,
      : {
        'POST /v1/chat/completions': .({ : '0.05' }),
        'GET /v1/models': true,
      },
    }),
  ],
})
 
// Bun / Deno
export default { : . }
 
// Node.js
import {  } from 'node:http'
(.).(3000)

The proxy returns two handlers:

  • fetch — Fetch API handler. Works with Bun, Deno, Next.js, Hono, Elysia, and SvelteKit.
  • listener — Node.js request listener. Works with Express, Fastify, and http.createServer.

Route values use the current EndpointMap shape:

  • Use an mppx intent handler like mppx.charge({ amount: '0.05' }) for paid routes.
  • Use true for free passthrough routes.
  • Use a method-specific handler, such as mppx.tempo.session({ amount, unitType }), for session-priced routes.

Multiple services

Pass multiple services to gate several upstream APIs behind a single proxy.

server.ts
import { , , ,  } from 'mppx/proxy'
import { ,  } from 'mppx/server'
 
const  = .({ : [.()] })
 
const  = .({
  : 'Multi-service paid API proxy',
  : 'My Proxy',
  : [
    ({
      : ..!,
      : {
        'POST /v1/chat/completions': .({ : '0.05' }),
      },
    }),
    ({
      : ..!,
      : {
        'POST /v1/messages': .({ : '0.03' }),
      },
    }),
    ({
      : ..!,
      : {
        'POST /v1/charges': .({ : '1' }),
        'GET /v1/customers/:id': true,
      },
    }),
  ],
})

Each service is mounted at /{serviceId}/—for example, requests to /openai/v1/chat/completions route to https://api.openai.com/v1/chat/completions.

Built-in services

openai

Creates an OpenAI service definition. Injects Authorization: Bearer header for upstream authentication.

server.ts
import { openai } from 'mppx/proxy'
 
openai({
  apiKey: 'sk-...',
  routes: {
    'POST /v1/chat/completions': mppx.charge({ amount: '0.05' }),
    'POST /v1/embeddings': mppx.charge({ amount: '0.01' }),
    'POST /v1/images/generations': mppx.charge({ amount: '0.10' }),
    'GET /v1/models': true,
  },
})
ParameterTypeDescription
apiKeystringOpenAI API key. Used as Authorization: Bearer header.
baseUrl (optional)stringBase URL override. Defaults to 'https://api.openai.com'.
routesEndpointMapRoute definitions for OpenAI endpoints.

Typed routes: POST /v1/chat/completions, POST /v1/completions, POST /v1/embeddings, POST /v1/images/generations, POST /v1/images/edits, POST /v1/images/variations, POST /v1/audio/transcriptions, POST /v1/audio/translations

anthropic

Creates an Anthropic service definition. Injects x-api-key header for upstream authentication.

server.ts
import { anthropic } from 'mppx/proxy'
 
anthropic({
  apiKey: 'sk-ant-...',
  routes: {
    'POST /v1/messages': mppx.charge({ amount: '0.03' }),
    'POST /v1/complete': mppx.charge({ amount: '0.02' }),
  },
})
ParameterTypeDescription
apiKeystringAnthropic API key. Used as x-api-key header.
baseUrl (optional)stringBase URL override. Defaults to 'https://api.anthropic.com'.
routesEndpointMapRoute definitions for Anthropic endpoints.

Typed routes: POST /v1/messages, POST /v1/messages/batches, GET /v1/messages/batches, GET /v1/messages/batches/:batchId, POST /v1/complete

stripe

Creates a Stripe service definition. Injects Authorization: Basic header (API key as username) for upstream authentication. This is a proxy service for the Stripe API—not a payment method.

server.ts
import { stripe } from 'mppx/proxy'
 
stripe({
  apiKey: 'sk-...',
  routes: {
    'POST /v1/charges': mppx.charge({ amount: '1' }),
    'GET /v1/customers/:id': true,
  },
})
ParameterTypeDescription
apiKeystringStripe API key. Used as Basic auth username.
baseUrl (optional)stringBase URL override. Defaults to 'https://api.stripe.com'.
routesEndpointMapRoute definitions for Stripe endpoints.

Typed routes: POST /v1/charges, POST /v1/customers, GET /v1/customers/:id, POST /v1/payment_intents, GET /v1/payment_intents/:id, POST /v1/subscriptions, GET /v1/subscriptions/:id, POST /v1/invoices, GET /v1/invoices/:id

Custom services

Use Service.from (or its alias custom) to define a service for any upstream API.

With bearer shorthand

server.ts
import { ,  } from 'mppx/proxy'
import { ,  } from 'mppx/server'
 
const  = .({ : [.()] })
 
const  = .({
  : [
    .('my-api', {
      : 'https://api.example.com',
      : ..!,
      : 'Example upstream API',
      : 'My API',
      : {
        'POST /v1/generate': .({ : '0.01' }),
        'GET /v1/status': true,
      },
    }),
  ],
})

With headers shorthand

server.ts
import { Service } from 'mppx/proxy'
 
Service.from('custom-api', {
  baseUrl: 'https://api.example.com',
  headers: {
    'X-API-Key': process.env.CUSTOM_API_KEY!,
    'X-Org-Id': 'org-123',
  },
  routes: {
    'POST /v1/query': mppx.charge({ amount: '0.02' }),
  },
})

With rewriteRequest

For full control over the upstream request, use rewriteRequest. The context includes per-endpoint options set via the options field on an endpoint definition.

server.ts
import { Service } from 'mppx/proxy'
 
Service.from('advanced-api', {
  baseUrl: 'https://api.example.com',
  rewriteRequest(request, ctx) {
    request.headers.set('Authorization', `Token ${process.env.API_TOKEN}`)
    return request
  },
  routes: {
    'POST /v1/generate': mppx.charge({ amount: '0.05' }),
  },
})

Discovery endpoints

The proxy automatically serves discovery endpoints that describe available services and their routes. Coding agents and CLI tools use these endpoints to understand what the proxy offers.

EndpointContent-TypeDescription
GET /discoverapplication/json or text/plainLists all services. Returns JSON by default, markdown for AI user agents and terminal clients.
GET /discover/{id}application/json or text/markdownDetails for a single service, including routes and pricing.
GET /discover/{id}.mdtext/markdownMarkdown description of a single service.
GET /discover/allapplication/json or text/markdownAll services with full route details.
GET /discover/all.mdtext/markdownMarkdown listing of all services and routes.
GET /llms.txttext/plainllms.txt-formatted overview of the proxy and its services.
GET /discover.mdtext/plainAlias for /llms.txt.

The proxy returns markdown instead of JSON when the request comes from a known AI user agent (for example, ChatGPT-User, ClaudeBot, PerplexityBot) or a terminal client (for example, curl, HTTPie, mppx).

Parameters

Proxy.create config

basePath (optional)

  • Type: string

Base path prefix to strip before routing (for example, '/api/proxy'). Use when the proxy is mounted at a sub-path.

description (optional)

  • Type: string

Short description of the proxy shown in llms.txt and discovery endpoints.

fetch (optional)

  • Type: typeof globalThis.fetch

Custom fetch implementation. Defaults to globalThis.fetch.

services

  • Type: Service[]

Array of service definitions to proxy. Each service is mounted at /{serviceId}/.

title (optional)

  • Type: string

Human-readable title for the proxy shown in llms.txt and discovery endpoints.

Service type reference

Service.from config

baseUrl

  • Type: string

Base URL of the upstream service (for example, 'https://api.openai.com').

bearer (optional)

  • Type: string

Shorthand: injects Authorization: Bearer {token} header on upstream requests.

description (optional)

  • Type: string

Short description of the service, shown in discovery endpoints.

docsLlmsUrl (optional)

  • Type: string | ((options: { route?: string }) => string | undefined)

Documentation URL for the service. Provide a string for a static URL, or a function that receives an optional route pattern and returns a per-endpoint docs URL.

headers (optional)

  • Type: Record<string, string>

Shorthand: injects custom headers on upstream requests.

mutate (optional)

  • Type: (req: Request) => Request | Promise<Request>

Shorthand: full request mutation function. Takes priority over bearer and headers.

rewriteRequest (optional)

  • Type: (req: Request, ctx: Context) => Request | Promise<Request>

Hook to modify the upstream request before sending. Receives per-endpoint options via ctx.

routes

  • Type: EndpointMap

Map of "METHOD /pattern" keys to endpoint definitions. Each value is one of:

  • IntentHandler — Payment required. The handler issues a 402 Challenge or verifies payment.
  • { pay: IntentHandler, options: EndpointOptions } — Payment required with per-endpoint config overrides passed to rewriteRequest via ctx.
  • true — Free passthrough. No payment required; rewriteRequest is still applied.

title (optional)

  • Type: string

Human-readable title for the service (for example, 'OpenAI').