The HTTP side of the deck: the two routes under /deck.
POST /deck/ticket- with the deck bearer token, creates a session (no body) or attaches to one ({"session_id": "<uuid>"}: running, or stopped with a stored history that is resumed) and answers{"ticket", "session_id", "expires_in_ms"}. The ticket is single use and short lived, so the token never travels in a URL.GET /deck/socket?ticket=...- redeems the ticket and upgrades to a WebSocket served byMead.Deck.Socket.
Each check runs only if the previous ones passed: the route (404, or 405 with allow), the
bearer token on the ticket route (401, checked in constant time before the body is read), the
Origin header (403, the same rule and setting as MCP), then the request itself. Refusals are
{"error": "<reason>"} and never repeat a header, a ticket or a body. No cookies and no CORS
headers are set.
Options
:configuration- theMead.Deck.Configuration(required).:allowed_origins- exactOriginvalues accepted besides loopback; defaults to[].:session_options- options for the session a ticket creates or resumes (:handler,:turn_timeout); defaults to the router as handler.:storage_directory- where the event logs live; defaults to the session storage directory.:tickets- the ticket table; defaults toMead.Deck.Tickets.