Interface: McpRouterOptions
Defined in: index.ts:495
Options for configuring the MCP router
Properties
aliases?
optionalaliases?:string[]
Defined in: index.ts:512
Additional HTTP paths where the MCP server is also mounted.
Useful when MCP clients differ in where they connect after OAuth: some
follow the protected-resource resource metadata value as the endpoint,
others always connect to the bare origin (/). Setting aliases: ['/']
serves both without requiring app-level path rewrites.
Example
['/'] // also handle MCP requests at the bare root
apiBaseUrl?
optionalapiBaseUrl?:string
Defined in: index.ts:589
Base URL prepended to relative paths passed to apiCall (paths starting
with /). Tool handlers can then call apiCall('GET', '/resource') without
specifying a host.
Example
'http://localhost:3000/api/v1'
auth?
optionalauth?:McpAuthOptions
Defined in: index.ts:652
OAuth / JWT authentication configuration for the MCP endpoint.
When set, incoming MCP requests must include a valid Bearer token in the
Authorization header — except for publicMethods (by default the
lifecycle handshake of each protocol era: initialize and
server/discover), which bypass verification so a client can complete
the handshake before authenticating. Invalid or missing tokens
receive a 401 response with WWW-Authenticate: Bearer (or
Bearer resource_metadata="..." when resourceMetadataUrl is set, per
RFC 9728). Tokens that fail a requiredScopes check receive 403.
The verified token payload is accessible inside tool handlers via getIdentity. Fine-grained per-tool scope checks can be done with checkScopes.
Examples
Cognito
createMcpRouter(server, {
auth: {
cognitoUserPool: { userPoolId: 'us-east-1_xxx', clientId: 'yyy' },
requiredScopes: ['mcp:access'],
},
});
Custom verifier
createMcpRouter(server, {
auth: {
verifyToken: async (token) => myJwtLib.verify(token),
},
});
bus?
optionalbus?:ServerEventBus
Defined in: index.ts:559
The change-event bus 2026-07-28 subscriptions/listen streams subscribe
to, which McpRouter.notify publishes onto. Defaults to an
in-process bus, which reaches only the streams this process holds: with
several replicas, pass one over a shared pub/sub so a change published by
one replica reaches every client.
createMcpServer?
optionalcreateMcpServer?:McpServerFactory
Defined in: index.ts:550
Per-request factory for the McpServer serving one 2026-07-28 request.
Set it to serve that revision; without it, requests carrying its
per-request envelope get the unsupported-protocol-version error naming the
2025-era revisions this endpoint does serve. Register the same tools here
as on server, so the two eras cannot drift apart.
It cannot default to server: the negotiated revision is instance state,
so one instance serving both eras is pinned to 2026-07-28 by the first
client to speak it, and every 2025-era request after that is answered
-32602 … missing the required _meta envelope at HTTP 200. The SDK's own
serving entries take a factory and call it once per request.
Example
const buildServer = () => {
const mcpServer = new McpServer({ name: 'my-server', version: '1.0.0' });
registerEverything(mcpServer);
return mcpServer;
};
createMcpRouter(buildServer(), { createMcpServer: buildServer });
getApiHeaders?
optionalgetApiHeaders?: (ctx) =>Record<string,string>
Defined in: index.ts:615
Called once per incoming MCP HTTP request. Return a plain object whose
key-value pairs will be merged into the headers of every apiCall made
within that request's tool handlers.
Use this to forward any header from the MCP request — Bearer tokens, API keys, tenant IDs, trace headers, etc. — without coupling tool handlers to a specific authentication scheme.
Parameters
| Parameter | Type |
|---|---|
ctx | Context |
Returns
Record<string, string>
Examples
Forward a Bearer token
getApiHeaders: (ctx) => ({ Authorization: ctx.headers.authorization ?? '' })
Forward an x-api-key header
getApiHeaders: (ctx) => ({ 'x-api-key': ctx.headers['x-api-key'] as string })
Inject a static service-to-service key
getApiHeaders: () => ({ 'x-internal-key': process.env.INTERNAL_API_KEY! })
keepAliveMs?
optionalkeepAliveMs?:number
Defined in: index.ts:567
SSE keepalive interval for 2026-07-28 streams, in milliseconds. Keep it
below the idle timeout of whatever sits in front of the server (a CDN or
load balancer), or a quiet subscriptions/listen stream is cut there.
Default
15000
path?
optionalpath?:string
Defined in: index.ts:500
The HTTP path where the MCP server will be mounted
Default
'/mcp'
sessionIdGenerator?
optionalsessionIdGenerator?: () =>string
Defined in: index.ts:524
Optional session ID generator for stateful MCP servers. When provided, a single shared transport is created and sessions are tracked. When undefined (default), the server operates in stateless mode where each HTTP request uses its own transport instance.
Applies to 2025-era traffic. The 2026-07-28 protocol revision has no
session concept in its core, so requests speaking that revision are always
served statelessly regardless of this option.
Returns
string
streaming?
optionalstreaming?:boolean
Defined in: index.ts:580
Whether the host delivers a response while the handler is still writing
it. Set false on a host that buffers the whole response — AWS Lambda
behind API Gateway, or any serverless runtime without response streaming.
The router then stops every instance it serves from advertising change
notifications (listChanged for tools, prompts and resources, and
resources.subscribe), so a 2026-07-28 subscriptions/listen is
acknowledged and completed at once instead of being held until the
platform's timeout. notify then reaches no client.
Default
true