Skip to Content
HeronJS v4 is now available.

Model Context Protocol (MCP)

@heronjs/mcp exposes application services as Model Context Protocol tools, fixed resources, and prompts. It supports HTTP and explicitly configured stdio transport on Node.js 24 or later.

Define a tool catalog

import 'reflect-metadata'; import {Module} from '@heronjs/common'; import {HeronJS} from '@heronjs/core'; import {MCP, Tool} from '@heronjs/mcp'; import {z} from 'zod'; @MCP() class Tools { @Tool({name: 'echo', description: 'Echo text', inputSchema: z.object({text: z.string()})}) async echo(input: {text: string}) { return {content: [{type: 'text' as const, text: input.text}]}; } } @Module({mcps: [Tools]}) class App {} const app = await HeronJS.create({module: App}); // HTTP is the default; app.add({ mcp: {} }) may customize the options. await app.listen({port: 3000, host: '127.0.0.1'}); // Connect an MCP client to http://127.0.0.1:3000/mcp

Transport selection

Omitting runtime and McpOptions.transport selects HTTP. Registering MCP controllers enables the MCP extension with its HTTP defaults. Explicit runtime: { transport: 'stdio' } selects stdio when MCP transport is omitted.

For stdio use HeronJS.create({ module: App, runtime: { transport: 'stdio' } }), app.add({ mcp: { transport: 'stdio' } }), then await app.start(). Never write application diagnostics to stdout in stdio mode; use stderr or Logger. MCP and ACP cannot share process stdio. Call await app.close() for shutdown.

Handler contracts

Resource({ name, uri, mimeType? }) handlers receive a URL and return SDK ReadResourceResult. Prompt({ name, argsSchema, description? }) handlers receive validated arguments and return SDK GetPromptResult. Tools return CallToolResult. Every handler’s second argument is McpContext, containing caller identity, signal and the SDK protocol context. Shared service pools belong in DI; HTTP controller instances are resolved per request. Handle cancellation cooperatively.

HTTP authentication and endpoint policy

HTTP options include path, allowedHosts and allowedOrigins (hostname lists; SDK localhost defaults), publicAccess, verifyToken(token, request), resourceMetadata and authorize(guard, context). A remote bind requires a verifier or explicit publicAccess: true, plus the appropriate Host/Origin allowlists. The token verifier must return SDK AuthInfo with token, clientId, scopes, and expiresAt in epoch seconds. Verify token signatures and claims in that hook; the SDK also checks expiry. Return undefined to reject the token.

Optional resourceMetadata accepts { resource, oauthMetadata, scopesSupported? }, where oauthMetadata is the authorization server metadata. The SDK validates it; metadata is served at /.well-known/oauth-protected-resource followed by the MCP path. Tokens must then identify the matching resource URL. Guard metadata is evaluated against the authenticated identity, or by the configured authorize.

Notifications and limitations

SDK progress/notification APIs are available through context.protocol.mcpReq. Unexpected errors are sanitized. Tool execution failures use isError: true. Outgoing clients, custom WebSocket transports, dynamic catalogs and subscriptions are not supported by this package in 4.0.0.

Multiple catalog endpoints

Declare @MCP('/mcp/search') and @MCP('/mcp/admin') on separate controllers. Each path has its own tool/resource/prompt catalog. Tool names may repeat across paths; duplicate entries within one catalog fail registration. Controllers sharing a path contribute to the same catalog. @MCP() keeps the configured path, defaulting to /mcp.

protocols.mcp.endpoints maps paths to per-endpoint settings such as name, version, verifyToken, allowedHosts, and allowedOrigins. For example, { endpoints: { '/mcp/admin': { verifyToken } } } protects the admin catalog independently. All paths share the application’s HTTP server and retain the SDK’s HTTP transport, schema validation, and authentication handling.

For stdio with several catalogs, select one using { transport: 'stdio', endpoint: '/mcp/search' }. Ambiguous selection fails before consuming stdin. The public decorators are MCP, Tool, Resource, and Prompt.


Based on 4.0.0 release source  (4.0.0).

Last updated on