@modelcontextprotocol/server 2.0.0-alpha.3 → 2.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +5 -2
  2. package/dist/{ajvProvider-Birb50r-.mjs → ajvProvider-BQMcjynJ.mjs} +952 -154
  3. package/dist/ajvProvider-BQMcjynJ.mjs.map +1 -0
  4. package/dist/{ajvProvider-DZ_siXcF.d.mts → ajvProvider-Dzgk80kq.d.mts} +58 -11
  5. package/dist/ajvProvider-Dzgk80kq.d.mts.map +1 -0
  6. package/dist/{cfWorkerProvider-BrJKpSFH.mjs → cfWorkerProvider-BDC2rVl3.mjs} +21 -5
  7. package/dist/cfWorkerProvider-BDC2rVl3.mjs.map +1 -0
  8. package/dist/{cfWorkerProvider-DUhk5Ewx.d.mts → cfWorkerProvider-DmvjVsvQ.d.mts} +13 -6
  9. package/dist/cfWorkerProvider-DmvjVsvQ.d.mts.map +1 -0
  10. package/dist/{transport-DMKhEchd.d.mts → createMcpHandler-Du3hjXvf.d.mts} +5283 -1559
  11. package/dist/createMcpHandler-Du3hjXvf.d.mts.map +1 -0
  12. package/dist/index.d.mts +167 -2015
  13. package/dist/index.d.mts.map +1 -1
  14. package/dist/index.mjs +1238 -1281
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/mcp-JttQJlI9.mjs +9998 -0
  17. package/dist/mcp-JttQJlI9.mjs.map +1 -0
  18. package/dist/shimsNode.d.mts +1 -1
  19. package/dist/shimsNode.mjs +1 -1
  20. package/dist/shimsWorkerd.d.mts +1 -1
  21. package/dist/shimsWorkerd.mjs +1 -1
  22. package/dist/stdio.d.mts +61 -3
  23. package/dist/stdio.d.mts.map +1 -1
  24. package/dist/stdio.mjs +457 -2
  25. package/dist/stdio.mjs.map +1 -1
  26. package/dist/types-DBYdVs-n.d.mts +1099 -0
  27. package/dist/types-DBYdVs-n.d.mts.map +1 -0
  28. package/dist/validators/ajv.d.mts +1 -1
  29. package/dist/validators/ajv.mjs +1 -1
  30. package/dist/validators/cfWorker.d.mts +1 -1
  31. package/dist/validators/cfWorker.mjs +1 -1
  32. package/package.json +3 -6
  33. package/dist/ajvProvider-Birb50r-.mjs.map +0 -1
  34. package/dist/ajvProvider-DZ_siXcF.d.mts.map +0 -1
  35. package/dist/cfWorkerProvider-BrJKpSFH.mjs.map +0 -1
  36. package/dist/cfWorkerProvider-DUhk5Ewx.d.mts.map +0 -1
  37. package/dist/src-Pa1iAvsj.mjs +0 -3386
  38. package/dist/src-Pa1iAvsj.mjs.map +0 -1
  39. package/dist/transport-DMKhEchd.d.mts.map +0 -1
  40. package/dist/types-R2RTIcjk.d.mts +0 -66
  41. package/dist/types-R2RTIcjk.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.mjs","names":["_stdin: Readable","_stdout: Writable"],"sources":["../src/server/stdio.ts"],"sourcesContent":["import type { Readable, Writable } from 'node:stream';\n\nimport type { JSONRPCMessage, Transport } from '@modelcontextprotocol/core-internal';\nimport { ReadBuffer, serializeMessage } from '@modelcontextprotocol/core-internal';\nimport { process } from '@modelcontextprotocol/server/_shims';\n\n/**\n * Server transport for stdio: this communicates with an MCP client by reading from the current process' `stdin` and writing to `stdout`.\n *\n * This transport is only available in Node.js environments.\n *\n * @example\n * ```ts source=\"./stdio.examples.ts#StdioServerTransport_basicUsage\"\n * const server = new McpServer({ name: 'my-server', version: '1.0.0' });\n * const transport = new StdioServerTransport();\n * await server.connect(transport);\n * ```\n */\nexport class StdioServerTransport implements Transport {\n private _readBuffer: ReadBuffer;\n private _started = false;\n private _closed = false;\n\n constructor(\n private _stdin: Readable = process.stdin,\n private _stdout: Writable = process.stdout,\n options?: {\n /**\n * Maximum size of the read buffer in bytes. If a single message exceeds\n * this size the transport will emit an error and close.\n *\n * Defaults to 10 MB.\n */\n maxBufferSize?: number;\n }\n ) {\n this._readBuffer = new ReadBuffer({ maxBufferSize: options?.maxBufferSize });\n }\n\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n // Arrow functions to bind `this` properly, while maintaining function identity.\n _ondata = (chunk: Buffer) => {\n try {\n this._readBuffer.append(chunk);\n this.processReadBuffer();\n } catch (error) {\n this.onerror?.(error as Error);\n this.close().catch(() => {});\n }\n };\n _onerror = (error: Error) => {\n this.onerror?.(error);\n };\n _onstdouterror = (error: Error) => {\n this.onerror?.(error);\n this.close().catch(() => {\n // Ignore errors during close — we're already in an error path\n });\n };\n\n /**\n * Starts listening for messages on `stdin`.\n */\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\n 'StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.'\n );\n }\n\n this._started = true;\n this._stdin.on('data', this._ondata);\n this._stdin.on('error', this._onerror);\n this._stdout.on('error', this._onstdouterror);\n }\n\n private processReadBuffer() {\n while (true) {\n try {\n const message = this._readBuffer.readMessage();\n if (message === null) {\n break;\n }\n\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n async close(): Promise<void> {\n if (this._closed) {\n return;\n }\n this._closed = true;\n\n // Remove our event listeners first\n this._stdin.off('data', this._ondata);\n this._stdin.off('error', this._onerror);\n this._stdout.off('error', this._onstdouterror);\n\n // Check if we were the only data listener\n const remainingDataListeners = this._stdin.listenerCount('data');\n if (remainingDataListeners === 0) {\n // Only pause stdin if we were the only listener\n // This prevents interfering with other parts of the application that might be using stdin\n this._stdin.pause();\n }\n\n // Clear the buffer and notify closure\n this._readBuffer.clear();\n this.onclose?.();\n }\n\n send(message: JSONRPCMessage): Promise<void> {\n if (this._closed) {\n return Promise.reject(new Error('StdioServerTransport is closed'));\n }\n return new Promise((resolve, reject) => {\n const json = serializeMessage(message);\n\n let settled = false;\n const onError = (error: Error) => {\n if (settled) return;\n settled = true;\n this._stdout.off('error', onError);\n this._stdout.off('drain', onDrain);\n reject(error);\n };\n const onDrain = () => {\n if (settled) return;\n settled = true;\n this._stdout.off('error', onError);\n this._stdout.off('drain', onDrain);\n resolve();\n };\n\n this._stdout.once('error', onError);\n\n if (this._stdout.write(json)) {\n if (settled) return;\n settled = true;\n this._stdout.off('error', onError);\n resolve();\n } else if (!settled) {\n this._stdout.once('drain', onDrain);\n }\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,IAAa,uBAAb,MAAuD;CACnD,AAAQ;CACR,AAAQ,WAAW;CACnB,AAAQ,UAAU;CAElB,YACI,AAAQA,SAAmB,QAAQ,OACnC,AAAQC,UAAoB,QAAQ,QACpC,SASF;EAXU;EACA;AAWR,OAAK,cAAc,IAAI,WAAW,EAAE,eAAe,SAAS,eAAe,CAAC;;CAGhF;CACA;CACA;CAGA,WAAW,UAAkB;AACzB,MAAI;AACA,QAAK,YAAY,OAAO,MAAM;AAC9B,QAAK,mBAAmB;WACnB,OAAO;AACZ,QAAK,UAAU,MAAe;AAC9B,QAAK,OAAO,CAAC,YAAY,GAAG;;;CAGpC,YAAY,UAAiB;AACzB,OAAK,UAAU,MAAM;;CAEzB,kBAAkB,UAAiB;AAC/B,OAAK,UAAU,MAAM;AACrB,OAAK,OAAO,CAAC,YAAY,GAEvB;;;;;CAMN,MAAM,QAAuB;AACzB,MAAI,KAAK,SACL,OAAM,IAAI,MACN,gHACH;AAGL,OAAK,WAAW;AAChB,OAAK,OAAO,GAAG,QAAQ,KAAK,QAAQ;AACpC,OAAK,OAAO,GAAG,SAAS,KAAK,SAAS;AACtC,OAAK,QAAQ,GAAG,SAAS,KAAK,eAAe;;CAGjD,AAAQ,oBAAoB;AACxB,SAAO,KACH,KAAI;GACA,MAAM,UAAU,KAAK,YAAY,aAAa;AAC9C,OAAI,YAAY,KACZ;AAGJ,QAAK,YAAY,QAAQ;WACpB,OAAO;AACZ,QAAK,UAAU,MAAe;;;CAK1C,MAAM,QAAuB;AACzB,MAAI,KAAK,QACL;AAEJ,OAAK,UAAU;AAGf,OAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ;AACrC,OAAK,OAAO,IAAI,SAAS,KAAK,SAAS;AACvC,OAAK,QAAQ,IAAI,SAAS,KAAK,eAAe;AAI9C,MAD+B,KAAK,OAAO,cAAc,OAAO,KACjC,EAG3B,MAAK,OAAO,OAAO;AAIvB,OAAK,YAAY,OAAO;AACxB,OAAK,WAAW;;CAGpB,KAAK,SAAwC;AACzC,MAAI,KAAK,QACL,QAAO,QAAQ,uBAAO,IAAI,MAAM,iCAAiC,CAAC;AAEtE,SAAO,IAAI,SAAS,SAAS,WAAW;GACpC,MAAM,OAAO,iBAAiB,QAAQ;GAEtC,IAAI,UAAU;GACd,MAAM,WAAW,UAAiB;AAC9B,QAAI,QAAS;AACb,cAAU;AACV,SAAK,QAAQ,IAAI,SAAS,QAAQ;AAClC,SAAK,QAAQ,IAAI,SAAS,QAAQ;AAClC,WAAO,MAAM;;GAEjB,MAAM,gBAAgB;AAClB,QAAI,QAAS;AACb,cAAU;AACV,SAAK,QAAQ,IAAI,SAAS,QAAQ;AAClC,SAAK,QAAQ,IAAI,SAAS,QAAQ;AAClC,aAAS;;AAGb,QAAK,QAAQ,KAAK,SAAS,QAAQ;AAEnC,OAAI,KAAK,QAAQ,MAAM,KAAK,EAAE;AAC1B,QAAI,QAAS;AACb,cAAU;AACV,SAAK,QAAQ,IAAI,SAAS,QAAQ;AAClC,aAAS;cACF,CAAC,QACR,MAAK,QAAQ,KAAK,SAAS,QAAQ;IAEzC"}
1
+ {"version":3,"file":"stdio.mjs","names":["_stdin: Readable","_stdout: Writable","_wire: Transport","_onInstanceClose: () => void","_outboundIntercept?: (message: JSONRPCMessage) => 'handled' | undefined","state: EntryState","discarding: StdioConnectionChannel | undefined","channel: StdioConnectionChannel","queue: JSONRPCMessage[]"],"sources":["../src/server/stdio.ts","../src/server/serveStdio.ts"],"sourcesContent":["import type { Readable, Writable } from 'node:stream';\n\nimport type { JSONRPCMessage, Transport } from '@modelcontextprotocol/core-internal';\nimport { ReadBuffer, serializeMessage } from '@modelcontextprotocol/core-internal';\nimport { process } from '@modelcontextprotocol/server/_shims';\n\n/**\n * Server transport for stdio: this communicates with an MCP client by reading from the current process' `stdin` and writing to `stdout`.\n *\n * This transport is only available in Node.js environments.\n *\n * @example\n * ```ts source=\"./stdio.examples.ts#StdioServerTransport_basicUsage\"\n * const server = new McpServer({ name: 'my-server', version: '1.0.0' });\n * const transport = new StdioServerTransport();\n * await server.connect(transport);\n * ```\n */\nexport class StdioServerTransport implements Transport {\n private _readBuffer: ReadBuffer;\n private _started = false;\n private _closed = false;\n\n constructor(\n private _stdin: Readable = process.stdin,\n private _stdout: Writable = process.stdout,\n options?: {\n /**\n * Maximum size of the read buffer in bytes. If a single message exceeds\n * this size the transport will emit an error and close.\n *\n * Defaults to 10 MB.\n */\n maxBufferSize?: number;\n }\n ) {\n this._readBuffer = new ReadBuffer({ maxBufferSize: options?.maxBufferSize });\n }\n\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n // Arrow functions to bind `this` properly, while maintaining function identity.\n _ondata = (chunk: Buffer) => {\n try {\n this._readBuffer.append(chunk);\n this.processReadBuffer();\n } catch (error) {\n this.onerror?.(error as Error);\n this.close().catch(() => {});\n }\n };\n _onerror = (error: Error) => {\n this.onerror?.(error);\n };\n _onstdouterror = (error: Error) => {\n this.onerror?.(error);\n this.close().catch(() => {\n // Ignore errors during close — we're already in an error path\n });\n };\n\n /**\n * Starts listening for messages on `stdin`.\n */\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\n 'StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.'\n );\n }\n\n this._started = true;\n this._stdin.on('data', this._ondata);\n this._stdin.on('error', this._onerror);\n this._stdout.on('error', this._onstdouterror);\n }\n\n private processReadBuffer() {\n while (true) {\n try {\n const message = this._readBuffer.readMessage();\n if (message === null) {\n break;\n }\n\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n async close(): Promise<void> {\n if (this._closed) {\n return;\n }\n this._closed = true;\n\n // Remove our event listeners first\n this._stdin.off('data', this._ondata);\n this._stdin.off('error', this._onerror);\n this._stdout.off('error', this._onstdouterror);\n\n // Check if we were the only data listener\n const remainingDataListeners = this._stdin.listenerCount('data');\n if (remainingDataListeners === 0) {\n // Only pause stdin if we were the only listener\n // This prevents interfering with other parts of the application that might be using stdin\n this._stdin.pause();\n }\n\n // Clear the buffer and notify closure\n this._readBuffer.clear();\n this.onclose?.();\n }\n\n send(message: JSONRPCMessage): Promise<void> {\n if (this._closed) {\n return Promise.reject(new Error('StdioServerTransport is closed'));\n }\n return new Promise((resolve, reject) => {\n const json = serializeMessage(message);\n\n let settled = false;\n const onError = (error: Error) => {\n if (settled) return;\n settled = true;\n this._stdout.off('error', onError);\n this._stdout.off('drain', onDrain);\n reject(error);\n };\n const onDrain = () => {\n if (settled) return;\n settled = true;\n this._stdout.off('error', onError);\n this._stdout.off('drain', onDrain);\n resolve();\n };\n\n this._stdout.once('error', onError);\n\n if (this._stdout.write(json)) {\n if (settled) return;\n settled = true;\n this._stdout.off('error', onError);\n resolve();\n } else if (!settled) {\n this._stdout.once('drain', onDrain);\n }\n });\n }\n}\n","/**\n * `serveStdio` — the stdio entry point for serving the 2026-07-28 protocol\n * revision on a long-lived connection, with 2025-era serving as the default\n * for clients that open with the `initialize` handshake.\n *\n * The entry owns the stdio transport and the era decision for the connection.\n * It classifies the connection's opening exchange exactly once (using the\n * same body-primary rules as the HTTP entry), constructs ONE server instance\n * from the consumer's factory for the era the client opened with, pins that\n * instance for the lifetime of the connection, and passes every later message\n * straight through to it. No per-message era classification ever runs after\n * the connection is pinned — exactly mirroring how `createMcpHandler`\n * classifies an HTTP request before any instance exists.\n *\n * The opening exchange:\n *\n * - An `initialize` request (or any claim-less message) opens a 2025-era\n * session: the factory builds a legacy instance and the connection is\n * pinned to it (`legacy: 'serve'`, the default). With `legacy: 'reject'`\n * the opening is answered with the unsupported-protocol-version error\n * naming the supported modern revisions instead.\n * - A request carrying a valid per-request `_meta` envelope naming a\n * supported modern revision pins the connection to a modern instance\n * (era-marked and given the modern-only handlers, exactly like the HTTP\n * entry's modern path).\n * - A `server/discover` probe is answered by an optimistically built modern\n * instance but does NOT pin the connection yet: the spec's stdio\n * backward-compatibility flow lets a client probe first and then either\n * continue with modern requests (which pins the connection modern) or fall\n * back to the `initialize` handshake when no mutually supported modern\n * revision exists — in which case the probe instance is discarded and a\n * fresh legacy instance serves the handshake.\n * - Once the modern era is pinned, a later claim-less `initialize` is\n * rejected with the unsupported-protocol-version error naming the supported\n * revisions (the spec recommends naming them in any error returned to\n * `initialize`, and forbids falling back once the modern era is confirmed).\n *\n * Every instance the factory produces serves exactly one era; the ambiguity\n * of the opening exchange lives entirely in this entry. In the probe-fallback\n * case the factory is called twice (once for the discarded probe instance,\n * once for the legacy instance), so factories should be cheap and\n * side-effect-free to construct — the same expectation `createMcpHandler`\n * already sets for per-request construction.\n *\n * Hand-constructed servers connected directly to a `StdioServerTransport`\n * are unaffected by this entry: they keep serving the 2025-era protocol they\n * were written for.\n */\nimport type {\n CancelledNotificationParams,\n JSONRPCMessage,\n JSONRPCNotification,\n JSONRPCRequest,\n MessageClassification,\n MessageExtraInfo,\n RequestId,\n Transport,\n TransportSendOptions\n} from '@modelcontextprotocol/core-internal';\nimport {\n carriesValidModernEnvelopeClaim,\n envelopeClaimVersion,\n hasEnvelopeClaim,\n isJSONRPCErrorResponse,\n isJSONRPCNotification,\n isJSONRPCRequest,\n isJSONRPCResultResponse,\n modernOnlyStrictRejection,\n ProtocolErrorCode,\n requestMetaOf,\n setNegotiatedProtocolVersion,\n SUPPORTED_MODERN_PROTOCOL_VERSIONS,\n UnsupportedProtocolVersionError,\n validateEnvelopeMeta\n} from '@modelcontextprotocol/core-internal';\n\nimport type { McpServerFactory } from './createMcpHandler';\nimport { DEFAULT_MAX_SUBSCRIPTIONS, StdioListenRouter } from './listenRouter';\nimport { McpServer } from './mcp';\nimport type { Server } from './server';\nimport { installModernOnlyHandlers } from './server';\nimport { StdioServerTransport } from './stdio';\n\n/** Options for {@linkcode serveStdio}. */\nexport interface ServeStdioOptions {\n /**\n * How a 2025-era opening (an `initialize` request, or any claim-less\n * message) is handled:\n *\n * - `'serve'` (default) — the connection is pinned to a 2025-era instance\n * from the same factory and served exactly as a hand-wired stdio server\n * serves it today.\n * - `'reject'` — the opening request is answered with the\n * unsupported-protocol-version error naming the supported modern\n * revisions (claim-less notifications are dropped); the connection\n * stays open for a modern opening.\n */\n legacy?: 'serve' | 'reject';\n /**\n * Bring your own transport (for example a `StdioServerTransport`\n * constructed over a Unix domain socket or TCP stream, per the stdio\n * binding's custom-transport guidance). Defaults to a\n * {@linkcode StdioServerTransport} over the current process's stdio. The\n * entry owns the transport: it starts it, receives every inbound message,\n * and closes it when the connection ends.\n */\n transport?: Transport;\n /** Callback for out-of-band errors (reporting only; it never alters what is written to the wire). */\n onerror?: (error: Error) => void;\n /**\n * Reject a new `subscriptions/listen` with `-32603` 'Subscription limit\n * reached' (in-band, before the ack) when this many subscriptions are\n * already open on this connection.\n * @default 1024\n */\n maxSubscriptions?: number;\n}\n\n/** The handle returned by {@linkcode serveStdio}. */\nexport interface StdioServerHandle {\n /** Tears the connection down: closes the pinned instance (if any) and the underlying transport. */\n close(): Promise<void>;\n}\n\n/* ------------------------------------------------------------------------ *\n * Per-instance channel\n * ------------------------------------------------------------------------ */\n\n/**\n * How long the probe-discard path waits for the probe instance to answer the\n * requests it was delivered before closing it. The wait normally settles as\n * soon as the DiscoverResult is handed to the wire (or immediately, when a\n * delivered cancellation already settled the probe); the bound is a backstop\n * so no edge can ever hold the connection's inbound pump indefinitely behind\n * the discard.\n */\nconst DISCARD_ANSWER_TIMEOUT_MS = 3000;\n\n/**\n * The transport a pinned instance is connected to: a thin channel that writes\n * through to the entry-owned wire transport and receives the messages the\n * entry forwards. The wire transport itself is never handed to an instance —\n * that is what lets the entry discard an optimistic probe instance (close the\n * channel) without tearing down the connection.\n */\nclass StdioConnectionChannel implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: <T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void;\n\n private _closed = false;\n /** Request ids the entry delivered to the instance that the instance has not yet answered. */\n private readonly _pendingRequests = new Set<RequestId>();\n private _drainWaiters: Array<() => void> = [];\n\n constructor(\n private readonly _wire: Transport,\n private readonly _onInstanceClose: () => void,\n /**\n * Optional first-look on outbound messages. When set and returning\n * `'handled'`, the channel does not write the message to the wire\n * (the entry already wrote whatever was appropriate). Used by the\n * modern-era listen router to fan a change notification out onto the\n * active subscriptions instead of broadcasting it unsolicited.\n */\n private readonly _outboundIntercept?: (message: JSONRPCMessage) => 'handled' | undefined\n ) {}\n\n async start(): Promise<void> {\n // The entry already started the wire transport; connecting an\n // instance to its channel must not start anything again.\n }\n\n async send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void> {\n if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {\n // The instance answered a delivered request: settle it whether or\n // not the wire write below succeeds (write failures surface\n // through the wire's own error reporting).\n const { id } = message;\n if (id !== undefined) {\n this._settle(id);\n }\n }\n if (this._closed) {\n // A discarded or torn-down instance has nowhere to write; late\n // sends are dropped.\n return;\n }\n if (this._outboundIntercept?.(message) === 'handled') {\n return;\n }\n return this._wire.send(message, options);\n }\n\n setProtocolVersion = (version: string): void => {\n this._wire.setProtocolVersion?.(version);\n };\n\n /** Forwards one inbound message to the connected instance. */\n deliver(message: JSONRPCMessage, extra?: MessageExtraInfo): void {\n if (this._closed) {\n return;\n }\n if (isJSONRPCRequest(message)) {\n this._pendingRequests.add(message.id);\n } else if (isJSONRPCNotification(message) && message.method === 'notifications/cancelled') {\n // By protocol contract a cancelled request may legitimately go\n // unanswered (the instance aborts the in-flight handler and writes\n // nothing for it), so a delivered cancellation settles the request\n // it names: nothing should keep waiting for an answer that may\n // never come. Non-cancelled requests still settle only when their\n // answer is handed to the wire.\n const cancelledId = (message.params as CancelledNotificationParams | undefined)?.requestId;\n if (cancelledId !== undefined) {\n this._settle(cancelledId);\n }\n }\n this.onmessage?.(message, extra);\n }\n\n /**\n * Resolves once every request delivered to the instance has been answered\n * through {@linkcode send}, settled by a delivered cancellation, or the\n * channel has been closed and nothing further can be answered. The wait is\n * bounded by `timeoutMs` as a backstop so no edge can hold the caller\n * indefinitely; resolves `false` only when the bound elapsed with requests\n * still unanswered. Used by the probe-discard path so a probe request the\n * entry accepted is never silently dropped.\n */\n async whenRequestsAnswered(timeoutMs: number): Promise<boolean> {\n if (this._closed || this._pendingRequests.size === 0) {\n return true;\n }\n return await new Promise<boolean>(resolve => {\n const waiter = (): void => {\n clearTimeout(timer);\n resolve(true);\n };\n const timer = setTimeout(() => {\n this._drainWaiters = this._drainWaiters.filter(pending => pending !== waiter);\n resolve(false);\n }, timeoutMs);\n this._drainWaiters.push(waiter);\n });\n }\n\n async close(): Promise<void> {\n if (this._closed) {\n return;\n }\n this._closed = true;\n // Nothing further can be answered through a closed channel; release\n // anyone waiting on in-flight answers.\n this._pendingRequests.clear();\n this._releaseDrainWaiters();\n try {\n this._onInstanceClose();\n } finally {\n this.onclose?.();\n }\n }\n\n private _settle(id: RequestId): void {\n this._pendingRequests.delete(id);\n if (this._pendingRequests.size === 0) {\n this._releaseDrainWaiters();\n }\n }\n\n private _releaseDrainWaiters(): void {\n const waiters = this._drainWaiters;\n this._drainWaiters = [];\n for (const waiter of waiters) {\n waiter();\n }\n }\n}\n\n/* ------------------------------------------------------------------------ *\n * Opening-exchange classification\n * ------------------------------------------------------------------------ */\n\ninterface EnvelopeIssue {\n key: string;\n problem: string;\n}\n\ntype OpeningClassification =\n /** A 2025-era opening: `initialize`, or any message without an envelope claim. */\n | { kind: 'legacy'; reason: 'initialize' | 'no-claim'; requestedVersion?: string }\n /** A valid envelope claim naming a modern revision this entry serves. */\n | { kind: 'modern'; revision: string; classification: MessageClassification }\n /** A present envelope claim whose envelope is malformed. */\n | { kind: 'invalid-envelope'; issue: EnvelopeIssue }\n /** A valid envelope claim naming a revision this entry does not serve (unknown future or 2025-era). */\n | { kind: 'unsupported-revision'; requested: string };\n\n/**\n * Classifies one message of the opening exchange with the same body-primary\n * rules the HTTP entry applies per request: `initialize` is the legacy\n * handshake unless it carries a valid modern envelope claim; a present claim\n * is validated (never silently ignored); a claim-less message is 2025-era\n * traffic. There is no header layer on stdio, so the body is the only signal.\n */\nfunction classifyOpeningMessage(message: JSONRPCRequest | JSONRPCNotification): OpeningClassification {\n const params = message.params;\n\n if (message.method === 'initialize' && !carriesValidModernEnvelopeClaim(params)) {\n const requestedVersion =\n params !== null && typeof params === 'object' && typeof (params as { protocolVersion?: unknown }).protocolVersion === 'string'\n ? ((params as { protocolVersion: string }).protocolVersion as string)\n : undefined;\n return { kind: 'legacy', reason: 'initialize', ...(requestedVersion !== undefined && { requestedVersion }) };\n }\n\n if (!hasEnvelopeClaim(params)) {\n return { kind: 'legacy', reason: 'no-claim' };\n }\n\n // A present claim is validated, never silently ignored — a malformed\n // envelope behind the claim is an invalid-params answer, not a fall back\n // to legacy serving (mirrors the HTTP entry's envelope rung).\n const meta = requestMetaOf(params);\n const issues = meta === undefined ? [] : validateEnvelopeMeta(meta);\n const firstIssue = issues[0];\n if (firstIssue !== undefined) {\n return { kind: 'invalid-envelope', issue: firstIssue };\n }\n\n const claimedVersion = envelopeClaimVersion(params);\n if (claimedVersion === undefined || !SUPPORTED_MODERN_PROTOCOL_VERSIONS.includes(claimedVersion)) {\n // The claim names a revision this entry does not serve (an unknown\n // future revision, or a 2025-era revision delivered via the envelope\n // mechanism) — answered like the HTTP entry's modern path.\n return { kind: 'unsupported-revision', requested: claimedVersion ?? 'unknown' };\n }\n\n return { kind: 'modern', revision: claimedVersion, classification: { era: 'modern', revision: claimedVersion } };\n}\n\n/* ------------------------------------------------------------------------ *\n * The entry\n * ------------------------------------------------------------------------ */\n\ninterface ConnectedInstance {\n product: McpServer | Server;\n channel: StdioConnectionChannel;\n}\n\ntype EntryState =\n /** Waiting for the connection's opening message. */\n | { phase: 'opening' }\n /** A `server/discover` probe was answered; the era is not pinned yet. */\n | { phase: 'probe'; instance: ConnectedInstance }\n /** The connection is pinned to one instance serving one era. */\n | { phase: 'pinned'; era: 'legacy' | 'modern'; instance: ConnectedInstance }\n | { phase: 'closed' };\n\n/**\n * Serves MCP over stdio from a server factory, owning the era decision for\n * the connection: the opening exchange selects the era, ONE instance from the\n * factory is pinned for the connection lifetime, and everything after passes\n * straight through to it. See the module documentation for the opening rules.\n *\n * ```ts\n * import { serveStdio } from '@modelcontextprotocol/server/stdio';\n *\n * serveStdio(() => {\n * const server = new McpServer({ name: 'my-server', version: '1.0.0' }, { capabilities: { tools: {} } });\n * // register tools/resources/prompts once — the same factory serves both eras\n * return server;\n * });\n * ```\n */\nexport function serveStdio(factory: McpServerFactory, options: ServeStdioOptions = {}): StdioServerHandle {\n const legacyMode = options.legacy ?? 'serve';\n const wire = options.transport ?? new StdioServerTransport();\n\n let state: EntryState = { phase: 'opening' };\n /** Channel currently being discarded (its close must not tear the connection down). */\n let discarding: StdioConnectionChannel | undefined;\n let closing = false;\n\n /**\n * Whether the connection has been torn down (`handle.close()` or the wire\n * closing). The opening arms re-check this after every await: a close can\n * race factory construction, and the continuation must neither resurrect\n * the connection state nor keep a late-resolved instance around.\n */\n const isTornDown = (): boolean => closing || state.phase === 'closed';\n\n const reportError = (error: Error) => {\n try {\n options.onerror?.(error);\n } catch {\n // Reporting must never affect the wire.\n }\n };\n\n const writeErrorResponse = (id: RequestId, code: number, message: string, data?: unknown): Promise<void> =>\n wire\n .send({ jsonrpc: '2.0', id, error: { code, message, ...(data !== undefined && { data }) } })\n .catch(error => reportError(toError(error)));\n\n /**\n * Entry-handled `subscriptions/listen` for this connection: holds the\n * active subscriptions, serves inbound listen / cancelled-of-listen\n * before the pinned instance is consulted, and rewrites the instance's\n * outbound change notifications onto the active subscriptions. Only\n * consulted on a modern-pinned connection — on a legacy connection\n * change notifications pass straight through (the 2025 unsolicited\n * delivery model is unchanged).\n */\n const listenRouter = new StdioListenRouter(options.maxSubscriptions ?? DEFAULT_MAX_SUBSCRIPTIONS);\n\n /** Outbound intercept installed on a modern instance's channel. */\n const modernOutboundIntercept = (message: JSONRPCMessage): 'handled' | undefined => {\n if (!isJSONRPCNotification(message)) return undefined;\n const routed = listenRouter.routeOutbound(message);\n if (routed === 'passthrough') return undefined;\n // A subscription-gated change notification on the modern era: one\n // stamped copy per subscription that opted in (an empty array means\n // it is dropped — the modern era never delivers an un-requested\n // change type unsolicited). Nothing else from the instance is\n // affected.\n for (const stamped of routed) {\n void wire.send({ jsonrpc: '2.0', ...stamped }).catch(error => reportError(toError(error)));\n }\n return 'handled';\n };\n\n /**\n * Entry-handled inbound listen routing for a modern-pinned connection.\n * Returns `true` when the message was served at the entry and must NOT\n * be delivered to the pinned instance.\n */\n const tryServeListen = async (message: JSONRPCMessage): Promise<boolean> => {\n if (isJSONRPCRequest(message) && message.method === 'subscriptions/listen') {\n // Entry-handled listen is its own request-handling subsystem; it\n // applies the same per-request envelope rung the instance's\n // `_onrequest` would (method-existence is N/A here — the entry\n // recognized the method — so envelope validation is the first\n // applicable rung) and the same supported-revision check the\n // opening classifier and the HTTP entry apply per request. Reuses\n // the same validators the opening classifier uses.\n const meta = requestMetaOf(message.params);\n const issue = hasEnvelopeClaim(message.params)\n ? (meta === undefined ? [] : validateEnvelopeMeta(meta))[0]\n : { key: '_meta', problem: 'the per-request envelope is required on protocol revision 2026-07-28' };\n const claimedVersion = envelopeClaimVersion(message.params);\n let reply;\n if (issue !== undefined) {\n reply = {\n jsonrpc: '2.0' as const,\n id: message.id,\n error: { code: -32_602, message: `Invalid _meta envelope: ${issue.key}: ${issue.problem}` }\n };\n } else if (claimedVersion === undefined || !SUPPORTED_MODERN_PROTOCOL_VERSIONS.includes(claimedVersion)) {\n const error = new UnsupportedProtocolVersionError({\n supported: [...SUPPORTED_MODERN_PROTOCOL_VERSIONS],\n requested: claimedVersion ?? 'unknown'\n });\n reply = { jsonrpc: '2.0' as const, id: message.id, error: { code: error.code, message: error.message, data: error.data } };\n } else {\n reply = listenRouter.serve(message);\n }\n await wire\n .send('error' in reply ? reply : { jsonrpc: '2.0', method: reply.method, params: reply.params })\n .catch(error => reportError(toError(error)));\n return true;\n }\n if (isJSONRPCNotification(message) && message.method === 'notifications/cancelled') {\n const cancelledId = (message.params as CancelledNotificationParams | undefined)?.requestId;\n // Inbound cancel of a parked listen: tear the subscription down\n // and DO NOT deliver to the instance (it never saw the listen\n // request). After this point nothing further is delivered for\n // that subscription id (post-cancel hardening).\n if (cancelledId !== undefined && listenRouter.cancel(cancelledId)) {\n return true;\n }\n }\n return false;\n };\n\n /** Answers a 2025-era request the entry will not serve (the modern-only rejection cells). */\n const answerLegacyRejection = (\n request: JSONRPCRequest,\n reason: 'initialize' | 'no-claim',\n requestedVersion?: string\n ): Promise<void> => {\n const rejection = modernOnlyStrictRejection(\n { kind: 'legacy', reason, ...(requestedVersion !== undefined && { requestedVersion }) },\n SUPPORTED_MODERN_PROTOCOL_VERSIONS\n );\n if (rejection === undefined) {\n return Promise.resolve();\n }\n reportError(new Error(`Rejected 2025-era request on a modern-only stdio connection (${rejection.cell}): ${rejection.message}`));\n return writeErrorResponse(request.id, rejection.code, rejection.message, rejection.data);\n };\n\n const onInstanceClosed = (channel: StdioConnectionChannel) => {\n if (closing || channel === discarding) {\n return;\n }\n // The pinned (or probe) instance was closed from the instance side:\n // the connection is over.\n void closeAll();\n };\n\n const connectInstance = async (era: 'legacy' | 'modern', revision?: string): Promise<ConnectedInstance> => {\n const product = await factory({ era });\n const server = product instanceof McpServer ? product.server : product;\n if (era === 'modern') {\n // Era-write at instance binding, then modern-only handler\n // installation — the same helpers the HTTP entry's modern path\n // uses, before the instance is connected.\n setNegotiatedProtocolVersion(server, revision);\n installModernOnlyHandlers(server, SUPPORTED_MODERN_PROTOCOL_VERSIONS);\n // The listen router was created before this instance existed; now\n // that capabilities are known, hand them over so the acknowledged\n // filter is narrowed against what the server actually advertises.\n listenRouter.setServerCapabilities(server.getCapabilities());\n }\n const channel: StdioConnectionChannel = new StdioConnectionChannel(\n wire,\n () => onInstanceClosed(channel),\n era === 'modern' ? modernOutboundIntercept : undefined\n );\n await product.connect(channel);\n return { product, channel };\n };\n\n /** Closes an instance whose factory resolved only after the connection was torn down. */\n const disposeLateInstance = (instance: ConnectedInstance): Promise<void> =>\n instance.product.close().catch(error => reportError(toError(error)));\n\n const discardProbeInstance = async (instance: ConnectedInstance): Promise<void> => {\n // The probe instance served only the discover exchange; closing its\n // channel must not tear down the connection the fallback is about to\n // continue on.\n discarding = instance.channel;\n try {\n // A probe request the entry accepted must never go silently\n // unanswered: a client may pipeline its fallback `initialize`\n // straight behind `server/discover` without waiting, and closing\n // the instance aborts whatever it still has in flight. Let the\n // in-flight DiscoverResult reach the wire before the instance is\n // closed; the probe instance only ever receives `server/discover`,\n // whose entry-installed handler always answers promptly. A probe\n // the client cancelled is already settled by the delivered\n // cancellation (a cancelled request may go unanswered), and the\n // wait is bounded as a backstop so nothing can wedge the\n // connection's pump behind the discard.\n const answered = await instance.channel.whenRequestsAnswered(DISCARD_ANSWER_TIMEOUT_MS);\n if (!answered) {\n reportError(\n new Error(\n `Discarded the probe instance with requests still unanswered after ${DISCARD_ANSWER_TIMEOUT_MS}ms; continuing with the fallback`\n )\n );\n }\n await instance.product.close();\n } catch (error) {\n reportError(toError(error));\n } finally {\n discarding = undefined;\n }\n };\n\n const processMessage = async (message: JSONRPCMessage): Promise<void> => {\n if (state.phase === 'closed') {\n return;\n }\n\n if (state.phase === 'pinned') {\n if (\n state.era === 'modern' &&\n isJSONRPCRequest(message) &&\n message.method === 'initialize' &&\n !carriesValidModernEnvelopeClaim(message.params)\n ) {\n // The modern era is confirmed for this connection; a late\n // legacy handshake is answered with the version error naming\n // the supported revisions (the specification recommends\n // naming them in any error returned to `initialize`, and\n // rules out falling back once the modern era is confirmed).\n const requestedVersion =\n message.params !== null &&\n typeof message.params === 'object' &&\n typeof (message.params as { protocolVersion?: unknown }).protocolVersion === 'string'\n ? ((message.params as { protocolVersion: string }).protocolVersion as string)\n : undefined;\n await answerLegacyRejection(message, 'initialize', requestedVersion);\n return;\n }\n if (state.era === 'modern' && (await tryServeListen(message))) {\n return;\n }\n state.instance.channel.deliver(message);\n return;\n }\n\n // Negotiation window ('opening' | 'probe').\n if (!isJSONRPCRequest(message) && !isJSONRPCNotification(message)) {\n // A JSON-RPC response before any era is pinned: nothing has been\n // asked of the client yet, so there is nothing it can answer.\n reportError(new Error('Discarded a JSON-RPC response received before the connection negotiated an era'));\n return;\n }\n\n const opening = classifyOpeningMessage(message);\n switch (opening.kind) {\n case 'invalid-envelope': {\n const detail = `Invalid _meta envelope for protocol revision 2026-07-28: ${opening.issue.key}: ${opening.issue.problem}`;\n if (isJSONRPCRequest(message)) {\n await writeErrorResponse(message.id, ProtocolErrorCode.InvalidParams, detail, { envelope: opening.issue });\n } else {\n reportError(new Error(`Discarded a notification with a malformed envelope: ${detail}`));\n }\n return;\n }\n case 'unsupported-revision': {\n if (isJSONRPCRequest(message)) {\n const error = new UnsupportedProtocolVersionError({\n supported: [...SUPPORTED_MODERN_PROTOCOL_VERSIONS],\n requested: opening.requested\n });\n reportError(error);\n await writeErrorResponse(message.id, error.code, error.message, error.data);\n } else {\n reportError(new Error(`Discarded a notification claiming unsupported protocol revision ${opening.requested}`));\n }\n return;\n }\n case 'modern': {\n if (isJSONRPCRequest(message) && message.method === 'server/discover') {\n if (state.phase === 'probe') {\n // A repeated probe is answered by the same optimistic\n // instance and the negotiation window stays open: only\n // a non-discover enveloped request commits the\n // connection to the modern era, so a later fallback\n // `initialize` is still served by a fresh legacy\n // instance.\n state.instance.channel.deliver(message, { classification: opening.classification });\n return;\n }\n // Probe: answer from an optimistically built modern\n // instance so the advertisement reflects the real server\n // definition, but do not pin the connection yet — the\n // client may still fall back to `initialize` when it\n // shares no modern revision with the advertisement.\n const instance = await connectInstance('modern', opening.revision);\n if (isTornDown()) {\n // The connection was torn down while the factory was\n // building the probe instance: dispose of it and stay\n // closed instead of resurrecting the negotiation\n // window; nothing is delivered or answered.\n await disposeLateInstance(instance);\n return;\n }\n state = { phase: 'probe', instance };\n instance.channel.deliver(message, { classification: opening.classification });\n return;\n }\n if (state.phase === 'probe') {\n if (isJSONRPCNotification(message)) {\n // An enveloped notification during the negotiation\n // window (for example a notifications/cancelled for\n // the probe itself) is delivered to the probe instance\n // without committing the era: only a non-discover\n // enveloped request pins the connection, so a later\n // fallback `initialize` is still served by a fresh\n // legacy instance.\n state.instance.channel.deliver(message, { classification: opening.classification });\n return;\n }\n // The probe was followed by a modern request: the client\n // committed to the modern era — pin the probe instance.\n state = { phase: 'pinned', era: 'modern', instance: state.instance };\n } else {\n const instance = await connectInstance('modern', opening.revision);\n if (isTornDown()) {\n // Closed while the factory was building the modern\n // instance: dispose of it and stay closed.\n await disposeLateInstance(instance);\n return;\n }\n state = { phase: 'pinned', era: 'modern', instance };\n }\n if (await tryServeListen(message)) {\n return;\n }\n state.instance.channel.deliver(message, { classification: opening.classification });\n return;\n }\n case 'legacy': {\n if (legacyMode === 'reject') {\n if (isJSONRPCRequest(message)) {\n await answerLegacyRejection(message, opening.reason, opening.requestedVersion);\n }\n // Claim-less notifications are accepted and dropped (the\n // stdio analog of the HTTP entry's 202-and-drop); the\n // connection stays open for a modern opening.\n return;\n }\n if (state.phase === 'probe') {\n // Probe-then-fallback: the client probed, found no\n // mutually supported modern revision, and fell back to\n // the 2025 handshake on the same connection. The probe\n // instance is discarded; a fresh legacy instance serves\n // the handshake.\n await discardProbeInstance(state.instance);\n if (isTornDown()) {\n // Closed while the probe was being discarded: stay closed.\n return;\n }\n state = { phase: 'opening' };\n }\n const instance = await connectInstance('legacy');\n if (isTornDown()) {\n // Closed while the factory was building the legacy\n // instance: dispose of it and stay closed.\n await disposeLateInstance(instance);\n return;\n }\n state = { phase: 'pinned', era: 'legacy', instance };\n state.instance.channel.deliver(message);\n return;\n }\n }\n };\n\n // Inbound messages are processed strictly in arrival order: the queue\n // absorbs anything that arrives while the opening exchange is still being\n // decided (factory construction and instance connection are async).\n const queue: JSONRPCMessage[] = [];\n let pumping = false;\n const pump = async (): Promise<void> => {\n if (pumping) {\n return;\n }\n pumping = true;\n try {\n while (queue.length > 0) {\n const message = queue.shift()!;\n try {\n await processMessage(message);\n } catch (error) {\n // Every arm of processMessage that answers a request does\n // so through writeErrorResponse (which never throws — wire\n // failures are routed to onerror) and returns right after,\n // so an error escaping to here means the request was never\n // answered. Answer it now: a throwing factory or a failed\n // connect during the opening exchange must not leave the\n // client's request hanging (the stdio analog of the HTTP\n // entry's internal-server-error response). Notifications\n // carry no id to answer and are only reported.\n if (isJSONRPCRequest(message)) {\n await writeErrorResponse(message.id, ProtocolErrorCode.InternalError, 'Internal server error');\n }\n reportError(toError(error));\n }\n }\n } finally {\n pumping = false;\n }\n };\n\n const closeAll = async (): Promise<void> => {\n if (closing || state.phase === 'closed') {\n return;\n }\n closing = true;\n const current = state;\n state = { phase: 'closed' };\n // Stdio server-side graceful teardown: emit the empty\n // `subscriptions/listen` JSON-RPC result for every active subscription\n // (the spec's graceful-close signal — `SubscriptionsListenResult`)\n // before the wire is closed, so the client distinguishes graceful end\n // from a transport drop.\n for (const result of listenRouter.teardownAll()) {\n await wire.send(result).catch(error => reportError(toError(error)));\n }\n if (current.phase === 'probe' || current.phase === 'pinned') {\n await current.instance.product.close().catch(error => reportError(toError(error)));\n }\n await wire.close().catch(error => reportError(toError(error)));\n };\n\n wire.onmessage = (message: JSONRPCMessage) => {\n queue.push(message);\n void pump();\n };\n wire.onerror = error => {\n reportError(error);\n if (state.phase === 'probe' || state.phase === 'pinned') {\n state.instance.channel.onerror?.(error);\n }\n };\n wire.onclose = () => {\n if (closing || state.phase === 'closed') {\n return;\n }\n closing = true;\n const current = state;\n state = { phase: 'closed' };\n if (current.phase === 'probe' || current.phase === 'pinned') {\n void current.instance.product.close().catch(error => reportError(toError(error)));\n }\n };\n\n const started = wire.start().catch(error => {\n reportError(toError(error));\n throw error;\n });\n // Surface a failed start through onerror (above); close() still resolves.\n started.catch(() => {});\n\n return {\n close: async () => {\n await started.catch(() => {});\n await closeAll();\n }\n };\n}\n\nfunction toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value));\n}\n"],"mappings":"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"}