StaticupgradeUpgrade a running Nest application with a stateless MCP endpoint.
Scans the application container for methods decorated with McpRoute, then registers a catch-all HTTP route at the configured path. Each incoming request builds a fresh MCP server + transport on demand, wires the registered tools into it, and delegates handling.
Must be called after NestFactory.create(...) but before app.listen(...)
if you want the MCP endpoint to be reachable alongside your regular HTTP
routes.
Running Nest application instance.
Transport and identity overrides.
contracts/common.md#principled-implementation Tools are collected once from the prototype chain of every controller instance by the nestia/McpRoute metadata, with the first definition of a property name winning and accessors skipped without execution, duplicates by tool name refused before serving, and each call runs through NestJS's ExternalContextCreator so guards, interceptors, pipes, and exception filters apply as for an HTTP route; every request gets a fresh MCP server and Streamable HTTP transport, which stateless mode requires, and both are closed in a finally.
contracts/common.md#clear-and-simple-design One entry point does discovery and registration; the per-tool call (createHandler), the duplicate check, the SDK loader, and the per-request response facade are separate module-private functions.
contracts/common.md#prohibited-implementation-shortcuts Reading the module graph goes through the internal app.container, because INestApplication exposes no public accessor for it, create_external_context_creator constructs an owned subclass through the Nest constructor and overrides module selection on that type, because the default looks for provider classes while controllers belong to the controller collection, and get_request_context_id registers the request provider on the request object as NestJS's router does for an HTTP route, and a per-request response facade forwards native state, events and method receivers without replacing raw methods. After a tool or its exception filter has sent headers, only the facade suppresses subsequent transport writes and preserves callbacks and chaining. Native transport writes do not themselves activate takeover. The remaining foreign-internal reads are the application container and Nest request context registration; the MCP SDK uses its public Node response injection boundary.
MCP (Model Context Protocol) adaptor.
McpAdaptorexposes every method decorated with McpRoute as an MCP tool, reachable by LLM clients through a stateless Streamable HTTP endpoint.At bootstrap the adaptor walks the NestContainer, collects every controller method carrying
"nestia/McpRoute"metadata, and caches a tool registry. A fresh MCP server and transport pair is spun up per incoming HTTP request, following MCP stateless Streamable HTTP mode. This adaptor intentionally does not manageMcp-Session-Idstate.Typia-generated JSON Schemas flow through unchanged; the Zod-based high-level registration API of
McpServeris bypassed by accessing the low-level.serverhandler.A tool call passes the guards, interceptors, pipes, and exception filters NestJS applies to an HTTP route on the same method, with the MCP HTTP request as the execution context. The endpoint is mounted at
pathas given, outside the application's global prefix.Error mapping follows the MCP specification:
-32601.-32602with structured diagnostics.isError: true, so the LLM can read the message and recover.-32603.Author
wildduck - https://github.com/wildduck2
Example