Skip to content

v2.0.0-alpha.5

Pre-release
Pre-release

Choose a tag to compare

@rinormaloku rinormaloku released this 15 Jul 05:59
· 8 commits to main since this release

MCP-Nest v2 is a ground-up rewrite of how the module works. It's available now as an alpha for testing and feedback. It will be merged after the release of MCP TypeScript SDK v2 currently in beta (https://ts.sdk.modelcontextprotocol.io/v2/). Thus expect the possibility of further breaking changes before a stable 2.0.0.

How to migrate

The easiest and most efficient way to migrate is to ask your agents to do that for you using the migration guide: docs/migration-to-v2.md and or to use context7 with version v2 of the library.

The big architectural change: NestJS microservices under the hood

v1 generated HTTP controllers from an McpModule.forRoot(options) module. v2 replaces that with a real NestJS CustomTransportStrategy:

export const mcp = new McpStrategy({
  name: 'srv',
  version: '1.0.0',
  transports: [new StreamableHttpTransport()],
});

@Module({ controllers: [GreetingController] })
class AppModule {}

const app = await NestFactory.create(AppModule);
mcp.setHttpAdapter(app.getHttpAdapter());
app.connectMicroservice({ strategy: mcp });
await app.startAllMicroservices();
await app.listen(3000);

Every tool, resource, and prompt is now a real @MessagePattern handler on an @McpController() class. That means guards, pipes, interceptors, and exception filters all apply natively — no bespoke auth/validation machinery bolted on top. class-validator DTOs, custom pipes, @UseFilters, RpcException — all work exactly as they do on regular Nest controllers.

📦 Breaking: the OAuth authorization server moved to its own package

McpAuthModule and everything under the old src/authz/ (McpAuthJwtGuard, GitHubOAuthProvider, GoogleOAuthProvider, AzureADOAuthProvider, McpUser, IOAuthStore, JwtTokenService, the TypeORM store, …) now ships as a separate package: @rekog/mcp-nest-auth.

This keeps the core @rekog/mcp-nest free of typeorm, passport, and @nestjs/jwt for everyone who doesn't need a built-in auth server.

npm install @rekog/mcp-nest@2.0.0-alpha.4 @modelcontextprotocol/sdk zod@^4 @nestjs/microservices

# only if you use the built-in OAuth server:
npm install @rekog/mcp-nest-auth@2.0.0-alpha.4

@rekog/mcp-nest-auth depends on @rekog/mcp-nest as a peer — install both. All OAuth-related imports need to be updated to come from @rekog/mcp-nest-auth instead of @rekog/mcp-nest. The OAuth server's behavior and API surface are otherwise unchanged from v1 — this was a packaging move, not a feature rework.

Other notable breaking changes

  • HTTP+SSE transport removed. Streamable HTTP (stateful or stateless) and STDIO are the only transports now.
  • Streamable HTTP is stateless by default, and the flag is renamed: statelessModestatefulMode (inverted default). new StreamableHttpTransport() is now stateless out of the box; opt into sessions with { statefulMode: true }.
  • McpModule is gone — no forRoot/forRootAsync/forFeature. Config lives on new McpStrategy(...); async config is just your own async bootstrap() before connectMicroservice; multi-server support (forFeature) is replaced by named servers (@McpController({ server: 'name' }) + McpStrategy({ server: 'name' })) — see docs/multiple-servers.md.
  • The module-level guards option is gone. Authenticate by putting @UseGuards() on a controller made with the new McpHttpControllerFor(transport) mixin (the replacement for the old McpStreamableHttpService custom-controller pattern). Per-tool enforcement still uses @UseGuards(), now on the @McpController class/method itself.
  • @ToolGuards() decorator removed; use native @UseGuards(). @PublicTool, @ToolScopes, @ToolRoles are unchanged.
  • New peer dependency: @nestjs/microservices (required — it's how the strategy plugs into Nest).
  • Tool/resource/prompt method signatures changed from positional (args, context, request) to @Payload() / @Ctx() ctx: McpContext. The raw HTTP request moves from a 3rd positional arg to ctx.getRawRequest(), or the new @McpRawRequest() param decorator.

New in v2 (didn't exist in v1)

  • Native @UseGuards/@UseInterceptors/@UsePipes on tools, resources, and prompts (real Nest RPC handlers now).
  • First-class NestJS RPC exception filters on capabilities, plus an exported McpExceptionFilter to un-mask handler errors to the agent when you want that.
  • RpcException passthrough — throw new RpcException('msg') surfaces a clean message to the client instead of a masked "Internal server error".
  • McpHttpControllerFor(transport) — turn a transport into a real, ownable Nest controller with the full HTTP pipeline (guards/interceptors/filters/versioning/middleware).
  • @McpRawRequest() and @McpUser() param decorators.
  • Resource-template query params ({?a,b}), and a previously-broken catch-all wildcard ({path*}) now works correctly.
  • Decorator-based multi-server capability isolation via named servers.

Everything else — @Tool/@Resource/@ResourceTemplate/@Prompt options, output schema validation, progress reporting, elicitation, context logging, _meta passthrough, request-scoped DI, and the entire OAuth feature set — carries over with equivalent behavior.

v1 status

v1 moves to a v1 branch and enters security-patch-only maintenance: we'll accept community-contributed security fixes, but no new features or general bug fixes from maintainers going forward. New projects should start on v2. Existing v1 users can stay on v1 as long as they need — just know it won't receive further feature development.

Credit

This work was started by @Manuel-Antunes!

Feedback

This is an alpha — file issues for anything that breaks, feels wrong, or is missing from the migration guide. Docs: docs/migration-to-v2.md · full docs index.

Full Changelog: v1.9.11...v2.0.0-alpha.5