Open Pizza Ordering Protocol
Version 2026-11-01. OpenAPI 3.1: /openapi.json. MCP: https://openpizza-pizza-mcp.vercel.app/api/mcp.
MCP tools
find_pizzerias, get_menu, resolve_order_text, update_cart, get_quote, place_order, get_order_status, cancel_order, list_recent_orders, reorder. Resources: opop://guide/ordering, opop://pizzerias/{id}/menu, opop://orders/{id}. Prompts: order_pizza, reorder_usual, feed_a_group, track_my_order. stdio: npm run mcp:stdio.
REST /api/v1
| Method | Path | Purpose |
|---|---|---|
| GET | /pizzerias | Find opted-in pizzerias (q, near, radius_km, fulfillment, open_now) |
| GET | /pizzerias/{id} | Details: hours, open_now, capabilities |
| GET | /pizzerias/{id}/menu | Normalized menu (OPMS v1), ETag |
| POST | /pizzerias/{id}/menu/resolve | Free text -> structured lines + ambiguities |
| POST | /carts 路 PATCH /carts/{id} | Batch cart ops; returns per-line issues (If-Match) |
| POST | /carts/{id}/quote | Server-priced quote (the only authoritative price) |
| POST | /orders | Place order. Idempotency-Key required. Held until a human pays |
| GET | /orders 路 /orders/{id} | Status, timeline, tracking |
| POST | /orders/{id}/cancel 路 /reorder | Cancel before the kitchen starts; rebuild a cart |
Auth
Resource server per RFC 9728 (metadata). Scopes: pizza:browse, orders:read, orders:write. Tokens are audience-bound to the MCP URL and never passed to the pizzeria's system. Set PIZZA_MCP_AUTH_ISSUER to enable real JWT verification; without it, Bearer dev_<user> works for local demos.
Errors
RFC 9457 problem+json with code, retryable, path, details, suggestions and ask_user. Codes: UNAUTHENTICATED, INSUFFICIENT_SCOPE, INVALID_CLIENT, FORBIDDEN, NOT_FOUND, VALIDATION_FAILED, CONFLICT, IDEMPOTENCY_CONFLICT, RATE_LIMITED, CAPABILITY_UNSUPPORTED, MODULE_DISABLED, INTERNAL, UPSTREAM_UNAVAILABLE, ITEM_NOT_FOUND, ITEM_UNAVAILABLE, AMBIGUOUS_ITEM, SIZE_REQUIRED, SIZE_NOT_FOUND, SIZE_UNAVAILABLE, OPTION_NOT_FOUND, OPTION_UNAVAILABLE, OPTION_REQUIRED, MODIFIER_LIMIT_EXCEEDED, HALF_NOT_SUPPORTED, PLACEMENT_CONFLICT, QUANTITY_LIMIT_EXCEEDED, INVALID_ADJUSTMENT, FULFILLMENT_UNAVAILABLE, STORE_CLOSED, ORDERING_PAUSED, SCHEDULE_OUT_OF_WINDOW, ADDRESS_REQUIRED, OUT_OF_DELIVERY_ZONE, BELOW_MINIMUM, QUOTE_NOT_FOUND, QUOTE_EXPIRED, QUOTE_INVALID, PRICE_CHANGED, CANCEL_NOT_ALLOWED, INVALID_TRANSITION, PAYMENT_REQUIRED, PAYMENT_FAILED, CONFIRMATION_REQUIRED, SPEND_LIMIT_EXCEEDED, AGENT_ORDERS_DISABLED, AGENT_CAP_REACHED, KITCHEN_BUSY.