[{"data":1,"prerenderedAt":3343},["ShallowReactive",2],{"navigation_docs":3,"-docs-capabilities-mcp":493,"-docs-capabilities-mcp-surround":3338},[4,46,135,218,257,292,355,377,420],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":45},"Getting Started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"What is Heximon?","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F01.getting-started\u002F02.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F01.getting-started\u002F03.quick-start","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Core Concepts","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","docs\u002F01.getting-started\u002F04.core-concepts","i-lucide-shapes",{"title":31,"path":32,"stem":33,"icon":34},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F01.getting-started\u002F05.examples","i-lucide-library",{"title":36,"path":37,"stem":38,"icon":39},"Where Next?","\u002Fdocs\u002Fgetting-started\u002Fwhere-next","docs\u002F01.getting-started\u002F06.where-next","i-lucide-signpost",{"title":41,"path":42,"stem":43,"icon":44},"Troubleshooting","\u002Fdocs\u002Fgetting-started\u002Ftroubleshooting","docs\u002F01.getting-started\u002F07.troubleshooting","i-lucide-life-buoy",false,{"title":47,"icon":48,"path":49,"stem":50,"children":51,"page":45},"Essentials","i-lucide-boxes","\u002Fdocs\u002Fessentials","docs\u002F02.essentials",[52,56,61,66,71,76,81,86,91,96,101,105,110,115,120,125,130],{"title":53,"path":54,"stem":55,"icon":48},"Modules & DI","\u002Fdocs\u002Fessentials\u002Fmodules-and-di","docs\u002F02.essentials\u002F01.modules-and-di",{"title":57,"path":58,"stem":59,"icon":60},"Controllers","\u002Fdocs\u002Fessentials\u002Fcontrollers","docs\u002F02.essentials\u002F02.controllers","i-lucide-route",{"title":62,"path":63,"stem":64,"icon":65},"Validation & DTOs","\u002Fdocs\u002Fessentials\u002Fvalidation","docs\u002F02.essentials\u002F03.validation","i-lucide-shield-check",{"title":67,"path":68,"stem":69,"icon":70},"Contracts","\u002Fdocs\u002Fessentials\u002Fcontracts","docs\u002F02.essentials\u002F04.contracts","i-lucide-file-signature",{"title":72,"path":73,"stem":74,"icon":75},"REST Client","\u002Fdocs\u002Fessentials\u002Fclient","docs\u002F02.essentials\u002F05.client","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":80},"Database","\u002Fdocs\u002Fessentials\u002Fdatabase","docs\u002F02.essentials\u002F06.database","i-lucide-database",{"title":82,"path":83,"stem":84,"icon":85},"Drizzle ORM","\u002Fdocs\u002Fessentials\u002Fdrizzle","docs\u002F02.essentials\u002F07.drizzle","i-lucide-database-zap",{"title":87,"path":88,"stem":89,"icon":90},"Persistence & Transactions","\u002Fdocs\u002Fessentials\u002Fpersistence","docs\u002F02.essentials\u002F08.persistence","i-lucide-database-backup",{"title":92,"path":93,"stem":94,"icon":95},"Migrations","\u002Fdocs\u002Fessentials\u002Fmigrations","docs\u002F02.essentials\u002F09.migrations","i-lucide-git-branch",{"title":97,"path":98,"stem":99,"icon":100},"Authentication","\u002Fdocs\u002Fessentials\u002Fauthentication","docs\u002F02.essentials\u002F10.authentication","i-lucide-key-round",{"title":102,"path":103,"stem":104,"icon":65},"Permissions & scopes","\u002Fdocs\u002Fessentials\u002Fpermissions","docs\u002F02.essentials\u002F11.permissions",{"title":106,"path":107,"stem":108,"icon":109},"Error Handling","\u002Fdocs\u002Fessentials\u002Ferrors","docs\u002F02.essentials\u002F12.errors","i-lucide-triangle-alert",{"title":111,"path":112,"stem":113,"icon":114},"Testing a Heximon App","\u002Fdocs\u002Fessentials\u002Ftesting","docs\u002F02.essentials\u002F13.testing","i-lucide-flask-conical",{"title":116,"path":117,"stem":118,"icon":119},"Test app harness","\u002Fdocs\u002Fessentials\u002Fcreatetestapp","docs\u002F02.essentials\u002F14.createtestapp","i-lucide-test-tube",{"title":121,"path":122,"stem":123,"icon":124},"Logging & Observability","\u002Fdocs\u002Fessentials\u002Flogging","docs\u002F02.essentials\u002F17.logging","i-lucide-scroll-text",{"title":126,"path":127,"stem":128,"icon":129},"Context & Lifecycle","\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle","docs\u002F02.essentials\u002F18.context-and-lifecycle","i-lucide-radio",{"title":131,"path":132,"stem":133,"icon":134},"Project Structure","\u002Fdocs\u002Fessentials\u002Fproject-structure","docs\u002F02.essentials\u002F19.project-structure","i-lucide-folder-tree",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":45},"Capabilities","i-lucide-sparkles","\u002Fdocs\u002Fcapabilities","docs\u002F03.capabilities",[141,145,150,155,160,164,169,174,179,184,188,193,198,203,208,213],{"title":142,"path":143,"stem":144,"icon":137},"Overview","\u002Fdocs\u002Fcapabilities\u002Foverview","docs\u002F03.capabilities\u002F01.overview",{"title":146,"path":147,"stem":148,"icon":149},"Events","\u002Fdocs\u002Fcapabilities\u002Fevents","docs\u002F03.capabilities\u002F02.events","i-lucide-radio-tower",{"title":151,"path":152,"stem":153,"icon":154},"Queue","\u002Fdocs\u002Fcapabilities\u002Fbackground-jobs","docs\u002F03.capabilities\u002F03.background-jobs","i-lucide-list-ordered",{"title":156,"path":157,"stem":158,"icon":159},"Scheduled Work","\u002Fdocs\u002Fcapabilities\u002Fscheduled-jobs","docs\u002F03.capabilities\u002F04.scheduled-jobs","i-lucide-clock",{"title":161,"path":162,"stem":163,"icon":85},"Caching","\u002Fdocs\u002Fcapabilities\u002Fcaching","docs\u002F03.capabilities\u002F05.caching",{"title":165,"path":166,"stem":167,"icon":168},"Key\u002FValue Storage","\u002Fdocs\u002Fcapabilities\u002Fkey-value","docs\u002F03.capabilities\u002F06.key-value","i-lucide-hard-drive",{"title":170,"path":171,"stem":172,"icon":173},"Blob Storage","\u002Fdocs\u002Fcapabilities\u002Fblob","docs\u002F03.capabilities\u002F07.blob","i-lucide-folder-open",{"title":175,"path":176,"stem":177,"icon":178},"Health & Readiness","\u002Fdocs\u002Fcapabilities\u002Fhealth","docs\u002F03.capabilities\u002F08.health","i-lucide-heart-pulse",{"title":180,"path":181,"stem":182,"icon":183},"Notifications","\u002Fdocs\u002Fcapabilities\u002Fnotifications","docs\u002F03.capabilities\u002F09.notifications","i-lucide-mail",{"title":185,"path":186,"stem":187,"icon":65},"Idempotency","\u002Fdocs\u002Fcapabilities\u002Fidempotency","docs\u002F03.capabilities\u002F10.idempotency",{"title":189,"path":190,"stem":191,"icon":192},"Security Hardening","\u002Fdocs\u002Fcapabilities\u002Fsecurity","docs\u002F03.capabilities\u002F11.security","i-lucide-shield",{"title":194,"path":195,"stem":196,"icon":197},"Observability & Tracing","\u002Fdocs\u002Fcapabilities\u002Fobservability","docs\u002F03.capabilities\u002F12.observability","i-lucide-activity",{"title":199,"path":200,"stem":201,"icon":202},"OpenAPI","\u002Fdocs\u002Fcapabilities\u002Fopenapi","docs\u002F03.capabilities\u002F13.openapi","i-lucide-book-marked",{"title":204,"path":205,"stem":206,"icon":207},"MCP Server","\u002Fdocs\u002Fcapabilities\u002Fmcp","docs\u002F03.capabilities\u002F14.mcp","i-lucide-bot",{"title":209,"path":210,"stem":211,"icon":212},"Schema DTOs","\u002Fdocs\u002Fcapabilities\u002Fschema","docs\u002F03.capabilities\u002F15.schema","i-lucide-file-json",{"title":214,"path":215,"stem":216,"icon":217},"Branded IDs","\u002Fdocs\u002Fcapabilities\u002Fbranded-ids","docs\u002F03.capabilities\u002F16.branded-ids","i-lucide-tag",{"title":219,"icon":220,"path":221,"stem":222,"children":223,"page":45},"Architecture","i-lucide-building","\u002Fdocs\u002Farchitecture","docs\u002F04.architecture",[224,227,232,237,242,247,252],{"title":142,"path":225,"stem":226,"icon":220},"\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F04.architecture\u002F01.overview",{"title":228,"path":229,"stem":230,"icon":231},"Domain-Driven Design","\u002Fdocs\u002Farchitecture\u002Fddd","docs\u002F04.architecture\u002F02.ddd","i-lucide-hexagon",{"title":233,"path":234,"stem":235,"icon":236},"CQRS","\u002Fdocs\u002Farchitecture\u002Fcqrs","docs\u002F04.architecture\u002F03.cqrs","i-lucide-split",{"title":238,"path":239,"stem":240,"icon":241},"Repository Pattern","\u002Fdocs\u002Farchitecture\u002Frepository-pattern","docs\u002F04.architecture\u002F04.repository-pattern","i-lucide-archive",{"title":243,"path":244,"stem":245,"icon":246},"Integration Events","\u002Fdocs\u002Farchitecture\u002Fintegration-events","docs\u002F04.architecture\u002F05.integration-events","i-lucide-send-horizontal",{"title":248,"path":249,"stem":250,"icon":251},"Saga Orchestration","\u002Fdocs\u002Farchitecture\u002Fsagas","docs\u002F04.architecture\u002F06.sagas","i-lucide-hourglass",{"title":253,"path":254,"stem":255,"icon":256},"Durable Workflows","\u002Fdocs\u002Farchitecture\u002Fworkflows","docs\u002F04.architecture\u002F07.workflows","i-lucide-workflow",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":45},"Realtime","i-lucide-cable","\u002Fdocs\u002Frealtime","docs\u002F05.realtime",[263,266,270,274,279,284,288],{"title":142,"path":264,"stem":265,"icon":259},"\u002Fdocs\u002Frealtime\u002Foverview","docs\u002F05.realtime\u002F01.overview",{"title":267,"path":268,"stem":269,"icon":129},"WebSockets","\u002Fdocs\u002Frealtime\u002Fwebsockets","docs\u002F05.realtime\u002F02.websockets",{"title":271,"path":272,"stem":273,"icon":70},"WebSocket Contracts","\u002Fdocs\u002Frealtime\u002Fwebsocket-contracts","docs\u002F05.realtime\u002F03.websocket-contracts",{"title":275,"path":276,"stem":277,"icon":278},"Server-Sent Events","\u002Fdocs\u002Frealtime\u002Fserver-sent-events","docs\u002F05.realtime\u002F04.server-sent-events","i-lucide-rss",{"title":280,"path":281,"stem":282,"icon":283},"Typed Clients","\u002Fdocs\u002Frealtime\u002Ftyped-clients","docs\u002F05.realtime\u002F05.typed-clients","i-lucide-plug-zap",{"title":285,"path":286,"stem":287,"icon":259},"AsyncAPI","\u002Fdocs\u002Frealtime\u002Fasyncapi","docs\u002F05.realtime\u002F06.asyncapi",{"title":289,"path":290,"stem":291,"icon":80},"Durable Objects","\u002Fdocs\u002Frealtime\u002Fdurable-objects","docs\u002F05.realtime\u002F07.durable-objects",{"title":293,"icon":294,"path":295,"stem":296,"children":297,"page":45},"Deploy","i-lucide-cloud-upload","\u002Fdocs\u002Fdeploy","docs\u002F06.deploy",[298,301,306,311,316,321,326,331,336,341,345,350],{"title":142,"path":299,"stem":300,"icon":6},"\u002Fdocs\u002Fdeploy\u002Foverview","docs\u002F06.deploy\u002F01.overview",{"title":302,"path":303,"stem":304,"icon":305},"Node","\u002Fdocs\u002Fdeploy\u002Fnode","docs\u002F06.deploy\u002F02.node","la:node-js",{"title":307,"path":308,"stem":309,"icon":310},"Cloudflare","\u002Fdocs\u002Fdeploy\u002Fcloudflare","docs\u002F06.deploy\u002F03.cloudflare","simple-icons:cloudflare",{"title":312,"path":313,"stem":314,"icon":315},"Vercel","\u002Fdocs\u002Fdeploy\u002Fvercel","docs\u002F06.deploy\u002F04.vercel","ri:vercel-fill",{"title":317,"path":318,"stem":319,"icon":320},"Netlify","\u002Fdocs\u002Fdeploy\u002Fnetlify","docs\u002F06.deploy\u002F05.netlify","i-simple-icons-netlify",{"title":322,"path":323,"stem":324,"icon":325},"AWS Lambda","\u002Fdocs\u002Fdeploy\u002Faws-lambda","docs\u002F06.deploy\u002F06.aws-lambda","hugeicons:aws-lambda",{"title":327,"path":328,"stem":329,"icon":330},"Deno Deploy","\u002Fdocs\u002Fdeploy\u002Fdeno-deploy","docs\u002F06.deploy\u002F07.deno-deploy","simple-icons:denodeploy",{"title":332,"path":333,"stem":334,"icon":335},"Nitro","\u002Fdocs\u002Fdeploy\u002Fnitro","docs\u002F06.deploy\u002F08.nitro","i-unjs-nitro",{"title":337,"path":338,"stem":339,"icon":340},"Nuxt","\u002Fdocs\u002Fdeploy\u002Fnuxt","docs\u002F06.deploy\u002F09.nuxt","i-devicon-nuxt",{"title":342,"path":343,"stem":344,"icon":236},"Mixed-runtime split","\u002Fdocs\u002Fdeploy\u002Fmixed-runtime-split","docs\u002F06.deploy\u002F10.mixed-runtime-split",{"title":346,"path":347,"stem":348,"icon":349},"Hosts","\u002Fdocs\u002Fdeploy\u002Fhosts","docs\u002F06.deploy\u002F11.hosts","i-lucide-map",{"title":351,"path":352,"stem":353,"icon":354},"Cross-service events","\u002Fdocs\u002Fdeploy\u002Fcross-service-events","docs\u002F06.deploy\u002F12.cross-service-events","i-lucide-network",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":45},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F07.cli",[361,365,369,373],{"title":362,"path":363,"stem":364,"icon":357},"The heximon CLI","\u002Fdocs\u002Fcli\u002Foverview","docs\u002F07.cli\u002F01.overview",{"title":366,"path":367,"stem":368,"icon":137},"Create a New App","\u002Fdocs\u002Fcli\u002Fcreate","docs\u002F07.cli\u002F02.create",{"title":370,"path":371,"stem":372,"icon":95},"Migrations from the CLI","\u002Fdocs\u002Fcli\u002Fmigrations","docs\u002F07.cli\u002F03.migrations",{"title":374,"path":375,"stem":376,"icon":6},"Deploying a Heximon app","\u002Fdocs\u002Fcli\u002Fdeploy","docs\u002F07.cli\u002F04.deploy",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":45},"Under the Hood","i-lucide-wrench","\u002Fdocs\u002Funder-the-hood","docs\u002F08.under-the-hood",[383,388,393,397,402,407,411,415],{"title":384,"path":385,"stem":386,"icon":387},"How the Compiler Works","\u002Fdocs\u002Funder-the-hood\u002Fhow-the-compiler-works","docs\u002F08.under-the-hood\u002F01.how-the-compiler-works","i-lucide-cog",{"title":389,"path":390,"stem":391,"icon":392},"Compiler","\u002Fdocs\u002Funder-the-hood\u002Fextending-the-compiler","docs\u002F08.under-the-hood\u002F02.extending-the-compiler","i-lucide-cpu",{"title":394,"path":395,"stem":396,"icon":357},"Compiler Diagnostics","\u002Fdocs\u002Funder-the-hood\u002Fcompiler-diagnostics","docs\u002F08.under-the-hood\u002F03.compiler-diagnostics",{"title":398,"path":399,"stem":400,"icon":401},"Library Mode","\u002Fdocs\u002Funder-the-hood\u002Flibrary-mode","docs\u002F08.under-the-hood\u002F04.library-mode","i-lucide-package",{"title":403,"path":404,"stem":405,"icon":406},"Other bundlers","\u002Fdocs\u002Funder-the-hood\u002Falternate-bundlers","docs\u002F08.under-the-hood\u002F05.alternate-bundlers","i-lucide-blocks",{"title":408,"path":409,"stem":410,"icon":401},"Packages","\u002Fdocs\u002Funder-the-hood\u002Fpackages","docs\u002F08.under-the-hood\u002F06.packages",{"title":412,"path":413,"stem":414,"icon":207},"AI Skills","\u002Fdocs\u002Funder-the-hood\u002Fai-and-agents","docs\u002F08.under-the-hood\u002F07.ai-and-agents",{"title":416,"path":417,"stem":418,"icon":419},"Advanced DI","\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di","docs\u002F08.under-the-hood\u002F08.advanced-di","i-lucide-git-fork",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":45},"Recipes","i-lucide-book-open-check","\u002Fdocs\u002Frecipes","docs\u002F09.recipes",[426,431,436,440,444,448,452,456,460,465,469,474,479,484,488],{"title":427,"path":428,"stem":429,"icon":430},"Send an Email","\u002Fdocs\u002Frecipes\u002Fsend-an-email","docs\u002F09.recipes\u002F01.send-an-email","i-lucide-send",{"title":432,"path":433,"stem":434,"icon":435},"Upload a File","\u002Fdocs\u002Frecipes\u002Fupload-a-file","docs\u002F09.recipes\u002F02.upload-a-file","i-lucide-upload",{"title":437,"path":438,"stem":439,"icon":24},"Cache an Expensive Call","\u002Fdocs\u002Frecipes\u002Fcache-an-expensive-call","docs\u002F09.recipes\u002F03.cache-an-expensive-call",{"title":441,"path":442,"stem":443,"icon":154},"Paginate a List","\u002Fdocs\u002Frecipes\u002Fpaginate-a-list","docs\u002F09.recipes\u002F04.paginate-a-list",{"title":445,"path":446,"stem":447,"icon":65},"Protect Admin Routes","\u002Fdocs\u002Frecipes\u002Fprotect-admin-routes","docs\u002F09.recipes\u002F05.protect-admin-routes",{"title":449,"path":450,"stem":451,"icon":178},"Health Probes and a Nightly Job","\u002Fdocs\u002Frecipes\u002Fhealth-probes-and-a-nightly-job","docs\u002F09.recipes\u002F06.health-probes-and-a-nightly-job",{"title":453,"path":454,"stem":455,"icon":80},"Build a CRUD API","\u002Fdocs\u002Frecipes\u002Fcrud-api","docs\u002F09.recipes\u002F07.crud-api",{"title":457,"path":458,"stem":459,"icon":100},"Add Authentication","\u002Fdocs\u002Frecipes\u002Fadd-authentication","docs\u002F09.recipes\u002F08.add-authentication",{"title":461,"path":462,"stem":463,"icon":464},"Background Jobs","\u002Fdocs\u002Frecipes\u002Fbackground-jobs","docs\u002F09.recipes\u002F09.background-jobs","i-lucide-timer",{"title":466,"path":467,"stem":468,"icon":149},"Decouple Features with Events","\u002Fdocs\u002Frecipes\u002Fevent-driven-module","docs\u002F09.recipes\u002F10.event-driven-module",{"title":470,"path":471,"stem":472,"icon":473},"Build a DDD Aggregate","\u002Fdocs\u002Frecipes\u002Fddd-aggregate","docs\u002F09.recipes\u002F11.ddd-aggregate","i-lucide-box",{"title":475,"path":476,"stem":477,"icon":478},"Publish a Feature Package","\u002Fdocs\u002Frecipes\u002Ffeature-package","docs\u002F09.recipes\u002F12.feature-package","i-lucide-package-open",{"title":480,"path":481,"stem":482,"icon":483},"Reliable Integration Events","\u002Fdocs\u002Frecipes\u002Freliable-integration-events","docs\u002F09.recipes\u002F13.reliable-integration-events","i-lucide-inbox",{"title":485,"path":486,"stem":487,"icon":95},"Reactive Choreography","\u002Fdocs\u002Frecipes\u002Freactive-choreography","docs\u002F09.recipes\u002F14.reactive-choreography",{"title":489,"path":490,"stem":491,"icon":492},"Build a Production CRUD API","\u002Fdocs\u002Frecipes\u002Fproduction-crud-api","docs\u002F09.recipes\u002F15.production-crud-api","i-lucide-layers",{"id":494,"title":204,"body":495,"description":3331,"extension":3332,"links":3333,"meta":3334,"navigation":3335,"path":205,"seo":3336,"stem":206,"__hash__":3337},"docs\u002Fdocs\u002F03.capabilities\u002F14.mcp.md",{"type":496,"value":497,"toc":3319},"minimark",[498,507,529,532,537,608,614,625,1227,1233,1349,1353,1370,1667,1670,1806,1828,1832,1855,2802,2818,2822,2847,2857,2861,2880,2972,2982,2986,3010,3157,3161,3172,3190,3259,3263,3315],[499,500,501,502,506],"p",{},"The Model Context Protocol (MCP) is the open standard that lets AI agents — Claude, an IDE assistant, any\nMCP-speaking client — discover and call your API's operations as typed tools over HTTP, instead of you hand-writing\na bespoke integration per agent. ",[503,504,505],"code",{},"@heximon\u002Fmcp"," turns your existing contract's routes into exactly those tools.",[499,508,509,510,513,514,516,517,520,521,524,525,528],{},"Your backend already describes its API once, as a ",[503,511,512],{},"Contract",". ",[503,515,505],{}," reads that same route\ntable at runtime and derives an MCP tool manifest from it — no compiler, no extra config. Mark each route\nyou want to expose with ",[503,518,519],{},".mcp({})",", point a ",[503,522,523],{},"McpServerGenerator"," at the contract, and every ",[503,526,527],{},".mcp()","-marked\nroute becomes a typed MCP tool.",[499,530,531],{},"Because tool execution dispatches in-process through the same route chain the HTTP surface uses — handlers,\nmiddleware, validation, error filters, and auth — the MCP surface and the REST surface can't drift. One\nroute declaration drives both.",[533,534,536],"h2",{"id":535},"install-the-package","Install the package",[538,539,540,565,580,594],"code-group",{},[541,542,548],"pre",{"className":543,"code":544,"filename":545,"language":546,"meta":547,"style":547},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @heximon\u002Fmcp\n","pnpm","bash","",[503,549,550],{"__ignoreMap":547},[551,552,555,558,562],"span",{"class":553,"line":554},"line",1,[551,556,545],{"class":557},"sBMFI",[551,559,561],{"class":560},"sfazB"," add",[551,563,564],{"class":560}," @heximon\u002Fmcp\n",[541,566,569],{"className":543,"code":567,"filename":568,"language":546,"meta":547,"style":547},"npm install @heximon\u002Fmcp\n","npm",[503,570,571],{"__ignoreMap":547},[551,572,573,575,578],{"class":553,"line":554},[551,574,568],{"class":557},[551,576,577],{"class":560}," install",[551,579,564],{"class":560},[541,581,584],{"className":543,"code":582,"filename":583,"language":546,"meta":547,"style":547},"yarn add @heximon\u002Fmcp\n","yarn",[503,585,586],{"__ignoreMap":547},[551,587,588,590,592],{"class":553,"line":554},[551,589,583],{"class":557},[551,591,561],{"class":560},[551,593,564],{"class":560},[541,595,598],{"className":543,"code":596,"filename":597,"language":546,"meta":547,"style":547},"bun add @heximon\u002Fmcp\n","bun",[503,599,600],{"__ignoreMap":547},[551,601,602,604,606],{"class":553,"line":554},[551,603,597],{"class":557},[551,605,561],{"class":560},[551,607,564],{"class":560},[533,609,611,612],{"id":610},"opt-routes-in-with-mcp","Opt routes in with ",[503,613,527],{},[499,615,616,617,620,621,624],{},"The route builder's ",[503,618,619],{},".mcp({ ... })"," method marks a route for MCP exposure. The generator's default\nselection is ",[503,622,623],{},"'marked'"," — only routes that carry this marker become tools, so you curate your AI surface\nroute by route with no risk of accidentally exposing an internal endpoint.",[541,626,631],{"className":627,"code":628,"filename":629,"language":630,"meta":547,"style":547},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { Contract, Route } from \"@heximon\u002Fcontract\";\nimport \"@heximon\u002Fmcp\"; \u002F\u002F side-effect: augments Route descriptor with .mcp() typing\nimport { createProduct, product, productCount, productList, productParams } from \".\u002Fproduct.schema\";\n\nexport class ProductsApi extends Contract({\n  prefix: \"\u002Fapi\u002Fproducts\",\n  routes: {\n    \u002F\u002F Marked .mcp({}) — exposed as the `products.list` tool.\n    list: Route.get(\"\u002F\").summary(\"List products\").mcp({}).responses({ 200: productList }),\n\n    \u002F\u002F Marked with resource: true — also a readable MCP resource (mcp:\u002F\u002Fresource\u002Fapi\u002Fproducts\u002F:sku).\n    find: Route.get(\"\u002F:sku\")\n      .summary(\"Get a product by SKU\")\n      .pathParams(productParams)\n      .mcp({ resource: true })\n      .responses({ 200: product }),\n\n    \u002F\u002F Marked with annotation overrides.\n    create: Route.post(\"\u002F\")\n      .summary(\"Create a product\")\n      .body(createProduct)\n      .scopes(\"products.write\")\n      .mcp({ annotations: { destructiveHint: false } })\n      .responses({ 201: product }),\n\n    \u002F\u002F No .mcp() — plain HTTP only, never a tool.\n    count: Route.get(\"\u002Fcount\").summary(\"Count products\").responses({ 200: productCount }),\n  },\n}) {}\n","src\u002Fproducts\u002Fproduct.api.ts","ts",[503,632,633,671,689,732,739,764,784,795,801,883,888,894,920,939,950,974,998,1003,1009,1034,1052,1063,1082,1114,1138,1143,1149,1210,1216],{"__ignoreMap":547},[551,634,635,639,643,647,650,653,656,659,662,665,668],{"class":553,"line":554},[551,636,638],{"class":637},"s7zQu","import",[551,640,642],{"class":641},"sMK4o"," {",[551,644,646],{"class":645},"sTEyZ"," Contract",[551,648,649],{"class":641},",",[551,651,652],{"class":645}," Route",[551,654,655],{"class":641}," }",[551,657,658],{"class":637}," from",[551,660,661],{"class":641}," \"",[551,663,664],{"class":560},"@heximon\u002Fcontract",[551,666,667],{"class":641},"\"",[551,669,670],{"class":641},";\n",[551,672,674,676,678,680,682,685],{"class":553,"line":673},2,[551,675,638],{"class":637},[551,677,661],{"class":641},[551,679,505],{"class":560},[551,681,667],{"class":641},[551,683,684],{"class":641},";",[551,686,688],{"class":687},"sHwdD"," \u002F\u002F side-effect: augments Route descriptor with .mcp() typing\n",[551,690,692,694,696,699,701,704,706,709,711,714,716,719,721,723,725,728,730],{"class":553,"line":691},3,[551,693,638],{"class":637},[551,695,642],{"class":641},[551,697,698],{"class":645}," createProduct",[551,700,649],{"class":641},[551,702,703],{"class":645}," product",[551,705,649],{"class":641},[551,707,708],{"class":645}," productCount",[551,710,649],{"class":641},[551,712,713],{"class":645}," productList",[551,715,649],{"class":641},[551,717,718],{"class":645}," productParams",[551,720,655],{"class":641},[551,722,658],{"class":637},[551,724,661],{"class":641},[551,726,727],{"class":560},".\u002Fproduct.schema",[551,729,667],{"class":641},[551,731,670],{"class":641},[551,733,735],{"class":553,"line":734},4,[551,736,738],{"emptyLinePlaceholder":737},true,"\n",[551,740,742,745,749,752,755,758,761],{"class":553,"line":741},5,[551,743,744],{"class":637},"export",[551,746,748],{"class":747},"spNyl"," class",[551,750,751],{"class":557}," ProductsApi",[551,753,754],{"class":747}," extends",[551,756,646],{"class":757},"s2Zo4",[551,759,760],{"class":645},"(",[551,762,763],{"class":641},"{\n",[551,765,767,771,774,776,779,781],{"class":553,"line":766},6,[551,768,770],{"class":769},"swJcz","  prefix",[551,772,773],{"class":641},":",[551,775,661],{"class":641},[551,777,778],{"class":560},"\u002Fapi\u002Fproducts",[551,780,667],{"class":641},[551,782,783],{"class":641},",\n",[551,785,787,790,792],{"class":553,"line":786},7,[551,788,789],{"class":769},"  routes",[551,791,773],{"class":641},[551,793,794],{"class":641}," {\n",[551,796,798],{"class":553,"line":797},8,[551,799,800],{"class":687},"    \u002F\u002F Marked .mcp({}) — exposed as the `products.list` tool.\n",[551,802,804,807,809,811,814,817,819,821,824,826,829,831,834,836,838,841,843,845,847,850,852,855,857,859,862,864,867,871,873,876,879,881],{"class":553,"line":803},9,[551,805,806],{"class":769},"    list",[551,808,773],{"class":641},[551,810,652],{"class":645},[551,812,813],{"class":641},".",[551,815,816],{"class":757},"get",[551,818,760],{"class":645},[551,820,667],{"class":641},[551,822,823],{"class":560},"\u002F",[551,825,667],{"class":641},[551,827,828],{"class":645},")",[551,830,813],{"class":641},[551,832,833],{"class":757},"summary",[551,835,760],{"class":645},[551,837,667],{"class":641},[551,839,840],{"class":560},"List products",[551,842,667],{"class":641},[551,844,828],{"class":645},[551,846,813],{"class":641},[551,848,849],{"class":757},"mcp",[551,851,760],{"class":645},[551,853,854],{"class":641},"{}",[551,856,828],{"class":645},[551,858,813],{"class":641},[551,860,861],{"class":757},"responses",[551,863,760],{"class":645},[551,865,866],{"class":641},"{",[551,868,870],{"class":869},"sbssI"," 200",[551,872,773],{"class":641},[551,874,875],{"class":645}," productList ",[551,877,878],{"class":641},"}",[551,880,828],{"class":645},[551,882,783],{"class":641},[551,884,886],{"class":553,"line":885},10,[551,887,738],{"emptyLinePlaceholder":737},[551,889,891],{"class":553,"line":890},11,[551,892,893],{"class":687},"    \u002F\u002F Marked with resource: true — also a readable MCP resource (mcp:\u002F\u002Fresource\u002Fapi\u002Fproducts\u002F:sku).\n",[551,895,897,900,902,904,906,908,910,912,915,917],{"class":553,"line":896},12,[551,898,899],{"class":769},"    find",[551,901,773],{"class":641},[551,903,652],{"class":645},[551,905,813],{"class":641},[551,907,816],{"class":757},[551,909,760],{"class":645},[551,911,667],{"class":641},[551,913,914],{"class":560},"\u002F:sku",[551,916,667],{"class":641},[551,918,919],{"class":645},")\n",[551,921,923,926,928,930,932,935,937],{"class":553,"line":922},13,[551,924,925],{"class":641},"      .",[551,927,833],{"class":757},[551,929,760],{"class":645},[551,931,667],{"class":641},[551,933,934],{"class":560},"Get a product by SKU",[551,936,667],{"class":641},[551,938,919],{"class":645},[551,940,942,944,947],{"class":553,"line":941},14,[551,943,925],{"class":641},[551,945,946],{"class":757},"pathParams",[551,948,949],{"class":645},"(productParams)\n",[551,951,953,955,957,959,961,964,966,970,972],{"class":553,"line":952},15,[551,954,925],{"class":641},[551,956,849],{"class":757},[551,958,760],{"class":645},[551,960,866],{"class":641},[551,962,963],{"class":769}," resource",[551,965,773],{"class":641},[551,967,969],{"class":968},"sfNiH"," true",[551,971,655],{"class":641},[551,973,919],{"class":645},[551,975,977,979,981,983,985,987,989,992,994,996],{"class":553,"line":976},16,[551,978,925],{"class":641},[551,980,861],{"class":757},[551,982,760],{"class":645},[551,984,866],{"class":641},[551,986,870],{"class":869},[551,988,773],{"class":641},[551,990,991],{"class":645}," product ",[551,993,878],{"class":641},[551,995,828],{"class":645},[551,997,783],{"class":641},[551,999,1001],{"class":553,"line":1000},17,[551,1002,738],{"emptyLinePlaceholder":737},[551,1004,1006],{"class":553,"line":1005},18,[551,1007,1008],{"class":687},"    \u002F\u002F Marked with annotation overrides.\n",[551,1010,1012,1015,1017,1019,1021,1024,1026,1028,1030,1032],{"class":553,"line":1011},19,[551,1013,1014],{"class":769},"    create",[551,1016,773],{"class":641},[551,1018,652],{"class":645},[551,1020,813],{"class":641},[551,1022,1023],{"class":757},"post",[551,1025,760],{"class":645},[551,1027,667],{"class":641},[551,1029,823],{"class":560},[551,1031,667],{"class":641},[551,1033,919],{"class":645},[551,1035,1037,1039,1041,1043,1045,1048,1050],{"class":553,"line":1036},20,[551,1038,925],{"class":641},[551,1040,833],{"class":757},[551,1042,760],{"class":645},[551,1044,667],{"class":641},[551,1046,1047],{"class":560},"Create a product",[551,1049,667],{"class":641},[551,1051,919],{"class":645},[551,1053,1055,1057,1060],{"class":553,"line":1054},21,[551,1056,925],{"class":641},[551,1058,1059],{"class":757},"body",[551,1061,1062],{"class":645},"(createProduct)\n",[551,1064,1066,1068,1071,1073,1075,1078,1080],{"class":553,"line":1065},22,[551,1067,925],{"class":641},[551,1069,1070],{"class":757},"scopes",[551,1072,760],{"class":645},[551,1074,667],{"class":641},[551,1076,1077],{"class":560},"products.write",[551,1079,667],{"class":641},[551,1081,919],{"class":645},[551,1083,1085,1087,1089,1091,1093,1096,1098,1100,1103,1105,1108,1110,1112],{"class":553,"line":1084},23,[551,1086,925],{"class":641},[551,1088,849],{"class":757},[551,1090,760],{"class":645},[551,1092,866],{"class":641},[551,1094,1095],{"class":769}," annotations",[551,1097,773],{"class":641},[551,1099,642],{"class":641},[551,1101,1102],{"class":769}," destructiveHint",[551,1104,773],{"class":641},[551,1106,1107],{"class":968}," false",[551,1109,655],{"class":641},[551,1111,655],{"class":641},[551,1113,919],{"class":645},[551,1115,1117,1119,1121,1123,1125,1128,1130,1132,1134,1136],{"class":553,"line":1116},24,[551,1118,925],{"class":641},[551,1120,861],{"class":757},[551,1122,760],{"class":645},[551,1124,866],{"class":641},[551,1126,1127],{"class":869}," 201",[551,1129,773],{"class":641},[551,1131,991],{"class":645},[551,1133,878],{"class":641},[551,1135,828],{"class":645},[551,1137,783],{"class":641},[551,1139,1141],{"class":553,"line":1140},25,[551,1142,738],{"emptyLinePlaceholder":737},[551,1144,1146],{"class":553,"line":1145},26,[551,1147,1148],{"class":687},"    \u002F\u002F No .mcp() — plain HTTP only, never a tool.\n",[551,1150,1152,1155,1157,1159,1161,1163,1165,1167,1170,1172,1174,1176,1178,1180,1182,1185,1187,1189,1191,1193,1195,1197,1199,1201,1204,1206,1208],{"class":553,"line":1151},27,[551,1153,1154],{"class":769},"    count",[551,1156,773],{"class":641},[551,1158,652],{"class":645},[551,1160,813],{"class":641},[551,1162,816],{"class":757},[551,1164,760],{"class":645},[551,1166,667],{"class":641},[551,1168,1169],{"class":560},"\u002Fcount",[551,1171,667],{"class":641},[551,1173,828],{"class":645},[551,1175,813],{"class":641},[551,1177,833],{"class":757},[551,1179,760],{"class":645},[551,1181,667],{"class":641},[551,1183,1184],{"class":560},"Count products",[551,1186,667],{"class":641},[551,1188,828],{"class":645},[551,1190,813],{"class":641},[551,1192,861],{"class":757},[551,1194,760],{"class":645},[551,1196,866],{"class":641},[551,1198,870],{"class":869},[551,1200,773],{"class":641},[551,1202,1203],{"class":645}," productCount ",[551,1205,878],{"class":641},[551,1207,828],{"class":645},[551,1209,783],{"class":641},[551,1211,1213],{"class":553,"line":1212},28,[551,1214,1215],{"class":641},"  },\n",[551,1217,1219,1221,1224],{"class":553,"line":1218},29,[551,1220,878],{"class":641},[551,1222,1223],{"class":645},") ",[551,1225,1226],{"class":641},"{}\n",[499,1228,1229,1230,1232],{},"The ",[503,1231,619],{}," marker accepts several optional overrides:",[1234,1235,1236,1250],"table",{},[1237,1238,1239],"thead",{},[1240,1241,1242,1247],"tr",{},[1243,1244,1246],"th",{"align":1245},"left","Field",[1243,1248,1249],{"align":1245},"What it controls",[1251,1252,1253,1267,1279,1292,1317,1331],"tbody",{},[1240,1254,1255,1261],{},[1256,1257,1258],"td",{"align":1245},[503,1259,1260],{},"name",[1256,1262,1263,1264,828],{"align":1245},"Override the tool name (default ",[503,1265,1266],{},"\u003Cnamespace>.\u003CrouteKey>",[1240,1268,1269,1274],{},[1256,1270,1271],{"align":1245},[503,1272,1273],{},"title",[1256,1275,1276,1277,828],{"align":1245},"Override the tool title (default: the route's ",[503,1278,833],{},[1240,1280,1281,1286],{},[1256,1282,1283],{"align":1245},[503,1284,1285],{},"description",[1256,1287,1288,1289,828],{"align":1245},"Override the tool description (default: ",[503,1290,1291],{},"description ?? summary ?? \"METHOD \u002Fpath\"",[1240,1293,1294,1299],{},[1256,1295,1296],{"align":1245},[503,1297,1298],{},"annotations",[1256,1300,1301,1302,1305,1306,1309,1310,1305,1313,1316],{"align":1245},"Merge over the verb-seeded behavioral hints (",[503,1303,1304],{},"GET","→",[503,1307,1308],{},"readOnlyHint",", ",[503,1311,1312],{},"DELETE",[503,1314,1315],{},"destructiveHint",", …)",[1240,1318,1319,1324],{},[1256,1320,1321],{"align":1245},[503,1322,1323],{},"exclude",[1256,1325,1326,1327,1330],{"align":1245},"Exclude even under ",[503,1328,1329],{},"'all'"," selection",[1240,1332,1333,1338],{},[1256,1334,1335],{"align":1245},[503,1336,1337],{},"resource",[1256,1339,1340,1341,1344,1345,1348],{"align":1245},"Also expose as an MCP resource — ",[503,1342,1343],{},"true"," uses defaults; ",[503,1346,1347],{},"{ name?, mimeType? }"," overrides",[533,1350,1352],{"id":1351},"create-the-generator","Create the generator",[499,1354,1355,1357,1358,1361,1362,1365,1366,1369],{},[503,1356,523],{}," is the runtime counterpart of ",[503,1359,1360],{},"OpenApiGenerator"," — it builds the tool manifest once\nand memoizes it. Construct it with ",[503,1363,1364],{},"serverInfo"," and the ",[503,1367,1368],{},"contracts"," to expose, then wire it as a DI\nprovider so the controller receives it by constructor injection.",[541,1371,1374],{"className":627,"code":1372,"filename":1373,"language":630,"meta":547,"style":547},"import { Module } from \"@heximon\u002Fruntime\";\nimport { McpServerGenerator } from \"@heximon\u002Fmcp\";\nimport { ProductsApi } from \"..\u002Fproducts\u002Fproduct.api\";\nimport { McpController } from \".\u002Fmcp.controller\";\n\nexport class McpModule extends Module({\n  providers: [\n    {\n      provide: McpServerGenerator,\n      useFactory: () =>\n        new McpServerGenerator({\n          serverInfo: { name: \"products-mcp\", version: \"1.0.0\", title: \"Products MCP\" },\n          contracts: [ProductsApi],\n          \u002F\u002F selection defaults to 'marked' — only .mcp()-marked routes become tools\n          instructions: \"Tools for listing, fetching, and creating products.\",\n        }),\n    },\n  ],\n  http: { controllers: [McpController] },\n}) {}\n","src\u002Fmcp\u002Fmcp.module.ts",[503,1375,1376,1398,1419,1440,1462,1466,1483,1493,1498,1509,1522,1533,1585,1597,1602,1618,1627,1632,1639,1659],{"__ignoreMap":547},[551,1377,1378,1380,1382,1385,1387,1389,1391,1394,1396],{"class":553,"line":554},[551,1379,638],{"class":637},[551,1381,642],{"class":641},[551,1383,1384],{"class":645}," Module",[551,1386,655],{"class":641},[551,1388,658],{"class":637},[551,1390,661],{"class":641},[551,1392,1393],{"class":560},"@heximon\u002Fruntime",[551,1395,667],{"class":641},[551,1397,670],{"class":641},[551,1399,1400,1402,1404,1407,1409,1411,1413,1415,1417],{"class":553,"line":673},[551,1401,638],{"class":637},[551,1403,642],{"class":641},[551,1405,1406],{"class":645}," McpServerGenerator",[551,1408,655],{"class":641},[551,1410,658],{"class":637},[551,1412,661],{"class":641},[551,1414,505],{"class":560},[551,1416,667],{"class":641},[551,1418,670],{"class":641},[551,1420,1421,1423,1425,1427,1429,1431,1433,1436,1438],{"class":553,"line":691},[551,1422,638],{"class":637},[551,1424,642],{"class":641},[551,1426,751],{"class":645},[551,1428,655],{"class":641},[551,1430,658],{"class":637},[551,1432,661],{"class":641},[551,1434,1435],{"class":560},"..\u002Fproducts\u002Fproduct.api",[551,1437,667],{"class":641},[551,1439,670],{"class":641},[551,1441,1442,1444,1446,1449,1451,1453,1455,1458,1460],{"class":553,"line":734},[551,1443,638],{"class":637},[551,1445,642],{"class":641},[551,1447,1448],{"class":645}," McpController",[551,1450,655],{"class":641},[551,1452,658],{"class":637},[551,1454,661],{"class":641},[551,1456,1457],{"class":560},".\u002Fmcp.controller",[551,1459,667],{"class":641},[551,1461,670],{"class":641},[551,1463,1464],{"class":553,"line":741},[551,1465,738],{"emptyLinePlaceholder":737},[551,1467,1468,1470,1472,1475,1477,1479,1481],{"class":553,"line":766},[551,1469,744],{"class":637},[551,1471,748],{"class":747},[551,1473,1474],{"class":557}," McpModule",[551,1476,754],{"class":747},[551,1478,1384],{"class":757},[551,1480,760],{"class":645},[551,1482,763],{"class":641},[551,1484,1485,1488,1490],{"class":553,"line":786},[551,1486,1487],{"class":769},"  providers",[551,1489,773],{"class":641},[551,1491,1492],{"class":645}," [\n",[551,1494,1495],{"class":553,"line":797},[551,1496,1497],{"class":641},"    {\n",[551,1499,1500,1503,1505,1507],{"class":553,"line":803},[551,1501,1502],{"class":769},"      provide",[551,1504,773],{"class":641},[551,1506,1406],{"class":645},[551,1508,783],{"class":641},[551,1510,1511,1514,1516,1519],{"class":553,"line":885},[551,1512,1513],{"class":757},"      useFactory",[551,1515,773],{"class":641},[551,1517,1518],{"class":641}," ()",[551,1520,1521],{"class":747}," =>\n",[551,1523,1524,1527,1529,1531],{"class":553,"line":890},[551,1525,1526],{"class":641},"        new",[551,1528,1406],{"class":757},[551,1530,760],{"class":645},[551,1532,763],{"class":641},[551,1534,1535,1538,1540,1542,1545,1547,1549,1552,1554,1556,1559,1561,1563,1566,1568,1570,1573,1575,1577,1580,1582],{"class":553,"line":896},[551,1536,1537],{"class":769},"          serverInfo",[551,1539,773],{"class":641},[551,1541,642],{"class":641},[551,1543,1544],{"class":769}," name",[551,1546,773],{"class":641},[551,1548,661],{"class":641},[551,1550,1551],{"class":560},"products-mcp",[551,1553,667],{"class":641},[551,1555,649],{"class":641},[551,1557,1558],{"class":769}," version",[551,1560,773],{"class":641},[551,1562,661],{"class":641},[551,1564,1565],{"class":560},"1.0.0",[551,1567,667],{"class":641},[551,1569,649],{"class":641},[551,1571,1572],{"class":769}," title",[551,1574,773],{"class":641},[551,1576,661],{"class":641},[551,1578,1579],{"class":560},"Products MCP",[551,1581,667],{"class":641},[551,1583,1584],{"class":641}," },\n",[551,1586,1587,1590,1592,1595],{"class":553,"line":922},[551,1588,1589],{"class":769},"          contracts",[551,1591,773],{"class":641},[551,1593,1594],{"class":645}," [ProductsApi]",[551,1596,783],{"class":641},[551,1598,1599],{"class":553,"line":941},[551,1600,1601],{"class":687},"          \u002F\u002F selection defaults to 'marked' — only .mcp()-marked routes become tools\n",[551,1603,1604,1607,1609,1611,1614,1616],{"class":553,"line":952},[551,1605,1606],{"class":769},"          instructions",[551,1608,773],{"class":641},[551,1610,661],{"class":641},[551,1612,1613],{"class":560},"Tools for listing, fetching, and creating products.",[551,1615,667],{"class":641},[551,1617,783],{"class":641},[551,1619,1620,1623,1625],{"class":553,"line":976},[551,1621,1622],{"class":641},"        }",[551,1624,828],{"class":645},[551,1626,783],{"class":641},[551,1628,1629],{"class":553,"line":1000},[551,1630,1631],{"class":641},"    },\n",[551,1633,1634,1637],{"class":553,"line":1005},[551,1635,1636],{"class":645},"  ]",[551,1638,783],{"class":641},[551,1640,1641,1644,1646,1648,1651,1653,1656],{"class":553,"line":1011},[551,1642,1643],{"class":769},"  http",[551,1645,773],{"class":641},[551,1647,642],{"class":641},[551,1649,1650],{"class":769}," controllers",[551,1652,773],{"class":641},[551,1654,1655],{"class":645}," [McpController] ",[551,1657,1658],{"class":641},"},\n",[551,1660,1661,1663,1665],{"class":553,"line":1036},[551,1662,878],{"class":641},[551,1664,1223],{"class":645},[551,1666,1226],{"class":641},[499,1668,1669],{},"The generator options:",[1234,1671,1672,1685],{},[1237,1673,1674],{},[1240,1675,1676,1679,1682],{},[1243,1677,1678],{"align":1245},"Option",[1243,1680,1681],{"align":1245},"Default",[1243,1683,1684],{"align":1245},"What it does",[1251,1686,1687,1702,1713,1738,1751,1765,1777,1792],{},[1240,1688,1689,1693,1696],{},[1256,1690,1691],{"align":1245},[503,1692,1364],{},[1256,1694,1695],{"align":1245},"—",[1256,1697,1698,1699],{"align":1245},"The server name + version echoed at ",[503,1700,1701],{},"initialize",[1240,1703,1704,1708,1710],{},[1256,1705,1706],{"align":1245},[503,1707,1368],{},[1256,1709,1695],{"align":1245},[1256,1711,1712],{"align":1245},"The contracts whose marked routes become tools",[1240,1714,1715,1720,1724],{},[1256,1716,1717],{"align":1245},[503,1718,1719],{},"selection",[1256,1721,1722],{"align":1245},[503,1723,623],{},[1256,1725,1726,1728,1729,1731,1732,1734,1735],{"align":1245},[503,1727,623],{}," — only ",[503,1730,527],{},"-marked routes; ",[503,1733,1329],{}," — every route except ",[503,1736,1737],{},"mcp.exclude",[1240,1739,1740,1745,1748],{},[1256,1741,1742],{"align":1245},[503,1743,1744],{},"converter",[1256,1746,1747],{"align":1245},"Standard JSON Schema",[1256,1749,1750],{"align":1245},"Custom schema → JSON Schema converter",[1240,1752,1753,1758,1762],{},[1256,1754,1755],{"align":1245},[503,1756,1757],{},"toolName",[1256,1759,1760],{"align":1245},[503,1761,1266],{},[1256,1763,1764],{"align":1245},"Override the name derivation for all tools",[1240,1766,1767,1771,1774],{},[1256,1768,1769],{"align":1245},[503,1770,1298],{},[1256,1772,1773],{"align":1245},"verb-seeded",[1256,1775,1776],{"align":1245},"Override behavioral annotations at the generator level",[1240,1778,1779,1784,1789],{},[1256,1780,1781],{"align":1245},[503,1782,1783],{},"resourceBaseUrl",[1256,1785,1786],{"align":1245},[503,1787,1788],{},"\"mcp:\u002F\u002Fresource\"",[1256,1790,1791],{"align":1245},"Base URI prefix for MCP resources",[1240,1793,1794,1799,1801],{},[1256,1795,1796],{"align":1245},[503,1797,1798],{},"instructions",[1256,1800,1695],{"align":1245},[1256,1802,1803,1804],{"align":1245},"Usage instructions surfaced at ",[503,1805,1701],{},[1807,1808,1810,1817,1818,1821,1822,1824,1825,1827],"callout",{"type":1809},"info",[1811,1812,1813,1814,1816],"strong",{},"Selection ",[503,1815,1329],{}," is for a deliberately-curated contract."," When you set ",[503,1819,1820],{},"selection: 'all'",", every route\nin the supplied contracts becomes a tool (except those marked ",[503,1823,1737],{},"). Only use it with a contract\nyou have already scoped to AI-facing routes — the safer default is ",[503,1826,623],{},", which requires you to opt each\nroute in individually.",[533,1829,1831],{"id":1830},"write-the-controller","Write the controller",[499,1833,1834,1836,1837,1840,1841,1843,1844,1847,1848,1851,1852,813],{},[503,1835,505],{}," ships no controller. You write a thin one — the same pattern as ",[503,1838,1839],{},"DocsController"," for\nOpenAPI. The controller receives the ",[503,1842,523],{}," and the host-supplied ",[503,1845,1846],{},"InternalClient"," by\nconstructor injection, constructs an ",[503,1849,1850],{},"McpServer"," per request, and calls ",[503,1853,1854],{},"handle()",[541,1856,1859],{"className":627,"code":1857,"filename":1858,"language":630,"meta":547,"style":547},"import type { Controller, Get, InternalClient, Post } from \"@heximon\u002Fhttp\";\nimport {\n  JsonRpcErrorCode,\n  type McpHttpReply,\n  McpServer,\n  type McpServerGenerator,\n  McpToolDispatcher,\n} from \"@heximon\u002Fmcp\";\n\nexport class McpController implements Controller {\n  public constructor(\n    private readonly generator: McpServerGenerator,\n    private readonly internalClient: InternalClient,\n  ) {}\n\n  \u002F** POST \u002Fmcp — handle one JSON-RPC message (initialize \u002F tools\u002Flist \u002F tools\u002Fcall \u002F notifications). *\u002F\n  public async rpc(action: Post\u003C\"\u002Fmcp\">): Promise\u003CResponse> {\n    let message: unknown;\n\n    try {\n      message = await action.request.readBody();\n    } catch {\n      return McpController.send({\n        status: 400,\n        body: {\n          jsonrpc: \"2.0\",\n          id: null,\n          error: { code: JsonRpcErrorCode.ParseError, message: \"Parse error: invalid JSON.\" },\n        },\n      });\n    }\n\n    const server = new McpServer(this.generator, new McpToolDispatcher(this.internalClient));\n    return McpController.send(await server.handle(message, action.request));\n  }\n\n  \u002F** GET \u002Fmcp — the stateless tier has no server-initiated stream; a GET is 405. *\u002F\n  public async probe(_action: Get\u003C\"\u002Fmcp\">): Promise\u003CResponse> {\n    return McpController.send({\n      status: 405,\n      headers: { allow: \"POST\" },\n      body: {\n        jsonrpc: \"2.0\",\n        id: null,\n        error: {\n          code: JsonRpcErrorCode.InvalidRequest,\n          message: \"The MCP endpoint uses POST (stateless Streamable HTTP).\",\n        },\n      },\n    });\n  }\n\n  private static send(reply: McpHttpReply): Response {\n    const headers = new Headers(reply.headers);\n    if (reply.body === undefined) {\n      return new Response(null, { status: reply.status, headers });\n    }\n    headers.set(\"content-type\", \"application\u002Fjson\");\n    return new Response(JSON.stringify(reply.body), { status: reply.status, headers });\n  }\n}\n","src\u002Fmcp\u002Fmcp.controller.ts",[503,1860,1861,1901,1907,1914,1924,1931,1939,1946,1960,1964,1979,1990,2008,2023,2031,2035,2040,2085,2100,2104,2111,2140,2150,2166,2178,2187,2203,2213,2250,2255,2265,2271,2276,2320,2361,2367,2372,2378,2417,2432,2445,2469,2479,2495,2505,2515,2532,2549,2554,2560,2569,2574,2579,2608,2636,2661,2700,2705,2738,2791,2796],{"__ignoreMap":547},[551,1862,1863,1865,1868,1870,1873,1875,1878,1880,1883,1885,1888,1890,1892,1894,1897,1899],{"class":553,"line":554},[551,1864,638],{"class":637},[551,1866,1867],{"class":637}," type",[551,1869,642],{"class":641},[551,1871,1872],{"class":645}," Controller",[551,1874,649],{"class":641},[551,1876,1877],{"class":645}," Get",[551,1879,649],{"class":641},[551,1881,1882],{"class":645}," InternalClient",[551,1884,649],{"class":641},[551,1886,1887],{"class":645}," Post",[551,1889,655],{"class":641},[551,1891,658],{"class":637},[551,1893,661],{"class":641},[551,1895,1896],{"class":560},"@heximon\u002Fhttp",[551,1898,667],{"class":641},[551,1900,670],{"class":641},[551,1902,1903,1905],{"class":553,"line":673},[551,1904,638],{"class":637},[551,1906,794],{"class":641},[551,1908,1909,1912],{"class":553,"line":691},[551,1910,1911],{"class":645},"  JsonRpcErrorCode",[551,1913,783],{"class":641},[551,1915,1916,1919,1922],{"class":553,"line":734},[551,1917,1918],{"class":637},"  type",[551,1920,1921],{"class":645}," McpHttpReply",[551,1923,783],{"class":641},[551,1925,1926,1929],{"class":553,"line":741},[551,1927,1928],{"class":645},"  McpServer",[551,1930,783],{"class":641},[551,1932,1933,1935,1937],{"class":553,"line":766},[551,1934,1918],{"class":637},[551,1936,1406],{"class":645},[551,1938,783],{"class":641},[551,1940,1941,1944],{"class":553,"line":786},[551,1942,1943],{"class":645},"  McpToolDispatcher",[551,1945,783],{"class":641},[551,1947,1948,1950,1952,1954,1956,1958],{"class":553,"line":797},[551,1949,878],{"class":641},[551,1951,658],{"class":637},[551,1953,661],{"class":641},[551,1955,505],{"class":560},[551,1957,667],{"class":641},[551,1959,670],{"class":641},[551,1961,1962],{"class":553,"line":803},[551,1963,738],{"emptyLinePlaceholder":737},[551,1965,1966,1968,1970,1972,1975,1977],{"class":553,"line":885},[551,1967,744],{"class":637},[551,1969,748],{"class":747},[551,1971,1448],{"class":557},[551,1973,1974],{"class":747}," implements",[551,1976,1872],{"class":557},[551,1978,794],{"class":641},[551,1980,1981,1984,1987],{"class":553,"line":890},[551,1982,1983],{"class":747},"  public",[551,1985,1986],{"class":747}," constructor",[551,1988,1989],{"class":641},"(\n",[551,1991,1992,1995,1998,2002,2004,2006],{"class":553,"line":896},[551,1993,1994],{"class":747},"    private",[551,1996,1997],{"class":747}," readonly",[551,1999,2001],{"class":2000},"sHdIc"," generator",[551,2003,773],{"class":641},[551,2005,1406],{"class":557},[551,2007,783],{"class":641},[551,2009,2010,2012,2014,2017,2019,2021],{"class":553,"line":922},[551,2011,1994],{"class":747},[551,2013,1997],{"class":747},[551,2015,2016],{"class":2000}," internalClient",[551,2018,773],{"class":641},[551,2020,1882],{"class":557},[551,2022,783],{"class":641},[551,2024,2025,2028],{"class":553,"line":941},[551,2026,2027],{"class":641},"  )",[551,2029,2030],{"class":641}," {}\n",[551,2032,2033],{"class":553,"line":952},[551,2034,738],{"emptyLinePlaceholder":737},[551,2036,2037],{"class":553,"line":976},[551,2038,2039],{"class":687},"  \u002F** POST \u002Fmcp — handle one JSON-RPC message (initialize \u002F tools\u002Flist \u002F tools\u002Fcall \u002F notifications). *\u002F\n",[551,2041,2042,2044,2047,2050,2052,2055,2057,2059,2062,2064,2067,2069,2072,2075,2077,2080,2083],{"class":553,"line":1000},[551,2043,1983],{"class":747},[551,2045,2046],{"class":747}," async",[551,2048,2049],{"class":769}," rpc",[551,2051,760],{"class":641},[551,2053,2054],{"class":2000},"action",[551,2056,773],{"class":641},[551,2058,1887],{"class":557},[551,2060,2061],{"class":641},"\u003C",[551,2063,667],{"class":641},[551,2065,2066],{"class":560},"\u002Fmcp",[551,2068,667],{"class":641},[551,2070,2071],{"class":641},">):",[551,2073,2074],{"class":557}," Promise",[551,2076,2061],{"class":641},[551,2078,2079],{"class":557},"Response",[551,2081,2082],{"class":641},">",[551,2084,794],{"class":641},[551,2086,2087,2090,2093,2095,2098],{"class":553,"line":1005},[551,2088,2089],{"class":747},"    let",[551,2091,2092],{"class":645}," message",[551,2094,773],{"class":641},[551,2096,2097],{"class":557}," unknown",[551,2099,670],{"class":641},[551,2101,2102],{"class":553,"line":1011},[551,2103,738],{"emptyLinePlaceholder":737},[551,2105,2106,2109],{"class":553,"line":1036},[551,2107,2108],{"class":637},"    try",[551,2110,794],{"class":641},[551,2112,2113,2116,2119,2122,2125,2127,2130,2132,2135,2138],{"class":553,"line":1054},[551,2114,2115],{"class":645},"      message",[551,2117,2118],{"class":641}," =",[551,2120,2121],{"class":637}," await",[551,2123,2124],{"class":645}," action",[551,2126,813],{"class":641},[551,2128,2129],{"class":645},"request",[551,2131,813],{"class":641},[551,2133,2134],{"class":757},"readBody",[551,2136,2137],{"class":769},"()",[551,2139,670],{"class":641},[551,2141,2142,2145,2148],{"class":553,"line":1065},[551,2143,2144],{"class":641},"    }",[551,2146,2147],{"class":637}," catch",[551,2149,794],{"class":641},[551,2151,2152,2155,2157,2159,2162,2164],{"class":553,"line":1084},[551,2153,2154],{"class":637},"      return",[551,2156,1448],{"class":645},[551,2158,813],{"class":641},[551,2160,2161],{"class":757},"send",[551,2163,760],{"class":769},[551,2165,763],{"class":641},[551,2167,2168,2171,2173,2176],{"class":553,"line":1116},[551,2169,2170],{"class":769},"        status",[551,2172,773],{"class":641},[551,2174,2175],{"class":869}," 400",[551,2177,783],{"class":641},[551,2179,2180,2183,2185],{"class":553,"line":1140},[551,2181,2182],{"class":769},"        body",[551,2184,773],{"class":641},[551,2186,794],{"class":641},[551,2188,2189,2192,2194,2196,2199,2201],{"class":553,"line":1145},[551,2190,2191],{"class":769},"          jsonrpc",[551,2193,773],{"class":641},[551,2195,661],{"class":641},[551,2197,2198],{"class":560},"2.0",[551,2200,667],{"class":641},[551,2202,783],{"class":641},[551,2204,2205,2208,2210],{"class":553,"line":1151},[551,2206,2207],{"class":769},"          id",[551,2209,773],{"class":641},[551,2211,2212],{"class":641}," null,\n",[551,2214,2215,2218,2220,2222,2225,2227,2230,2232,2235,2237,2239,2241,2243,2246,2248],{"class":553,"line":1212},[551,2216,2217],{"class":769},"          error",[551,2219,773],{"class":641},[551,2221,642],{"class":641},[551,2223,2224],{"class":769}," code",[551,2226,773],{"class":641},[551,2228,2229],{"class":645}," JsonRpcErrorCode",[551,2231,813],{"class":641},[551,2233,2234],{"class":645},"ParseError",[551,2236,649],{"class":641},[551,2238,2092],{"class":769},[551,2240,773],{"class":641},[551,2242,661],{"class":641},[551,2244,2245],{"class":560},"Parse error: invalid JSON.",[551,2247,667],{"class":641},[551,2249,1584],{"class":641},[551,2251,2252],{"class":553,"line":1218},[551,2253,2254],{"class":641},"        },\n",[551,2256,2258,2261,2263],{"class":553,"line":2257},30,[551,2259,2260],{"class":641},"      }",[551,2262,828],{"class":769},[551,2264,670],{"class":641},[551,2266,2268],{"class":553,"line":2267},31,[551,2269,2270],{"class":641},"    }\n",[551,2272,2274],{"class":553,"line":2273},32,[551,2275,738],{"emptyLinePlaceholder":737},[551,2277,2279,2282,2285,2287,2290,2293,2295,2298,2301,2303,2305,2308,2310,2312,2315,2318],{"class":553,"line":2278},33,[551,2280,2281],{"class":747},"    const",[551,2283,2284],{"class":645}," server",[551,2286,2118],{"class":641},[551,2288,2289],{"class":641}," new",[551,2291,2292],{"class":757}," McpServer",[551,2294,760],{"class":769},[551,2296,2297],{"class":641},"this.",[551,2299,2300],{"class":645},"generator",[551,2302,649],{"class":641},[551,2304,2289],{"class":641},[551,2306,2307],{"class":757}," McpToolDispatcher",[551,2309,760],{"class":769},[551,2311,2297],{"class":641},[551,2313,2314],{"class":645},"internalClient",[551,2316,2317],{"class":769},"))",[551,2319,670],{"class":641},[551,2321,2323,2326,2328,2330,2332,2334,2337,2339,2341,2344,2346,2349,2351,2353,2355,2357,2359],{"class":553,"line":2322},34,[551,2324,2325],{"class":637},"    return",[551,2327,1448],{"class":645},[551,2329,813],{"class":641},[551,2331,2161],{"class":757},[551,2333,760],{"class":769},[551,2335,2336],{"class":637},"await",[551,2338,2284],{"class":645},[551,2340,813],{"class":641},[551,2342,2343],{"class":757},"handle",[551,2345,760],{"class":769},[551,2347,2348],{"class":645},"message",[551,2350,649],{"class":641},[551,2352,2124],{"class":645},[551,2354,813],{"class":641},[551,2356,2129],{"class":645},[551,2358,2317],{"class":769},[551,2360,670],{"class":641},[551,2362,2364],{"class":553,"line":2363},35,[551,2365,2366],{"class":641},"  }\n",[551,2368,2370],{"class":553,"line":2369},36,[551,2371,738],{"emptyLinePlaceholder":737},[551,2373,2375],{"class":553,"line":2374},37,[551,2376,2377],{"class":687},"  \u002F** GET \u002Fmcp — the stateless tier has no server-initiated stream; a GET is 405. *\u002F\n",[551,2379,2381,2383,2385,2388,2390,2393,2395,2397,2399,2401,2403,2405,2407,2409,2411,2413,2415],{"class":553,"line":2380},38,[551,2382,1983],{"class":747},[551,2384,2046],{"class":747},[551,2386,2387],{"class":769}," probe",[551,2389,760],{"class":641},[551,2391,2392],{"class":2000},"_action",[551,2394,773],{"class":641},[551,2396,1877],{"class":557},[551,2398,2061],{"class":641},[551,2400,667],{"class":641},[551,2402,2066],{"class":560},[551,2404,667],{"class":641},[551,2406,2071],{"class":641},[551,2408,2074],{"class":557},[551,2410,2061],{"class":641},[551,2412,2079],{"class":557},[551,2414,2082],{"class":641},[551,2416,794],{"class":641},[551,2418,2420,2422,2424,2426,2428,2430],{"class":553,"line":2419},39,[551,2421,2325],{"class":637},[551,2423,1448],{"class":645},[551,2425,813],{"class":641},[551,2427,2161],{"class":757},[551,2429,760],{"class":769},[551,2431,763],{"class":641},[551,2433,2435,2438,2440,2443],{"class":553,"line":2434},40,[551,2436,2437],{"class":769},"      status",[551,2439,773],{"class":641},[551,2441,2442],{"class":869}," 405",[551,2444,783],{"class":641},[551,2446,2448,2451,2453,2455,2458,2460,2462,2465,2467],{"class":553,"line":2447},41,[551,2449,2450],{"class":769},"      headers",[551,2452,773],{"class":641},[551,2454,642],{"class":641},[551,2456,2457],{"class":769}," allow",[551,2459,773],{"class":641},[551,2461,661],{"class":641},[551,2463,2464],{"class":560},"POST",[551,2466,667],{"class":641},[551,2468,1584],{"class":641},[551,2470,2472,2475,2477],{"class":553,"line":2471},42,[551,2473,2474],{"class":769},"      body",[551,2476,773],{"class":641},[551,2478,794],{"class":641},[551,2480,2482,2485,2487,2489,2491,2493],{"class":553,"line":2481},43,[551,2483,2484],{"class":769},"        jsonrpc",[551,2486,773],{"class":641},[551,2488,661],{"class":641},[551,2490,2198],{"class":560},[551,2492,667],{"class":641},[551,2494,783],{"class":641},[551,2496,2498,2501,2503],{"class":553,"line":2497},44,[551,2499,2500],{"class":769},"        id",[551,2502,773],{"class":641},[551,2504,2212],{"class":641},[551,2506,2508,2511,2513],{"class":553,"line":2507},45,[551,2509,2510],{"class":769},"        error",[551,2512,773],{"class":641},[551,2514,794],{"class":641},[551,2516,2518,2521,2523,2525,2527,2530],{"class":553,"line":2517},46,[551,2519,2520],{"class":769},"          code",[551,2522,773],{"class":641},[551,2524,2229],{"class":645},[551,2526,813],{"class":641},[551,2528,2529],{"class":645},"InvalidRequest",[551,2531,783],{"class":641},[551,2533,2535,2538,2540,2542,2545,2547],{"class":553,"line":2534},47,[551,2536,2537],{"class":769},"          message",[551,2539,773],{"class":641},[551,2541,661],{"class":641},[551,2543,2544],{"class":560},"The MCP endpoint uses POST (stateless Streamable HTTP).",[551,2546,667],{"class":641},[551,2548,783],{"class":641},[551,2550,2552],{"class":553,"line":2551},48,[551,2553,2254],{"class":641},[551,2555,2557],{"class":553,"line":2556},49,[551,2558,2559],{"class":641},"      },\n",[551,2561,2563,2565,2567],{"class":553,"line":2562},50,[551,2564,2144],{"class":641},[551,2566,828],{"class":769},[551,2568,670],{"class":641},[551,2570,2572],{"class":553,"line":2571},51,[551,2573,2366],{"class":641},[551,2575,2577],{"class":553,"line":2576},52,[551,2578,738],{"emptyLinePlaceholder":737},[551,2580,2582,2585,2588,2591,2593,2596,2598,2600,2603,2606],{"class":553,"line":2581},53,[551,2583,2584],{"class":747},"  private",[551,2586,2587],{"class":747}," static",[551,2589,2590],{"class":769}," send",[551,2592,760],{"class":641},[551,2594,2595],{"class":2000},"reply",[551,2597,773],{"class":641},[551,2599,1921],{"class":557},[551,2601,2602],{"class":641},"):",[551,2604,2605],{"class":557}," Response",[551,2607,794],{"class":641},[551,2609,2611,2613,2616,2618,2620,2623,2625,2627,2629,2632,2634],{"class":553,"line":2610},54,[551,2612,2281],{"class":747},[551,2614,2615],{"class":645}," headers",[551,2617,2118],{"class":641},[551,2619,2289],{"class":641},[551,2621,2622],{"class":757}," Headers",[551,2624,760],{"class":769},[551,2626,2595],{"class":645},[551,2628,813],{"class":641},[551,2630,2631],{"class":645},"headers",[551,2633,828],{"class":769},[551,2635,670],{"class":641},[551,2637,2639,2642,2645,2647,2649,2651,2654,2657,2659],{"class":553,"line":2638},55,[551,2640,2641],{"class":637},"    if",[551,2643,2644],{"class":769}," (",[551,2646,2595],{"class":645},[551,2648,813],{"class":641},[551,2650,1059],{"class":645},[551,2652,2653],{"class":641}," ===",[551,2655,2656],{"class":641}," undefined",[551,2658,1223],{"class":769},[551,2660,763],{"class":641},[551,2662,2664,2666,2668,2670,2672,2675,2677,2680,2682,2685,2687,2690,2692,2694,2696,2698],{"class":553,"line":2663},56,[551,2665,2154],{"class":637},[551,2667,2289],{"class":641},[551,2669,2605],{"class":757},[551,2671,760],{"class":769},[551,2673,2674],{"class":641},"null,",[551,2676,642],{"class":641},[551,2678,2679],{"class":769}," status",[551,2681,773],{"class":641},[551,2683,2684],{"class":645}," reply",[551,2686,813],{"class":641},[551,2688,2689],{"class":645},"status",[551,2691,649],{"class":641},[551,2693,2615],{"class":645},[551,2695,655],{"class":641},[551,2697,828],{"class":769},[551,2699,670],{"class":641},[551,2701,2703],{"class":553,"line":2702},57,[551,2704,2270],{"class":641},[551,2706,2708,2711,2713,2716,2718,2720,2723,2725,2727,2729,2732,2734,2736],{"class":553,"line":2707},58,[551,2709,2710],{"class":645},"    headers",[551,2712,813],{"class":641},[551,2714,2715],{"class":757},"set",[551,2717,760],{"class":769},[551,2719,667],{"class":641},[551,2721,2722],{"class":560},"content-type",[551,2724,667],{"class":641},[551,2726,649],{"class":641},[551,2728,661],{"class":641},[551,2730,2731],{"class":560},"application\u002Fjson",[551,2733,667],{"class":641},[551,2735,828],{"class":769},[551,2737,670],{"class":641},[551,2739,2741,2743,2745,2747,2749,2752,2754,2757,2759,2761,2763,2765,2767,2769,2771,2773,2775,2777,2779,2781,2783,2785,2787,2789],{"class":553,"line":2740},59,[551,2742,2325],{"class":637},[551,2744,2289],{"class":641},[551,2746,2605],{"class":757},[551,2748,760],{"class":769},[551,2750,2751],{"class":645},"JSON",[551,2753,813],{"class":641},[551,2755,2756],{"class":757},"stringify",[551,2758,760],{"class":769},[551,2760,2595],{"class":645},[551,2762,813],{"class":641},[551,2764,1059],{"class":645},[551,2766,828],{"class":769},[551,2768,649],{"class":641},[551,2770,642],{"class":641},[551,2772,2679],{"class":769},[551,2774,773],{"class":641},[551,2776,2684],{"class":645},[551,2778,813],{"class":641},[551,2780,2689],{"class":645},[551,2782,649],{"class":641},[551,2784,2615],{"class":645},[551,2786,655],{"class":641},[551,2788,828],{"class":769},[551,2790,670],{"class":641},[551,2792,2794],{"class":553,"line":2793},60,[551,2795,2366],{"class":641},[551,2797,2799],{"class":553,"line":2798},61,[551,2800,2801],{"class":641},"}\n",[499,2803,2804,2807,2808,2811,2812,2814,2815,2817],{},[503,2805,2806],{},"McpToolDispatcher"," dispatches ",[503,2809,2810],{},"tools\u002Fcall"," in-process through the ",[503,2813,1846],{}," — the same request\nchain the HTTP surface uses, with middleware, validation, and auth. The host supplies ",[503,2816,1846],{},"\nautomatically; you declare it as a constructor parameter and the DI graph resolves it.",[533,2819,2821],{"id":2820},"how-tools-are-named","How tools are named",[499,2823,2824,2825,2827,2828,2831,2832,2835,2836,2839,2840,2843,2844,813],{},"The default name is ",[503,2826,1266],{},". The namespace is the last path segment of the contract's\n",[503,2829,2830],{},"prefix"," (cleaned to MCP-safe characters): a contract with ",[503,2833,2834],{},"prefix: \"\u002Fapi\u002Fproducts\""," yields namespace\n",[503,2837,2838],{},"products",", so the ",[503,2841,2842],{},"list"," route becomes ",[503,2845,2846],{},"products.list",[499,2848,2849,2850,2853,2854,2856],{},"Override the name per route with ",[503,2851,2852],{},"mcp({ name: \"my_tool\" })",", globally with the ",[503,2855,1757],{}," generator option,\nor both (per-route wins).",[533,2858,2860],{"id":2859},"schema-conversion-and-exclusions","Schema conversion and exclusions",[499,2862,2863,2864,2867,2868,2871,2872,2875,2876,2879],{},"Tool arguments and output schemas are derived from the route's Standard Schema values via\n",[503,2865,2866],{},"~standard.jsonSchema",". A route whose declared input schema cannot be converted to JSON Schema is ",[1811,2869,2870],{},"excluded\nfrom the manifest"," — the model would have no arguments to call it with, so shipping it argument-blind would\nbe unsafe. The generator records an ",[503,2873,2874],{},"McpGeneratorDiagnostic"," for each excluded route; call\n",[503,2877,2878],{},"generator.diagnostics()"," at boot to surface them.",[541,2881,2883],{"className":627,"code":2882,"filename":1373,"language":630,"meta":547,"style":547},"const generator = new McpServerGenerator({ ... });\n\u002F\u002F Log exclusions at startup so a misconfigured schema surfaces loudly.\nfor (const diagnostic of generator.diagnostics()) {\n  console.warn(diagnostic.message);\n}\n",[503,2884,2885,2913,2918,2945,2968],{"__ignoreMap":547},[551,2886,2887,2890,2893,2896,2898,2900,2902,2904,2907,2909,2911],{"class":553,"line":554},[551,2888,2889],{"class":747},"const",[551,2891,2892],{"class":645}," generator ",[551,2894,2895],{"class":641},"=",[551,2897,2289],{"class":641},[551,2899,1406],{"class":757},[551,2901,760],{"class":645},[551,2903,866],{"class":641},[551,2905,2906],{"class":641}," ...",[551,2908,655],{"class":641},[551,2910,828],{"class":645},[551,2912,670],{"class":641},[551,2914,2915],{"class":553,"line":673},[551,2916,2917],{"class":687},"\u002F\u002F Log exclusions at startup so a misconfigured schema surfaces loudly.\n",[551,2919,2920,2923,2925,2927,2930,2933,2935,2937,2940,2943],{"class":553,"line":691},[551,2921,2922],{"class":637},"for",[551,2924,2644],{"class":645},[551,2926,2889],{"class":747},[551,2928,2929],{"class":645}," diagnostic ",[551,2931,2932],{"class":641},"of",[551,2934,2001],{"class":645},[551,2936,813],{"class":641},[551,2938,2939],{"class":757},"diagnostics",[551,2941,2942],{"class":645},"()) ",[551,2944,763],{"class":641},[551,2946,2947,2950,2952,2955,2957,2960,2962,2964,2966],{"class":553,"line":734},[551,2948,2949],{"class":645},"  console",[551,2951,813],{"class":641},[551,2953,2954],{"class":757},"warn",[551,2956,760],{"class":769},[551,2958,2959],{"class":645},"diagnostic",[551,2961,813],{"class":641},[551,2963,2348],{"class":645},[551,2965,828],{"class":769},[551,2967,670],{"class":641},[551,2969,2970],{"class":553,"line":741},[551,2971,2801],{"class":641},[499,2973,2974,2975,2977,2978,2981],{},"To use a different validator library, supply a custom converter via the ",[503,2976,1744],{}," option (for example,\nZod v4's ",[503,2979,2980],{},"zod.toJSONSchema()",").",[533,2983,2985],{"id":2984},"expose-resources","Expose resources",[499,2987,2988,2989,2991,2992,2995,2996,2998,2999,3002,3003,3005,3006,3009],{},"A ",[503,2990,1304],{}," route marked with ",[503,2993,2994],{},"mcp({ resource: true })"," is also exposed as an MCP ",[1811,2997,1337],{}," (readable by\nURI). A GET with no path params becomes a fixed ",[503,3000,3001],{},"Resource","; one with path params (e.g. ",[503,3004,914],{},") becomes a\n",[503,3007,3008],{},"ResourceTemplate"," (RFC 6570 URI template). Resources are read-only snapshots — subscriptions are not\nsupported in the stateless tier.",[541,3011,3013],{"className":627,"code":3012,"language":630,"meta":547,"style":547},"\u002F\u002F A fixed resource: mcp:\u002F\u002Fresource\u002Fapi\u002Fproducts\nlist: Route.get(\"\u002F\").mcp({ resource: true }).responses({ 200: productList }),\n\n\u002F\u002F A resource template: mcp:\u002F\u002Fresource\u002Fapi\u002Fproducts\u002F{sku}\nfind: Route.get(\"\u002F:sku\").pathParams(productParams).mcp({ resource: true }).responses({ 200: product }),\n",[503,3014,3015,3020,3080,3084,3089],{"__ignoreMap":547},[551,3016,3017],{"class":553,"line":554},[551,3018,3019],{"class":687},"\u002F\u002F A fixed resource: mcp:\u002F\u002Fresource\u002Fapi\u002Fproducts\n",[551,3021,3022,3024,3026,3028,3030,3032,3034,3036,3038,3040,3042,3044,3046,3048,3050,3052,3054,3056,3058,3060,3062,3064,3066,3068,3070,3072,3074,3076,3078],{"class":553,"line":673},[551,3023,2842],{"class":557},[551,3025,773],{"class":641},[551,3027,652],{"class":645},[551,3029,813],{"class":641},[551,3031,816],{"class":757},[551,3033,760],{"class":645},[551,3035,667],{"class":641},[551,3037,823],{"class":560},[551,3039,667],{"class":641},[551,3041,828],{"class":645},[551,3043,813],{"class":641},[551,3045,849],{"class":757},[551,3047,760],{"class":645},[551,3049,866],{"class":641},[551,3051,963],{"class":769},[551,3053,773],{"class":641},[551,3055,969],{"class":968},[551,3057,655],{"class":641},[551,3059,828],{"class":645},[551,3061,813],{"class":641},[551,3063,861],{"class":757},[551,3065,760],{"class":645},[551,3067,866],{"class":641},[551,3069,870],{"class":869},[551,3071,773],{"class":641},[551,3073,875],{"class":645},[551,3075,878],{"class":641},[551,3077,828],{"class":645},[551,3079,783],{"class":641},[551,3081,3082],{"class":553,"line":691},[551,3083,738],{"emptyLinePlaceholder":737},[551,3085,3086],{"class":553,"line":734},[551,3087,3088],{"class":687},"\u002F\u002F A resource template: mcp:\u002F\u002Fresource\u002Fapi\u002Fproducts\u002F{sku}\n",[551,3090,3091,3094,3096,3098,3100,3102,3104,3106,3108,3110,3112,3114,3116,3119,3121,3123,3125,3127,3129,3131,3133,3135,3137,3139,3141,3143,3145,3147,3149,3151,3153,3155],{"class":553,"line":741},[551,3092,3093],{"class":557},"find",[551,3095,773],{"class":641},[551,3097,652],{"class":645},[551,3099,813],{"class":641},[551,3101,816],{"class":757},[551,3103,760],{"class":645},[551,3105,667],{"class":641},[551,3107,914],{"class":560},[551,3109,667],{"class":641},[551,3111,828],{"class":645},[551,3113,813],{"class":641},[551,3115,946],{"class":757},[551,3117,3118],{"class":645},"(productParams)",[551,3120,813],{"class":641},[551,3122,849],{"class":757},[551,3124,760],{"class":645},[551,3126,866],{"class":641},[551,3128,963],{"class":769},[551,3130,773],{"class":641},[551,3132,969],{"class":968},[551,3134,655],{"class":641},[551,3136,828],{"class":645},[551,3138,813],{"class":641},[551,3140,861],{"class":757},[551,3142,760],{"class":645},[551,3144,866],{"class":641},[551,3146,870],{"class":869},[551,3148,773],{"class":641},[551,3150,991],{"class":645},[551,3152,878],{"class":641},[551,3154,828],{"class":645},[551,3156,783],{"class":641},[533,3158,3160],{"id":3159},"protocol-details","Protocol details",[499,3162,3163,3164,3167,3168,3171],{},"The server speaks ",[1811,3165,3166],{},"stateless Streamable HTTP"," (MCP 2025-11-25): every JSON-RPC message is a single POST\nbody, the response is synchronous JSON, and notifications are acknowledged with a ",[503,3169,3170],{},"202"," empty body. JSON-RPC\nbatching is not supported (removed in that spec revision).",[499,3173,1229,3174,3177,3178,3181,3182,3185,3186,3189],{},[503,3175,3176],{},"MCP-Protocol-Version"," request header is\nvalidated; a mismatched version returns a ",[503,3179,3180],{},"400",". Set ",[503,3183,3184],{},"allowedOrigins"," on ",[503,3187,3188],{},"McpServerOptions"," for\nbrowser-facing deployments (DNS-rebinding guard):",[541,3191,3193],{"className":627,"code":3192,"language":630,"meta":547,"style":547},"const server = new McpServer(generator, dispatcher, {\n  allowedOrigins: [\"https:\u002F\u002Fclaude.ai\", \"https:\u002F\u002Fapp.example.com\"],\n});\n",[503,3194,3195,3220,3251],{"__ignoreMap":547},[551,3196,3197,3199,3202,3204,3206,3208,3211,3213,3216,3218],{"class":553,"line":554},[551,3198,2889],{"class":747},[551,3200,3201],{"class":645}," server ",[551,3203,2895],{"class":641},[551,3205,2289],{"class":641},[551,3207,2292],{"class":757},[551,3209,3210],{"class":645},"(generator",[551,3212,649],{"class":641},[551,3214,3215],{"class":645}," dispatcher",[551,3217,649],{"class":641},[551,3219,794],{"class":641},[551,3221,3222,3225,3227,3230,3232,3235,3237,3239,3241,3244,3246,3249],{"class":553,"line":673},[551,3223,3224],{"class":769},"  allowedOrigins",[551,3226,773],{"class":641},[551,3228,3229],{"class":645}," [",[551,3231,667],{"class":641},[551,3233,3234],{"class":560},"https:\u002F\u002Fclaude.ai",[551,3236,667],{"class":641},[551,3238,649],{"class":641},[551,3240,661],{"class":641},[551,3242,3243],{"class":560},"https:\u002F\u002Fapp.example.com",[551,3245,667],{"class":641},[551,3247,3248],{"class":645},"]",[551,3250,783],{"class":641},[551,3252,3253,3255,3257],{"class":553,"line":691},[551,3254,878],{"class":641},[551,3256,828],{"class":645},[551,3258,670],{"class":641},[533,3260,3262],{"id":3261},"see-also","See also",[3264,3265,3266,3280,3285,3290],"ul",{},[3267,3268,3269,3272,3273,3275,3276,3279],"li",{},[3270,3271,67],"a",{"href":68}," — author the ",[503,3274,512],{}," + ",[503,3277,3278],{},"Route"," table the tool manifest is generated\nfrom, the single source of truth shared by the HTTP server and the MCP surface.",[3267,3281,3282,3284],{},[3270,3283,199],{"href":200}," — generate an OpenAPI 3.1 document from the same contract at runtime; the\ncontract-only sibling of MCP generation.",[3267,3286,3287,3289],{},[3270,3288,57],{"href":58}," — the controller pattern the thin MCP controller follows.",[3267,3291,3292,3300,3301,3303,3304,3306,3307,3310,3311,3314],{},[3270,3293,3297],{"href":3294,"rel":3295},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fgap\u002Fopenapi-mcp",[3296],"nofollow",[1811,3298,3299],{},"OpenAPI + MCP"," — a products API\nwith ",[503,3302,527],{},"-marked routes, a ",[503,3305,523],{}," wired via ",[503,3308,3309],{},"useFactory",", the controller pattern above,\nand a ",[503,3312,3313],{},"McpChallengeMiddleware"," for JWT-based auth at the connection level.",[3316,3317,3318],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":547,"searchDepth":673,"depth":673,"links":3320},[3321,3322,3324,3325,3326,3327,3328,3329,3330],{"id":535,"depth":673,"text":536},{"id":610,"depth":673,"text":3323},"Opt routes in with .mcp()",{"id":1351,"depth":673,"text":1352},{"id":1830,"depth":673,"text":1831},{"id":2820,"depth":673,"text":2821},{"id":2859,"depth":673,"text":2860},{"id":2984,"depth":673,"text":2985},{"id":3159,"depth":673,"text":3160},{"id":3261,"depth":673,"text":3262},"Derive a Model Context Protocol server from a Contract's route table at runtime with McpServerGenerator — per-route .mcp() opt-in, marked or all selection, in-process tool execution, and stateless Streamable HTTP.","md",null,{},{"icon":207},{"title":204,"description":3331},"lU44OpbAzVwlrY2BY_PQqGLwr1UGkq2kvtqVH8l3oGU",[3339,3341],{"title":199,"path":200,"stem":201,"description":3340,"icon":202,"children":-1},"Generate an OpenAPI 3.1 document from your Contract route tables at runtime with OpenApiGenerator, register security schemes manually with the SecurityScheme factory, and serve Scalar or Swagger UI inline.",{"title":209,"path":210,"stem":211,"description":3342,"icon":212,"children":-1},"Author request and response shapes with SchemaObject and SchemaArray — one class that is both the validated TypeScript type and a Standard Schema value, with partial, pick, omit, and extend derivations.",1783300761903]