Define once, serve everywhere
One defineCommerce manifest, served over commerce.json, a plain HTTP API, MCP, ACP, and UCP — from a single serveCommerce() call. Read-only by default, no keys required.
serveCommerce(manifest).listen(3000)
Define your catalog once. Serve it over commerce.json, HTTP, MCP, ACP, and UCP from a single call. Add checkout through Stripe or a UCP PSP adapter. Use x402 for paid API requests that return HTTP 402.
/.well-known/commerce.jsonmanifest/commerceHTTP/mcpMCP/acp/feedACP/.well-known/ucpUCP/.well-known/commerce.jsonmanifest/commerceHTTP/mcpMCP/acp/feedACP/.well-known/ucpUCP01$ steelyard-agent "buy 1 espresso, email me@local"02→ POST /mcp · tools/call list_offers q="espresso"03200 found 3 · picking espresso $4.5004→ GET /.well-known/ucp05200 ucp · checkout · stripe06→ POST /api/checkout {offer:"espresso"}07201 chk_xy91 · total $4.7708→ IPC proposeIntent · caller_token09200 allow ic_test_9df2 · sha256:0f9c… · card scoped $4.7710→ POST /api/checkout/chk_xy91/complete11200 paid pi_test_abc123 · rcpt_xyz789
01merchant listening on http://localhost:300002↳ awaiting requests…03← POST /mcp · tools/call list_offers04200 3 offers returned05← GET /.well-known/ucp · 127.0.0.1 · 20006← POST /api/checkout {offer:espresso}07← POST /api/checkout/chk_xy91/complete · vc_******08↳ stripePsp.capture → stripe.paymentIntents.confirm09200 pi_test_abc123 paid $4.77
Define a manifest, call serveCommerce, and your catalog is live over five read surfaces at once. Read-only by default — no processor, no keys. Or run npx steelyard init inside an existing Next.js app and the five generated route files land in your project.
$ npx steelyard init ✔ Detected Next.js 15 (App Router · TypeScript · pnpm) ✔ Imported 12 prices from Stripe ✔ app/.well-known/commerce.json/route.ts ✔ app/mcp/route.ts ✔ app/acp/feed/route.ts ✔ app/.well-known/ucp/route.ts ✔ app/api/catalog/[...path]/route.ts ✔ commerce.ts · /steelyard inspector
import { defineCommerce, serveCommerce } from "steelyard" const manifest = defineCommerce({ identity: { name: "My Shop", domain: "shop.example", currencies: ["USD"] }, offers: [ { id: "tee", title: "T-Shirt", availability: "in_stock", pricing: [{ kind: "one_time", amount: 2500, currency: "USD" }] }, ], }) serveCommerce(manifest).listen(3000)
$ curl localhost:3000/.well-known/commerce.json $ curl localhost:3000/mcp # MCP $ curl localhost:3000/acp/feed # ACP
One defineCommerce manifest, served over commerce.json, a plain HTTP API, MCP, ACP, and UCP — from a single serveCommerce() call. Read-only by default, no keys required.
serveCommerce(manifest).listen(3000)
npx steelyard init detects your framework, language, and package manager, optionally imports your Stripe catalog, writes five route files plus a dev inspector at /steelyard, and installs the public steelyard package.
npx steelyard init
UCP checkout is adapter-neutral: the merchant advertises accepted instruments, and the buyer matches by instrument type. ACP checkout remains intentionally direct Stripe SPT-only.
createCheckoutServer(manifest, { psp: stripePsp(...) })For pay-per-request APIs, x402Fetch lets a Wallet satisfy HTTP 402 challenges. Policy runs before PAYMENT-SIGNATURE, and x402Paywall delegates verify and settle to a facilitator you choose.
x402Fetch(wallet, { maxAmount: { amount: "0.10", currency: "USDC" } })steelyard/psp is a thin, additive-only contract plus a framework-agnostic conformance kit. Ship a steelyard-psp-* adapter from your own repo and self-certify it.
runPspConformance(myAdapter)
Agents ask a local engine for permission before a payment mandate exists. YAML policy, approval flow, reservation ledger, and audit log run in a separate process; rail keys stay out of the LLM runtime.
steelyard policy run --policy ~/.steelyard/policy.yaml
AP2 mandates (SD-JWT+KB) and RFC 9421 HTTP Message Signatures, opt-in through UCP capability negotiation, isolated in steelyard/ucp-signing. Off by default; rigorous when on.
dev.ucp.shopping.ap2_mandate
The current verify report shows 238 passing conformance cases across protocol, lifecycle, security, compatibility, PSP, and adapter-neutral checkout suites.
pnpm verify · 238 passed, 0 failed
The same catalog answers an MCP tool call, an ACP feed reader, a UCP catalog request, and a plain curl. One source of truth, rendered for each protocol.
/.well-known/commerce.jsonStatic commerce manifest/commerce/productsPlain HTTP read API/mcpModel Context Protocol server/acp/feedAgentic Commerce Protocol feed/.well-known/ucpUniversal Commerce Protocol discovery + catalogTwo public diagnostic tools use Steelyard's own SDK validators: an ACP schema validator and a UCP validator for discovery/profile JSON.
steelyardThe front door. defineCommerce, serveCommerce, the protocol handlers, Wallet, PSP adapters — one install, one import.
↗steelyard/nextNext.js adapter. App Router and Pages Router handlers, the createCommerceRoutes factory, and the dev inspector page template that steelyard init writes.
↗steelyard/cliThe steelyard command. init scaffolds five route files into a Next.js app; enable checkout verifies your Stripe key and probes the agentic-payments capability.
↗steelyard/coreManifest schema, validation, canonical hashing, and the shared payment-contract types.
↗steelyard/protocol/*MCP, ACP, UCP, commerce.json, and the plain HTTP read API, all from one manifest.
↗steelyard/buyerWallet facade, encrypted vault, signed receipts, and the explore-and-buy client.
↗steelyard/x402Paid HTTP resources: x402Fetch, x402Payments, x402Paywall, exactUsdc, and facilitator client boundaries.
↗steelyard/policyBuyer-side permission engine: YAML rules, approvals, reservation ledger, local IPC, and audit chain.
↗steelyard/policy-rail-cardStripe Issuing adapter that mints constrained virtual cards and normalizes settlement webhooks.
↗steelyard/merchantCheckout server, PSP adapters, and mandate verification for ACP and UCP.
↗steelyard/pspThe public PSP adapter contract plus a conformance kit. Depend on this to ship an adapter.
↗steelyard/stripe/buyerFirst-party Stripe Shared Payment Token issuer for the wallet.
↗steelyard/ucp-signingAP2 mandates and RFC 9421 signatures. Optional; loaded only when negotiated.
↗