- a person, paying on a checkout page you already run
- the agent itself, paying for a tool call out of a wallet its user funded
- an advertiser, paying for a labeled slot in your tool results
Hand Off to Your Own Checkout
The simplest option, and what theecom template ships: send the shopper to a page you already run. The navigation has to go through the host with useOpenExternal.
views/carousel/detail/index.tsx
redirectDomains so the host skips its safe-link confirmation on the way out.
server.ts
Charge the Agent
An agent can also pay for a tool call itself, with no person present, under the Machine Payments Protocol. An unpaid call comes back as a payment challenge, the agent fetches a credential from its user’s wallet, and the retry returns the real result with a receipt attached.mcpMiddleware rather than inside the tool handler. The challenge has to reach the client as a JSON-RPC error, carrying the amount and the payment method the agent needs to pay: an exception thrown inside a handler is flattened into an isError tool result instead, which leaves the agent with a message and nothing to pay against.
server.ts
MPP_SECRET_KEY signs the challenges, so it has to be at least 32 bytes (openssl rand -base64 32), and setting realm avoids a fallback warning at boot.
mppx needs the v1 @modelcontextprotocol/sdk to build the payment error and declares it as an optional peer, so install it yourself alongside Skybridge’s v2 packages.
Stripe documents a different shape for the same protocol, where a tool returns a payment link and a separate HTTP endpoint handles the exchange. That endpoint also serves human browsers, so it covers both audiences with one URL, at the cost of a custom route Alpic Cloud does not serve.
Carry Sponsored Slots
Instead of charging anyone for your app, you can let an advertiser pay for a slot in it. Lulu is an ad network for MCP servers and agent tools: it sells the demand, matches an advertiser to each tool call, and pays publishers 70% of the conversions it bills, with a $100 payout minimum. Its SDK attaches one labeled sponsored field to your tool results, through a Skybridge adapter built onmcpMiddleware.
server.ts
LULU_ADS_PUBLISHER_ID and LULU_ADS_API_KEY. Every tool registered on the server then carries a field like this one:
_meta["ads.getlulu.dev/sponsored"] and never on structuredContent. Protocol middleware sees the result but not the tool’s outputSchema, and an undeclared field in structuredContent would fail validation.
Charging some users and showing ads to the rest needs the client directly, because the adapter above takes no per-request decision. Build a LuluAds yourself, and let the enabled flag read whatever your auth already knows about the caller.
server.ts
withLuluAdsSkybridge, not alongside it: the adapter already decorates every tool, so a tool doing its own slot would get two.
Lulu also ships result widgets, four templates that render your own tool output with the sponsored strip built in, for hosts that support rendered widgets.
Go Further
Register Tools
Define what humans and agents can do
Configure CSP
Let your views reach the domains they need
Build an Ecommerce App
Scaffold a catalog and carousel UI