A POST flows โ โโฆ through the group-sorted cascade into the route; an OPTIONS preflight short-circuits at โ . Companion to middleware-chain.html.
Resolved order (POST)
โข Chain is the 1st handler; cascade is group-sorted: cors โ parseBody โ middleware
โข Each calls next(); on cascade end, toExpressMiddleware calls Express next() โ router
โข /mcp route (mounted by installMcpHttp) is the destination behind the chain
โข โค the route's own express.json() no-ops (req._body set in โก)
Short-circuit exits
โข OPTIONS preflight โ cors ends 204 at โ , no next() (cheapest exit)
โข rate limit exceeded โ 429 at โข, before the router
โข auth guard rejects โ 401 at โฃ, transport never built
โข A non-preflight POST never short-circuits at โ โ cors just stamps headers
Layering
โข Edge concerns (cors, body, rate-limit) live in the chain โ uniform across all routes
โข Identity (โฃ req.auth/scopes) lives on the /mcp route โ session/scope-aware
โข Different layers, no collision: that's why the chain-first + per-session changes compose
โข bodyParser:false โ โก skipped, โค becomes the real parser; /mcp still works