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

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 (36) hide show
  1. package/README.md +6 -2
  2. package/dist/{src-IKPjmxu7.mjs → ajvProvider-Birb50r-.mjs} +21 -3421
  3. package/dist/ajvProvider-Birb50r-.mjs.map +1 -0
  4. package/dist/ajvProvider-DZ_siXcF.d.mts +983 -0
  5. package/dist/ajvProvider-DZ_siXcF.d.mts.map +1 -0
  6. package/dist/cfWorkerProvider-BrJKpSFH.mjs +954 -0
  7. package/dist/cfWorkerProvider-BrJKpSFH.mjs.map +1 -0
  8. package/dist/cfWorkerProvider-DUhk5Ewx.d.mts +52 -0
  9. package/dist/cfWorkerProvider-DUhk5Ewx.d.mts.map +1 -0
  10. package/dist/chunk-BRhqBsOc.mjs +42 -0
  11. package/dist/index.d.mts +1526 -334
  12. package/dist/index.d.mts.map +1 -1
  13. package/dist/index.mjs +91 -766
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/shimsNode.d.mts +1 -1
  16. package/dist/shimsNode.mjs +1 -1
  17. package/dist/shimsWorkerd.d.mts +1 -1
  18. package/dist/shimsWorkerd.mjs +1 -1
  19. package/dist/shimsWorkerd.mjs.map +1 -1
  20. package/dist/src-Pa1iAvsj.mjs +3386 -0
  21. package/dist/src-Pa1iAvsj.mjs.map +1 -0
  22. package/dist/stdio.d.mts +49 -0
  23. package/dist/stdio.d.mts.map +1 -0
  24. package/dist/stdio.mjs +106 -0
  25. package/dist/stdio.mjs.map +1 -0
  26. package/dist/{index-Bhfkexnj.d.mts → transport-DMKhEchd.d.mts} +636 -1907
  27. package/dist/transport-DMKhEchd.d.mts.map +1 -0
  28. package/dist/types-R2RTIcjk.d.mts +66 -0
  29. package/dist/types-R2RTIcjk.d.mts.map +1 -0
  30. package/dist/validators/ajv.d.mts +2 -0
  31. package/dist/validators/ajv.mjs +4 -0
  32. package/dist/validators/cfWorker.d.mts +2 -0
  33. package/dist/validators/cfWorker.mjs +3 -0
  34. package/package.json +35 -16
  35. package/dist/index-Bhfkexnj.d.mts.map +0 -1
  36. package/dist/src-IKPjmxu7.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as PARSE_ERROR, A as parseJSONRPCMessage, B as ListRootsResultSchema, C as isInitializeRequest, D as isJSONRPCRequest, E as isJSONRPCNotification, F as CreateTaskResultSchema, G as ProtocolErrorCode, H as getResultSchema, I as ElicitResultSchema, J as INVALID_PARAMS, K as DEFAULT_NEGOTIATED_PROTOCOL_VERSION, L as EmptyResultSchema, M as CallToolResultSchema, N as CreateMessageResultSchema, O as isJSONRPCResultResponse, P as CreateMessageResultWithToolsSchema, Q as METHOD_NOT_FOUND, R as GetTaskPayloadResultSchema, S as assertCompleteRequestResourceTemplate, T as isJSONRPCErrorResponse, U as ProtocolError, V as LoggingLevelSchema, W as UrlElicitationRequiredError, X as JSONRPC_VERSION, Y as INVALID_REQUEST, Z as LATEST_PROTOCOL_VERSION, _ as mergeCapabilities, a as standardSchemaToJsonSchema, at as SdkError, b as parseSchema, c as createFetchWithInit, ct as OAuthErrorCode, d as deserializeMessage, et as RELATED_TASK_META_KEY, f as serializeMessage, g as Protocol, h as DEFAULT_REQUEST_TIMEOUT_MSEC, i as promptArgumentsFromStandardSchema, it as resourceUrlFromServerUrl, j as CallToolRequestSchema, k as isTaskAugmentedRequestParams, l as validateAndWarnToolName, m as toArrayAsync, n as CfWorkerJsonSchemaValidator, nt as getDisplayName, o as validateStandardSchema, ot as SdkErrorCode, p as takeResult, q as INTERNAL_ERROR, r as AjvJsonSchemaValidator, rt as checkResourceAllowed, s as UriTemplate, st as OAuthError, t as fromJsonSchema$1, tt as SUPPORTED_PROTOCOL_VERSIONS, u as ReadBuffer, v as extractTaskManagerOptions, w as isInitializedNotification, x as assertCompleteRequestPrompt, y as isTerminal, z as JSONRPCMessageSchema } from "./src-IKPjmxu7.mjs";
2
- import { DefaultJsonSchemaValidator, process } from "@modelcontextprotocol/server/_shims";
1
+ import { $ as LATEST_PROTOCOL_VERSION, A as isTaskAugmentedRequestParams, B as LoggingLevelSchema, C as isInitializeRequest, D as isJSONRPCRequest, E as isJSONRPCNotification, F as CreateMessageResultWithToolsSchema, G as BAGGAGE_META_KEY, H as UnsupportedProtocolVersionError, I as ElicitResultSchema, J as DEFAULT_NEGOTIATED_PROTOCOL_VERSION, K as CLIENT_CAPABILITIES_META_KEY, L as EmptyResultSchema, M as CallToolRequestSchema, N as CallToolResultSchema, O as isJSONRPCResponse, P as CreateMessageResultSchema, Q as JSONRPC_VERSION, R as JSONRPCMessageSchema, S as isCallToolResult, T as isJSONRPCErrorResponse, U as UrlElicitationRequiredError, V as ProtocolError, W as ProtocolErrorCode, X as INVALID_PARAMS, Y as INTERNAL_ERROR, Z as INVALID_REQUEST, _ as validateStandardSchema, a as UriTemplate, at as SUPPORTED_PROTOCOL_VERSIONS, b as assertCompleteRequestPrompt, c as ReadBuffer, ct as getDisplayName, d as serializeMessage, dt as SdkError, et as LOG_LEVEL_META_KEY, f as DEFAULT_REQUEST_TIMEOUT_MSEC, ft as SdkErrorCode, g as standardSchemaToJsonSchema, h as promptArgumentsFromStandardSchema, ht as OAuthErrorCode, i as InMemoryTransport, it as RELATED_TASK_META_KEY, j as parseJSONRPCMessage, k as isJSONRPCResultResponse, l as STDIO_DEFAULT_MAX_BUFFER_SIZE, lt as checkResourceAllowed, m as mergeCapabilities, mt as OAuthError, n as normalizeRawShapeSchema, nt as PARSE_ERROR, o as createFetchWithInit, ot as TRACEPARENT_META_KEY, p as Protocol, pt as SdkHttpError, q as CLIENT_INFO_META_KEY, r as parseSchema, rt as PROTOCOL_VERSION_META_KEY, s as validateAndWarnToolName, st as TRACESTATE_META_KEY, t as fromJsonSchema$1, tt as METHOD_NOT_FOUND, u as deserializeMessage, ut as resourceUrlFromServerUrl, v as isSpecType, w as isInitializedNotification, x as assertCompleteRequestResourceTemplate, y as specTypeSchemas, z as ListRootsResultSchema } from "./src-Pa1iAvsj.mjs";
2
+ import { DefaultJsonSchemaValidator } from "@modelcontextprotocol/server/_shims";
3
3
 
4
4
  //#region src/server/completable.ts
5
5
  const COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
@@ -56,504 +56,6 @@ function getCompleter(schema) {
56
56
  return schema[COMPLETABLE_SYMBOL]?.complete;
57
57
  }
58
58
 
59
- //#endregion
60
- //#region ../core/src/experimental/tasks/helpers.ts
61
- /**
62
- * Experimental task capability assertion helpers.
63
- * WARNING: These APIs are experimental and may change without notice.
64
- *
65
- * @experimental
66
- */
67
- /**
68
- * Asserts that task creation is supported for `tools/call`.
69
- * Used to implement the `assertTaskCapability` or `assertTaskHandlerCapability` abstract methods on Protocol.
70
- *
71
- * @param requests - The task requests capability object
72
- * @param method - The method being checked
73
- * @param entityName - `'Server'` or `'Client'` for error messages
74
- * @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported
75
- *
76
- * @experimental
77
- */
78
- function assertToolsCallTaskCapability(requests, method, entityName) {
79
- if (!requests) throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);
80
- switch (method) {
81
- case "tools/call":
82
- if (!requests.tools?.call) throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation for tools/call (required for ${method})`);
83
- break;
84
- default: break;
85
- }
86
- }
87
- /**
88
- * Asserts that task creation is supported for `sampling/createMessage` or `elicitation/create`.
89
- * Used to implement the `assertTaskCapability` or `assertTaskHandlerCapability` abstract methods on Protocol.
90
- *
91
- * @param requests - The task requests capability object
92
- * @param method - The method being checked
93
- * @param entityName - `'Server'` or `'Client'` for error messages
94
- * @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported
95
- *
96
- * @experimental
97
- */
98
- function assertClientRequestTaskCapability(requests, method, entityName) {
99
- if (!requests) throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);
100
- switch (method) {
101
- case "sampling/createMessage":
102
- if (!requests.sampling?.createMessage) throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation for sampling/createMessage (required for ${method})`);
103
- break;
104
- case "elicitation/create":
105
- if (!requests.elicitation?.create) throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation for elicitation/create (required for ${method})`);
106
- break;
107
- default: break;
108
- }
109
- }
110
-
111
- //#endregion
112
- //#region ../core/src/experimental/tasks/stores/inMemory.ts
113
- /**
114
- * In-memory {@linkcode TaskStore} implementation for development and testing.
115
- * For production, use a database or distributed cache.
116
- * @experimental
117
- */
118
- var InMemoryTaskStore = class {
119
- tasks = /* @__PURE__ */ new Map();
120
- cleanupTimers = /* @__PURE__ */ new Map();
121
- /**
122
- * Generates a unique task ID using Web Crypto API.
123
- */
124
- generateTaskId() {
125
- return crypto.randomUUID().replaceAll("-", "");
126
- }
127
- /** {@inheritDoc TaskStore.createTask} */
128
- async createTask(taskParams, requestId, request, sessionId) {
129
- const taskId = this.generateTaskId();
130
- if (this.tasks.has(taskId)) throw new Error(`Task with ID ${taskId} already exists`);
131
- const actualTtl = taskParams.ttl ?? null;
132
- const createdAt = (/* @__PURE__ */ new Date()).toISOString();
133
- const task = {
134
- taskId,
135
- status: "working",
136
- ttl: actualTtl,
137
- createdAt,
138
- lastUpdatedAt: createdAt,
139
- pollInterval: taskParams.pollInterval ?? 1e3
140
- };
141
- this.tasks.set(taskId, {
142
- task,
143
- request,
144
- requestId,
145
- sessionId
146
- });
147
- if (actualTtl) {
148
- const timer = setTimeout(() => {
149
- this.tasks.delete(taskId);
150
- this.cleanupTimers.delete(taskId);
151
- }, actualTtl);
152
- this.cleanupTimers.set(taskId, timer);
153
- }
154
- return task;
155
- }
156
- /**
157
- * Retrieves a stored task, enforcing session ownership when a sessionId is provided.
158
- * Returns undefined if the task does not exist or belongs to a different session.
159
- */
160
- getStoredTask(taskId, sessionId) {
161
- const stored = this.tasks.get(taskId);
162
- if (!stored) return;
163
- if (sessionId !== void 0 && stored.sessionId !== void 0 && stored.sessionId !== sessionId) return;
164
- return stored;
165
- }
166
- async getTask(taskId, sessionId) {
167
- const stored = this.getStoredTask(taskId, sessionId);
168
- return stored ? { ...stored.task } : null;
169
- }
170
- /** {@inheritDoc TaskStore.storeTaskResult} */
171
- async storeTaskResult(taskId, status, result, sessionId) {
172
- const stored = this.getStoredTask(taskId, sessionId);
173
- if (!stored) throw new Error(`Task with ID ${taskId} not found`);
174
- if (isTerminal(stored.task.status)) throw new Error(`Cannot store result for task ${taskId} in terminal status '${stored.task.status}'. Task results can only be stored once.`);
175
- stored.result = result;
176
- stored.task.status = status;
177
- stored.task.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
178
- if (stored.task.ttl) {
179
- const existingTimer = this.cleanupTimers.get(taskId);
180
- if (existingTimer) clearTimeout(existingTimer);
181
- const timer = setTimeout(() => {
182
- this.tasks.delete(taskId);
183
- this.cleanupTimers.delete(taskId);
184
- }, stored.task.ttl);
185
- this.cleanupTimers.set(taskId, timer);
186
- }
187
- }
188
- /** {@inheritDoc TaskStore.getTaskResult} */
189
- async getTaskResult(taskId, sessionId) {
190
- const stored = this.getStoredTask(taskId, sessionId);
191
- if (!stored) throw new Error(`Task with ID ${taskId} not found`);
192
- if (!stored.result) throw new Error(`Task ${taskId} has no result stored`);
193
- return stored.result;
194
- }
195
- /** {@inheritDoc TaskStore.updateTaskStatus} */
196
- async updateTaskStatus(taskId, status, statusMessage, sessionId) {
197
- const stored = this.getStoredTask(taskId, sessionId);
198
- if (!stored) throw new Error(`Task with ID ${taskId} not found`);
199
- if (isTerminal(stored.task.status)) throw new Error(`Cannot update task ${taskId} from terminal status '${stored.task.status}' to '${status}'. Terminal states (completed, failed, cancelled) cannot transition to other states.`);
200
- stored.task.status = status;
201
- if (statusMessage) stored.task.statusMessage = statusMessage;
202
- stored.task.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
203
- if (isTerminal(status) && stored.task.ttl) {
204
- const existingTimer = this.cleanupTimers.get(taskId);
205
- if (existingTimer) clearTimeout(existingTimer);
206
- const timer = setTimeout(() => {
207
- this.tasks.delete(taskId);
208
- this.cleanupTimers.delete(taskId);
209
- }, stored.task.ttl);
210
- this.cleanupTimers.set(taskId, timer);
211
- }
212
- }
213
- /** {@inheritDoc TaskStore.listTasks} */
214
- async listTasks(cursor, sessionId) {
215
- const PAGE_SIZE = 10;
216
- const filteredTaskIds = [...this.tasks.entries()].filter(([, stored]) => {
217
- if (sessionId === void 0 || stored.sessionId === void 0) return true;
218
- return stored.sessionId === sessionId;
219
- }).map(([taskId]) => taskId);
220
- let startIndex = 0;
221
- if (cursor) {
222
- const cursorIndex = filteredTaskIds.indexOf(cursor);
223
- if (cursorIndex === -1) throw new Error(`Invalid cursor: ${cursor}`);
224
- else startIndex = cursorIndex + 1;
225
- }
226
- const pageTaskIds = filteredTaskIds.slice(startIndex, startIndex + PAGE_SIZE);
227
- return {
228
- tasks: pageTaskIds.map((taskId) => {
229
- return { ...this.tasks.get(taskId).task };
230
- }),
231
- nextCursor: startIndex + PAGE_SIZE < filteredTaskIds.length ? pageTaskIds.at(-1) : void 0
232
- };
233
- }
234
- /**
235
- * Cleanup all timers (useful for testing or graceful shutdown)
236
- */
237
- cleanup() {
238
- for (const timer of this.cleanupTimers.values()) clearTimeout(timer);
239
- this.cleanupTimers.clear();
240
- this.tasks.clear();
241
- }
242
- /**
243
- * Get all tasks (useful for debugging)
244
- */
245
- getAllTasks() {
246
- return [...this.tasks.values()].map((stored) => ({ ...stored.task }));
247
- }
248
- };
249
- /**
250
- * In-memory {@linkcode TaskMessageQueue} implementation for development and testing.
251
- * For production, use Redis or another distributed queue.
252
- * @experimental
253
- */
254
- var InMemoryTaskMessageQueue = class {
255
- queues = /* @__PURE__ */ new Map();
256
- /**
257
- * Generates a queue key from taskId.
258
- * SessionId is intentionally ignored because taskIds are globally unique
259
- * and tasks need to be accessible across HTTP requests/sessions.
260
- */
261
- getQueueKey(taskId, _sessionId) {
262
- return taskId;
263
- }
264
- /**
265
- * Gets or creates a queue for the given task and session.
266
- */
267
- getQueue(taskId, sessionId) {
268
- const key = this.getQueueKey(taskId, sessionId);
269
- let queue = this.queues.get(key);
270
- if (!queue) {
271
- queue = [];
272
- this.queues.set(key, queue);
273
- }
274
- return queue;
275
- }
276
- /**
277
- * Adds a message to the end of the queue for a specific task.
278
- * Atomically checks queue size and throws if maxSize would be exceeded.
279
- * @param taskId The task identifier
280
- * @param message The message to enqueue
281
- * @param sessionId Optional session ID for binding the operation to a specific session
282
- * @param maxSize Optional maximum queue size - if specified and queue is full, throws an error
283
- * @throws Error if maxSize is specified and would be exceeded
284
- */
285
- async enqueue(taskId, message, sessionId, maxSize) {
286
- const queue = this.getQueue(taskId, sessionId);
287
- if (maxSize !== void 0 && queue.length >= maxSize) throw new Error(`Task message queue overflow: queue size (${queue.length}) exceeds maximum (${maxSize})`);
288
- queue.push(message);
289
- }
290
- /**
291
- * Removes and returns the first message from the queue for a specific task.
292
- * @param taskId The task identifier
293
- * @param sessionId Optional session ID for binding the query to a specific session
294
- * @returns The first message, or `undefined` if the queue is empty
295
- */
296
- async dequeue(taskId, sessionId) {
297
- return this.getQueue(taskId, sessionId).shift();
298
- }
299
- /**
300
- * Removes and returns all messages from the queue for a specific task.
301
- * @param taskId The task identifier
302
- * @param sessionId Optional session ID for binding the query to a specific session
303
- * @returns Array of all messages that were in the queue
304
- */
305
- async dequeueAll(taskId, sessionId) {
306
- const key = this.getQueueKey(taskId, sessionId);
307
- const queue = this.queues.get(key) ?? [];
308
- this.queues.delete(key);
309
- return queue;
310
- }
311
- };
312
-
313
- //#endregion
314
- //#region src/experimental/tasks/mcpServer.ts
315
- /**
316
- * Experimental task features for {@linkcode McpServer}.
317
- *
318
- * Access via `server.experimental.tasks`:
319
- * ```typescript
320
- * server.experimental.tasks.registerToolTask('long-running', config, handler);
321
- * ```
322
- *
323
- * @experimental
324
- */
325
- var ExperimentalMcpServerTasks = class {
326
- constructor(_mcpServer) {
327
- this._mcpServer = _mcpServer;
328
- }
329
- registerToolTask(name, config, handler) {
330
- const execution = {
331
- taskSupport: "required",
332
- ...config.execution
333
- };
334
- if (execution.taskSupport === "forbidden") throw new Error(`Cannot register task-based tool '${name}' with taskSupport 'forbidden'. Use registerTool() instead.`);
335
- return this._mcpServer._createRegisteredTool(name, config.title, config.description, config.inputSchema, config.outputSchema, config.annotations, execution, config._meta, handler);
336
- }
337
- };
338
-
339
- //#endregion
340
- //#region src/experimental/tasks/server.ts
341
- /**
342
- * Experimental task features for low-level MCP servers.
343
- *
344
- * Access via `server.experimental.tasks`:
345
- * ```typescript
346
- * const stream = server.experimental.tasks.requestStream(request, options);
347
- * ```
348
- *
349
- * For high-level server usage with task-based tools, use {@linkcode index.McpServer | McpServer}.experimental.tasks instead.
350
- *
351
- * @experimental
352
- */
353
- var ExperimentalServerTasks = class {
354
- constructor(_server) {
355
- this._server = _server;
356
- }
357
- get _module() {
358
- return this._server.taskManager;
359
- }
360
- /**
361
- * Sends a request and returns an AsyncGenerator that yields response messages.
362
- * The generator is guaranteed to end with either a `'result'` or `'error'` message.
363
- *
364
- * This method provides streaming access to request processing, allowing you to
365
- * observe intermediate task status updates for task-augmented requests.
366
- *
367
- * @param request - The request to send (method name determines the result schema)
368
- * @param options - Optional request options (timeout, signal, task creation params, etc.)
369
- * @returns AsyncGenerator that yields {@linkcode ResponseMessage} objects
370
- *
371
- * @experimental
372
- */
373
- requestStream(request, options) {
374
- const resultSchema = getResultSchema(request.method);
375
- return this._module.requestStream(request, resultSchema, options);
376
- }
377
- /**
378
- * Sends a sampling request and returns an AsyncGenerator that yields response messages.
379
- * The generator is guaranteed to end with either a 'result' or 'error' message.
380
- *
381
- * For task-augmented requests, yields 'taskCreated' and 'taskStatus' messages
382
- * before the final result.
383
- *
384
- * @example
385
- * ```typescript
386
- * const stream = server.experimental.tasks.createMessageStream({
387
- * messages: [{ role: 'user', content: { type: 'text', text: 'Hello' } }],
388
- * maxTokens: 100
389
- * }, {
390
- * onprogress: (progress) => {
391
- * // Handle streaming tokens via progress notifications
392
- * console.log('Progress:', progress.message);
393
- * }
394
- * });
395
- *
396
- * for await (const message of stream) {
397
- * switch (message.type) {
398
- * case 'taskCreated':
399
- * console.log('Task created:', message.task.taskId);
400
- * break;
401
- * case 'taskStatus':
402
- * console.log('Task status:', message.task.status);
403
- * break;
404
- * case 'result':
405
- * console.log('Final result:', message.result);
406
- * break;
407
- * case 'error':
408
- * console.error('Error:', message.error);
409
- * break;
410
- * }
411
- * }
412
- * ```
413
- *
414
- * @param params - The sampling request parameters
415
- * @param options - Optional request options (timeout, signal, task creation params, onprogress, etc.)
416
- * @returns AsyncGenerator that yields ResponseMessage objects
417
- *
418
- * @experimental
419
- */
420
- createMessageStream(params, options) {
421
- const clientCapabilities = this._server.getClientCapabilities();
422
- if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) throw new SdkError(SdkErrorCode.CapabilityNotSupported, "Client does not support sampling tools capability.");
423
- if (params.messages.length > 0) {
424
- const lastMessage = params.messages.at(-1);
425
- const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
426
- const hasToolResults = lastContent.some((c) => c.type === "tool_result");
427
- const previousMessage = params.messages.length > 1 ? params.messages.at(-2) : void 0;
428
- const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
429
- const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
430
- if (hasToolResults) {
431
- if (lastContent.some((c) => c.type !== "tool_result")) throw new Error("The last message must contain only tool_result content if any is present");
432
- if (!hasPreviousToolUse) throw new Error("tool_result blocks are not matching any tool_use from the previous message");
433
- }
434
- if (hasPreviousToolUse) {
435
- const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
436
- const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
437
- if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
438
- }
439
- }
440
- return this.requestStream({
441
- method: "sampling/createMessage",
442
- params
443
- }, options);
444
- }
445
- /**
446
- * Sends an elicitation request and returns an AsyncGenerator that yields response messages.
447
- * The generator is guaranteed to end with either a 'result' or 'error' message.
448
- *
449
- * For task-augmented requests (especially URL-based elicitation), yields 'taskCreated'
450
- * and 'taskStatus' messages before the final result.
451
- *
452
- * @example
453
- * ```typescript
454
- * const stream = server.experimental.tasks.elicitInputStream({
455
- * mode: 'url',
456
- * message: 'Please authenticate',
457
- * elicitationId: 'auth-123',
458
- * url: 'https://example.com/auth'
459
- * }, {
460
- * task: { ttl: 300000 } // Task-augmented for long-running auth flow
461
- * });
462
- *
463
- * for await (const message of stream) {
464
- * switch (message.type) {
465
- * case 'taskCreated':
466
- * console.log('Task created:', message.task.taskId);
467
- * break;
468
- * case 'taskStatus':
469
- * console.log('Task status:', message.task.status);
470
- * break;
471
- * case 'result':
472
- * console.log('User action:', message.result.action);
473
- * break;
474
- * case 'error':
475
- * console.error('Error:', message.error);
476
- * break;
477
- * }
478
- * }
479
- * ```
480
- *
481
- * @param params - The elicitation request parameters
482
- * @param options - Optional request options (timeout, signal, task creation params, etc.)
483
- * @returns AsyncGenerator that yields ResponseMessage objects
484
- *
485
- * @experimental
486
- */
487
- elicitInputStream(params, options) {
488
- const clientCapabilities = this._server.getClientCapabilities();
489
- const mode = params.mode ?? "form";
490
- switch (mode) {
491
- case "url":
492
- if (!clientCapabilities?.elicitation?.url) throw new SdkError(SdkErrorCode.CapabilityNotSupported, "Client does not support url elicitation.");
493
- break;
494
- case "form":
495
- if (!clientCapabilities?.elicitation?.form) throw new SdkError(SdkErrorCode.CapabilityNotSupported, "Client does not support form elicitation.");
496
- break;
497
- }
498
- const normalizedParams = mode === "form" && params.mode !== "form" ? {
499
- ...params,
500
- mode: "form"
501
- } : params;
502
- return this.requestStream({
503
- method: "elicitation/create",
504
- params: normalizedParams
505
- }, options);
506
- }
507
- /**
508
- * Gets the current status of a task.
509
- *
510
- * @param taskId - The task identifier
511
- * @param options - Optional request options
512
- * @returns The task status
513
- *
514
- * @experimental
515
- */
516
- async getTask(taskId, options) {
517
- return this._module.getTask({ taskId }, options);
518
- }
519
- /**
520
- * Retrieves the result of a completed task.
521
- *
522
- * @param taskId - The task identifier
523
- * @param options - Optional request options
524
- * @returns The task result. The payload structure matches the result type of the
525
- * original request (e.g., a `tools/call` task returns a `CallToolResult`).
526
- *
527
- * @experimental
528
- */
529
- async getTaskResult(taskId, options) {
530
- return this._module.getTaskResult({ taskId }, GetTaskPayloadResultSchema, options);
531
- }
532
- /**
533
- * Lists tasks with optional pagination.
534
- *
535
- * @param cursor - Optional pagination cursor
536
- * @param options - Optional request options
537
- * @returns List of tasks with optional next cursor
538
- *
539
- * @experimental
540
- */
541
- async listTasks(cursor, options) {
542
- return this._module.listTasks(cursor ? { cursor } : void 0, options);
543
- }
544
- /**
545
- * Cancels a running task.
546
- *
547
- * @param taskId - The task identifier
548
- * @param options - Optional request options
549
- *
550
- * @experimental
551
- */
552
- async cancelTask(taskId, options) {
553
- return this._module.cancelTask({ taskId }, options);
554
- }
555
- };
556
-
557
59
  //#endregion
558
60
  //#region src/server/server.ts
559
61
  /**
@@ -566,10 +68,10 @@ var ExperimentalServerTasks = class {
566
68
  var Server = class extends Protocol {
567
69
  _clientCapabilities;
568
70
  _clientVersion;
71
+ _negotiatedProtocolVersion;
569
72
  _capabilities;
570
73
  _instructions;
571
74
  _jsonSchemaValidator;
572
- _experimental;
573
75
  /**
574
76
  * Callback for when initialization has fully completed (i.e., the client has sent an `notifications/initialized` notification).
575
77
  */
@@ -578,22 +80,22 @@ var Server = class extends Protocol {
578
80
  * Initializes this server with the given name and version information.
579
81
  */
580
82
  constructor(_serverInfo, options) {
581
- super({
582
- ...options,
583
- tasks: extractTaskManagerOptions(options?.capabilities?.tasks)
584
- });
83
+ super(options);
585
84
  this._serverInfo = _serverInfo;
586
85
  this._capabilities = options?.capabilities ? { ...options.capabilities } : {};
587
86
  this._instructions = options?.instructions;
588
87
  this._jsonSchemaValidator = options?.jsonSchemaValidator ?? new DefaultJsonSchemaValidator();
589
- if (options?.capabilities?.tasks) {
590
- const { taskStore, taskMessageQueue, defaultTaskPollInterval, maxTaskQueueSize, ...wireCapabilities } = options.capabilities.tasks;
591
- this._capabilities.tasks = wireCapabilities;
592
- }
593
88
  this.setRequestHandler("initialize", (request) => this._oninitialize(request));
594
89
  this.setNotificationHandler("notifications/initialized", () => this.oninitialized?.());
595
90
  if (this._capabilities.logging) this._registerLoggingHandler();
596
91
  }
92
+ /**
93
+ * Registers the built-in `logging/setLevel` request handler.
94
+ *
95
+ * @deprecated Deprecated as of protocol version 2026-07-28 (SEP-2577).
96
+ * Remains functional during the deprecation window (at least twelve months).
97
+ * Migrate to stderr logging (STDIO servers) or OpenTelemetry.
98
+ */
597
99
  _registerLoggingHandler() {
598
100
  this.setRequestHandler("logging/setLevel", async (request, ctx) => {
599
101
  const transportSessionId = ctx.sessionId || ctx.http?.req?.headers.get("mcp-session-id") || void 0;
@@ -625,17 +127,6 @@ var Server = class extends Protocol {
625
127
  } : void 0
626
128
  };
627
129
  }
628
- /**
629
- * Access experimental features.
630
- *
631
- * WARNING: These APIs are experimental and may change without notice.
632
- *
633
- * @experimental
634
- */
635
- get experimental() {
636
- if (!this._experimental) this._experimental = { tasks: new ExperimentalServerTasks(this) };
637
- return this._experimental;
638
- }
639
130
  _loggingLevels = /* @__PURE__ */ new Map();
640
131
  LOG_LEVEL_SEVERITY = new Map(LoggingLevelSchema.options.map((level, index) => [level, index]));
641
132
  isMessageIgnored = (level, sessionId) => {
@@ -654,36 +145,24 @@ var Server = class extends Protocol {
654
145
  if (!hadLogging && this._capabilities.logging) this._registerLoggingHandler();
655
146
  }
656
147
  /**
657
- * Override request handler registration to enforce server-side validation for `tools/call`.
148
+ * Enforces server-side validation for `tools/call` results regardless of how the
149
+ * handler was registered.
658
150
  */
659
- setRequestHandler(method, handler) {
660
- if (method === "tools/call") {
661
- const wrappedHandler = async (request, ctx) => {
662
- const validatedRequest = parseSchema(CallToolRequestSchema, request);
663
- if (!validatedRequest.success) {
664
- const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
665
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage}`);
666
- }
667
- const { params } = validatedRequest.data;
668
- const result = await Promise.resolve(handler(request, ctx));
669
- if (params.task) {
670
- const taskValidationResult = parseSchema(CreateTaskResultSchema, result);
671
- if (!taskValidationResult.success) {
672
- const errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
673
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
674
- }
675
- return taskValidationResult.data;
676
- }
677
- const validationResult = parseSchema(CallToolResultSchema, result);
678
- if (!validationResult.success) {
679
- const errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
680
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage}`);
681
- }
682
- return validationResult.data;
683
- };
684
- return super.setRequestHandler(method, wrappedHandler);
685
- }
686
- return super.setRequestHandler(method, handler);
151
+ _wrapHandler(method, handler) {
152
+ if (method !== "tools/call") return handler;
153
+ return async (request, ctx) => {
154
+ const validatedRequest = parseSchema(CallToolRequestSchema, request);
155
+ if (!validatedRequest.success) {
156
+ const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
157
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage}`);
158
+ }
159
+ const validationResult = parseSchema(CallToolResultSchema, await handler(request, ctx));
160
+ if (!validationResult.success) {
161
+ const errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
162
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage}`);
163
+ }
164
+ return validationResult.data;
165
+ };
687
166
  }
688
167
  assertCapabilityForMethod(method) {
689
168
  switch (method) {
@@ -746,17 +225,12 @@ var Server = class extends Protocol {
746
225
  case "initialize": break;
747
226
  }
748
227
  }
749
- assertTaskCapability(method) {
750
- assertClientRequestTaskCapability(this._clientCapabilities?.tasks?.requests, method, "Client");
751
- }
752
- assertTaskHandlerCapability(method) {
753
- assertToolsCallTaskCapability(this._capabilities?.tasks?.requests, method, "Server");
754
- }
755
228
  async _oninitialize(request) {
756
229
  const requestedVersion = request.params.protocolVersion;
757
230
  this._clientCapabilities = request.params.capabilities;
758
231
  this._clientVersion = request.params.clientInfo;
759
232
  const protocolVersion = this._supportedProtocolVersions.includes(requestedVersion) ? requestedVersion : this._supportedProtocolVersions[0] ?? LATEST_PROTOCOL_VERSION;
233
+ this._negotiatedProtocolVersion = protocolVersion;
760
234
  this.transport?.setProtocolVersion?.(protocolVersion);
761
235
  return {
762
236
  protocolVersion,
@@ -778,6 +252,14 @@ var Server = class extends Protocol {
778
252
  return this._clientVersion;
779
253
  }
780
254
  /**
255
+ * After initialization has completed, this will be populated with the protocol version negotiated
256
+ * with the client (the version the server responded with during the initialize handshake), or
257
+ * `undefined` before initialization.
258
+ */
259
+ getNegotiatedProtocolVersion() {
260
+ return this._negotiatedProtocolVersion;
261
+ }
262
+ /**
781
263
  * Returns the current server capabilities.
782
264
  */
783
265
  getCapabilities() {
@@ -867,6 +349,13 @@ var Server = class extends Protocol {
867
349
  params: { elicitationId }
868
350
  }, options);
869
351
  }
352
+ /**
353
+ * Requests the list of roots from the client.
354
+ *
355
+ * @deprecated Deprecated as of protocol version 2026-07-28 (SEP-2577).
356
+ * Remains functional during the deprecation window (at least twelve months).
357
+ * Migrate to passing paths via tool parameters, resource URIs, or configuration.
358
+ */
870
359
  async listRoots(params, options) {
871
360
  return this._requestWithSchema({
872
361
  method: "roots/list",
@@ -879,6 +368,10 @@ var Server = class extends Protocol {
879
368
  * @see {@linkcode LoggingMessageNotification}
880
369
  * @param params
881
370
  * @param sessionId Optional for stateless transports and backward compatibility.
371
+ *
372
+ * @deprecated Deprecated as of protocol version 2026-07-28 (SEP-2577).
373
+ * Remains functional during the deprecation window (at least twelve months).
374
+ * Migrate to stderr logging (STDIO servers) or OpenTelemetry.
882
375
  */
883
376
  async sendLoggingMessage(params, sessionId) {
884
377
  if (this._capabilities.logging && !this.isMessageIgnored(params.level, sessionId)) return this.notification({
@@ -927,20 +420,11 @@ var McpServer = class {
927
420
  _registeredResourceTemplates = {};
928
421
  _registeredTools = {};
929
422
  _registeredPrompts = {};
930
- _experimental;
931
423
  constructor(serverInfo, options) {
932
424
  this.server = new Server(serverInfo, options);
933
- }
934
- /**
935
- * Access experimental features.
936
- *
937
- * WARNING: These APIs are experimental and may change without notice.
938
- *
939
- * @experimental
940
- */
941
- get experimental() {
942
- if (!this._experimental) this._experimental = { tasks: new ExperimentalMcpServerTasks(this) };
943
- return this._experimental;
425
+ if (options?.capabilities?.tools) this.setToolRequestHandlers();
426
+ if (options?.capabilities?.resources) this.setResourceRequestHandlers();
427
+ if (options?.capabilities?.prompts) this.setPromptRequestHandlers();
944
428
  }
945
429
  /**
946
430
  * Attaches to the given transport, starts it, and starts listening for messages.
@@ -976,6 +460,7 @@ var McpServer = class {
976
460
  description: tool.description,
977
461
  inputSchema: tool.inputSchema ? standardSchemaToJsonSchema(tool.inputSchema, "input") : EMPTY_OBJECT_JSON_SCHEMA,
978
462
  annotations: tool.annotations,
463
+ icons: tool.icons,
979
464
  execution: tool.execution,
980
465
  _meta: tool._meta
981
466
  };
@@ -987,15 +472,8 @@ var McpServer = class {
987
472
  if (!tool) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool ${request.params.name} not found`);
988
473
  if (!tool.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool ${request.params.name} disabled`);
989
474
  try {
990
- const isTaskRequest = !!request.params.task;
991
- const taskSupport = tool.execution?.taskSupport;
992
- const isTaskHandler = "createTask" in tool.handler;
993
- if ((taskSupport === "required" || taskSupport === "optional") && !isTaskHandler) throw new ProtocolError(ProtocolErrorCode.InternalError, `Tool ${request.params.name} has taskSupport '${taskSupport}' but was not registered with registerToolTask`);
994
- if (taskSupport === "required" && !isTaskRequest) throw new ProtocolError(ProtocolErrorCode.MethodNotFound, `Tool ${request.params.name} requires task augmentation (taskSupport: 'required')`);
995
- if (taskSupport === "optional" && !isTaskRequest && isTaskHandler) return await this.handleAutomaticTaskPolling(tool, request, ctx);
996
475
  const args = await this.validateToolInput(tool, request.params.arguments, request.params.name);
997
476
  const result = await this.executeToolHandler(tool, args, ctx);
998
- if (isTaskRequest) return result;
999
477
  await this.validateToolOutput(tool, result, request.params.name);
1000
478
  return result;
1001
479
  } catch (error) {
@@ -1034,36 +512,17 @@ var McpServer = class {
1034
512
  */
1035
513
  async validateToolOutput(tool, result, toolName) {
1036
514
  if (!tool.outputSchema) return;
1037
- if (!("content" in result)) return;
1038
515
  if (result.isError) return;
1039
516
  if (!result.structuredContent) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Output validation error: Tool ${toolName} has an output schema but no structured content was provided`);
1040
517
  const parseResult = await validateStandardSchema(tool.outputSchema, result.structuredContent);
1041
518
  if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Output validation error: Invalid structured content for tool ${toolName}: ${parseResult.error}`);
1042
519
  }
1043
520
  /**
1044
- * Executes a tool handler (either regular or task-based).
521
+ * Executes a tool handler.
1045
522
  */
1046
523
  async executeToolHandler(tool, args, ctx) {
1047
524
  return tool.executor(args, ctx);
1048
525
  }
1049
- /**
1050
- * Handles automatic task polling for tools with `taskSupport` `'optional'`.
1051
- */
1052
- async handleAutomaticTaskPolling(tool, request, ctx) {
1053
- if (!ctx.task?.store) throw new Error("No task store provided for task-capable tool.");
1054
- const args = await this.validateToolInput(tool, request.params.arguments, request.params.name);
1055
- const createTaskResult = await tool.executor(args, ctx);
1056
- const taskId = createTaskResult.task.taskId;
1057
- let task = createTaskResult.task;
1058
- const pollInterval = task.pollInterval ?? 5e3;
1059
- while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
1060
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
1061
- const updatedTask = await ctx.task.store.getTask(taskId);
1062
- if (!updatedTask) throw new ProtocolError(ProtocolErrorCode.InternalError, `Task ${taskId} not found during polling`);
1063
- task = updatedTask;
1064
- }
1065
- return await ctx.task.store.getTaskResult(taskId);
1066
- }
1067
526
  _completionHandlerInitialized = false;
1068
527
  setCompletionRequestHandler() {
1069
528
  if (this._completionHandlerInitialized) return;
@@ -1161,6 +620,7 @@ var McpServer = class {
1161
620
  title: prompt.title,
1162
621
  description: prompt.description,
1163
622
  arguments: prompt.argsSchema ? promptArgumentsFromStandardSchema(prompt.argsSchema) : void 0,
623
+ icons: prompt.icons,
1164
624
  _meta: prompt._meta
1165
625
  };
1166
626
  }) }));
@@ -1241,13 +701,14 @@ var McpServer = class {
1241
701
  if (Array.isArray(variableNames) && variableNames.some((v) => !!template.completeCallback(v))) this.setCompletionRequestHandler();
1242
702
  return registeredResourceTemplate;
1243
703
  }
1244
- _createRegisteredPrompt(name, title, description, argsSchema, callback, _meta) {
704
+ _createRegisteredPrompt(name, title, description, argsSchema, callback, icons, _meta) {
1245
705
  let currentArgsSchema = argsSchema;
1246
706
  let currentCallback = callback;
1247
707
  const registeredPrompt = {
1248
708
  title,
1249
709
  description,
1250
710
  argsSchema,
711
+ icons,
1251
712
  _meta,
1252
713
  handler: createPromptHandler(name, argsSchema, callback),
1253
714
  enabled: true,
@@ -1261,6 +722,7 @@ var McpServer = class {
1261
722
  }
1262
723
  if (updates.title !== void 0) registeredPrompt.title = updates.title;
1263
724
  if (updates.description !== void 0) registeredPrompt.description = updates.description;
725
+ if (updates.icons !== void 0) registeredPrompt.icons = updates.icons;
1264
726
  if (updates._meta !== void 0) registeredPrompt._meta = updates._meta;
1265
727
  let needsHandlerRegen = false;
1266
728
  if (updates.argsSchema !== void 0) {
@@ -1288,7 +750,7 @@ var McpServer = class {
1288
750
  }
1289
751
  return registeredPrompt;
1290
752
  }
1291
- _createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, execution, _meta, handler) {
753
+ _createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, _meta, handler) {
1292
754
  validateAndWarnToolName(name);
1293
755
  let currentHandler = handler;
1294
756
  const registeredTool = {
@@ -1297,6 +759,7 @@ var McpServer = class {
1297
759
  inputSchema,
1298
760
  outputSchema,
1299
761
  annotations,
762
+ icons,
1300
763
  execution,
1301
764
  _meta,
1302
765
  handler,
@@ -1326,6 +789,7 @@ var McpServer = class {
1326
789
  if (needsExecutorRegen) registeredTool.executor = createToolExecutor(registeredTool.inputSchema, currentHandler);
1327
790
  if (updates.outputSchema !== void 0) registeredTool.outputSchema = updates.outputSchema;
1328
791
  if (updates.annotations !== void 0) registeredTool.annotations = updates.annotations;
792
+ if (updates.icons !== void 0) registeredTool.icons = updates.icons;
1329
793
  if (updates._meta !== void 0) registeredTool._meta = updates._meta;
1330
794
  if (updates.enabled !== void 0) registeredTool.enabled = updates.enabled;
1331
795
  this.sendToolListChanged();
@@ -1336,67 +800,15 @@ var McpServer = class {
1336
800
  this.sendToolListChanged();
1337
801
  return registeredTool;
1338
802
  }
1339
- /**
1340
- * Registers a tool with a config object and callback.
1341
- *
1342
- * @example
1343
- * ```ts source="./mcp.examples.ts#McpServer_registerTool_basic"
1344
- * server.registerTool(
1345
- * 'calculate-bmi',
1346
- * {
1347
- * title: 'BMI Calculator',
1348
- * description: 'Calculate Body Mass Index',
1349
- * inputSchema: z.object({
1350
- * weightKg: z.number(),
1351
- * heightM: z.number()
1352
- * }),
1353
- * outputSchema: z.object({ bmi: z.number() })
1354
- * },
1355
- * async ({ weightKg, heightM }) => {
1356
- * const output = { bmi: weightKg / (heightM * heightM) };
1357
- * return {
1358
- * content: [{ type: 'text', text: JSON.stringify(output) }],
1359
- * structuredContent: output
1360
- * };
1361
- * }
1362
- * );
1363
- * ```
1364
- */
1365
803
  registerTool(name, config, cb) {
1366
804
  if (this._registeredTools[name]) throw new Error(`Tool ${name} is already registered`);
1367
- const { title, description, inputSchema, outputSchema, annotations, _meta } = config;
1368
- return this._createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, { taskSupport: "forbidden" }, _meta, cb);
805
+ const { title, description, inputSchema, outputSchema, annotations, icons, _meta } = config;
806
+ return this._createRegisteredTool(name, title, description, normalizeRawShapeSchema(inputSchema), normalizeRawShapeSchema(outputSchema), annotations, icons, void 0, _meta, cb);
1369
807
  }
1370
- /**
1371
- * Registers a prompt with a config object and callback.
1372
- *
1373
- * @example
1374
- * ```ts source="./mcp.examples.ts#McpServer_registerPrompt_basic"
1375
- * server.registerPrompt(
1376
- * 'review-code',
1377
- * {
1378
- * title: 'Code Review',
1379
- * description: 'Review code for best practices',
1380
- * argsSchema: z.object({ code: z.string() })
1381
- * },
1382
- * ({ code }) => ({
1383
- * messages: [
1384
- * {
1385
- * role: 'user' as const,
1386
- * content: {
1387
- * type: 'text' as const,
1388
- * text: `Please review this code:\n\n${code}`
1389
- * }
1390
- * }
1391
- * ]
1392
- * })
1393
- * );
1394
- * ```
1395
- */
1396
808
  registerPrompt(name, config, cb) {
1397
809
  if (this._registeredPrompts[name]) throw new Error(`Prompt ${name} is already registered`);
1398
- const { title, description, argsSchema, _meta } = config;
1399
- const registeredPrompt = this._createRegisteredPrompt(name, title, description, argsSchema, cb, _meta);
810
+ const { title, description, argsSchema, icons, _meta } = config;
811
+ const registeredPrompt = this._createRegisteredPrompt(name, title, description, normalizeRawShapeSchema(argsSchema), cb, icons, _meta);
1400
812
  this.setPromptRequestHandlers();
1401
813
  this.sendPromptListChanged();
1402
814
  return registeredPrompt;
@@ -1422,6 +834,10 @@ var McpServer = class {
1422
834
  * data: 'Processing complete'
1423
835
  * });
1424
836
  * ```
837
+ *
838
+ * @deprecated Deprecated as of protocol version 2026-07-28 (SEP-2577).
839
+ * Remains functional during the deprecation window (at least twelve months).
840
+ * Migrate to stderr logging (STDIO servers) or OpenTelemetry.
1425
841
  */
1426
842
  async sendLoggingMessage(params, sessionId) {
1427
843
  return this.server.sendLoggingMessage(params, sessionId);
@@ -1480,21 +896,6 @@ var ResourceTemplate = class {
1480
896
  * When `inputSchema` is undefined, the handler is called with just `(ctx)`.
1481
897
  */
1482
898
  function createToolExecutor(inputSchema, handler) {
1483
- if ("createTask" in handler) {
1484
- const taskHandler = handler;
1485
- return async (args, ctx) => {
1486
- if (!ctx.task?.store) throw new Error("No task store provided.");
1487
- const taskCtx = {
1488
- ...ctx,
1489
- task: {
1490
- store: ctx.task.store,
1491
- requestedTtl: ctx.task?.requestedTtl
1492
- }
1493
- };
1494
- if (inputSchema) return taskHandler.createTask(args, taskCtx);
1495
- return taskHandler.createTask(taskCtx);
1496
- };
1497
- }
1498
899
  if (inputSchema) {
1499
900
  const callback$1 = handler;
1500
901
  return async (args, ctx) => callback$1(args, ctx);
@@ -1621,101 +1022,6 @@ function hostHeaderValidationResponse(req, allowedHostnames) {
1621
1022
  });
1622
1023
  }
1623
1024
 
1624
- //#endregion
1625
- //#region src/server/stdio.ts
1626
- /**
1627
- * Server transport for stdio: this communicates with an MCP client by reading from the current process' `stdin` and writing to `stdout`.
1628
- *
1629
- * This transport is only available in Node.js environments.
1630
- *
1631
- * @example
1632
- * ```ts source="./stdio.examples.ts#StdioServerTransport_basicUsage"
1633
- * const server = new McpServer({ name: 'my-server', version: '1.0.0' });
1634
- * const transport = new StdioServerTransport();
1635
- * await server.connect(transport);
1636
- * ```
1637
- */
1638
- var StdioServerTransport = class {
1639
- _readBuffer = new ReadBuffer();
1640
- _started = false;
1641
- _closed = false;
1642
- constructor(_stdin = process.stdin, _stdout = process.stdout) {
1643
- this._stdin = _stdin;
1644
- this._stdout = _stdout;
1645
- }
1646
- onclose;
1647
- onerror;
1648
- onmessage;
1649
- _ondata = (chunk) => {
1650
- this._readBuffer.append(chunk);
1651
- this.processReadBuffer();
1652
- };
1653
- _onerror = (error) => {
1654
- this.onerror?.(error);
1655
- };
1656
- _onstdouterror = (error) => {
1657
- this.onerror?.(error);
1658
- this.close().catch(() => {});
1659
- };
1660
- /**
1661
- * Starts listening for messages on `stdin`.
1662
- */
1663
- async start() {
1664
- if (this._started) throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
1665
- this._started = true;
1666
- this._stdin.on("data", this._ondata);
1667
- this._stdin.on("error", this._onerror);
1668
- this._stdout.on("error", this._onstdouterror);
1669
- }
1670
- processReadBuffer() {
1671
- while (true) try {
1672
- const message = this._readBuffer.readMessage();
1673
- if (message === null) break;
1674
- this.onmessage?.(message);
1675
- } catch (error) {
1676
- this.onerror?.(error);
1677
- }
1678
- }
1679
- async close() {
1680
- if (this._closed) return;
1681
- this._closed = true;
1682
- this._stdin.off("data", this._ondata);
1683
- this._stdin.off("error", this._onerror);
1684
- this._stdout.off("error", this._onstdouterror);
1685
- if (this._stdin.listenerCount("data") === 0) this._stdin.pause();
1686
- this._readBuffer.clear();
1687
- this.onclose?.();
1688
- }
1689
- send(message) {
1690
- if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
1691
- return new Promise((resolve, reject) => {
1692
- const json = serializeMessage(message);
1693
- let settled = false;
1694
- const onError = (error) => {
1695
- if (settled) return;
1696
- settled = true;
1697
- this._stdout.off("error", onError);
1698
- this._stdout.off("drain", onDrain);
1699
- reject(error);
1700
- };
1701
- const onDrain = () => {
1702
- if (settled) return;
1703
- settled = true;
1704
- this._stdout.off("error", onError);
1705
- this._stdout.off("drain", onDrain);
1706
- resolve();
1707
- };
1708
- this._stdout.once("error", onError);
1709
- if (this._stdout.write(json)) {
1710
- if (settled) return;
1711
- settled = true;
1712
- this._stdout.off("error", onError);
1713
- resolve();
1714
- } else if (!settled) this._stdout.once("drain", onDrain);
1715
- });
1716
- }
1717
- };
1718
-
1719
1025
  //#endregion
1720
1026
  //#region src/server/streamableHttp.ts
1721
1027
  /**
@@ -1772,6 +1078,7 @@ var StdioServerTransport = class {
1772
1078
  var WebStandardStreamableHTTPServerTransport = class {
1773
1079
  sessionIdGenerator;
1774
1080
  _started = false;
1081
+ _closed = false;
1775
1082
  _streamMapping = /* @__PURE__ */ new Map();
1776
1083
  _requestToStreamMapping = /* @__PURE__ */ new Map();
1777
1084
  _requestResponseMap = /* @__PURE__ */ new Map();
@@ -1876,13 +1183,29 @@ var WebStandardStreamableHTTPServerTransport = class {
1876
1183
  }
1877
1184
  }
1878
1185
  /**
1186
+ * Returns true if the client's protocol version supports empty SSE data in
1187
+ * priming events (the fix shipped with protocol version `2025-11-25`).
1188
+ *
1189
+ * The version is checked for membership in this transport instance's
1190
+ * supported protocol versions rather than with an open-ended
1191
+ * `>= '2025-11-25'` comparison: the value may come from an `initialize`
1192
+ * request body, which (unlike the `MCP-Protocol-Version` header) is not
1193
+ * validated against `supportedProtocolVersions` before reaching this
1194
+ * check. An unknown future version string must not silently enable
1195
+ * behavior reserved for versions this transport actually supports.
1196
+ */
1197
+ supportsEmptySSEData(protocolVersion) {
1198
+ return this._supportedProtocolVersions.includes(protocolVersion) && protocolVersion >= "2025-11-25";
1199
+ }
1200
+ /**
1879
1201
  * Writes a priming event to establish resumption capability.
1880
1202
  * Only sends if `eventStore` is configured (opt-in for resumability) and
1881
- * the client's protocol version supports empty SSE data (>= `2025-11-25`).
1203
+ * the client's protocol version supports empty SSE data (a supported
1204
+ * version that is >= `2025-11-25`).
1882
1205
  */
1883
1206
  async writePrimingEvent(controller, encoder, streamId, protocolVersion) {
1884
1207
  if (!this._eventStore) return;
1885
- if (protocolVersion < "2025-11-25") return;
1208
+ if (!this.supportsEmptySSEData(protocolVersion)) return;
1886
1209
  const primingEventId = await this._eventStore.storeEvent(streamId, {});
1887
1210
  let primingEvent = `id: ${primingEventId}\ndata: \n\n`;
1888
1211
  if (this._retryInterval !== void 0) primingEvent = `id: ${primingEventId}\nretry: ${this._retryInterval}\ndata: \n\n`;
@@ -2135,7 +1458,7 @@ var WebStandardStreamableHTTPServerTransport = class {
2135
1458
  for (const message of messages) {
2136
1459
  let closeSSEStream;
2137
1460
  let closeStandaloneSSEStream;
2138
- if (isJSONRPCRequest(message) && this._eventStore && clientProtocolVersion >= "2025-11-25") {
1461
+ if (isJSONRPCRequest(message) && this._eventStore && this.supportsEmptySSEData(clientProtocolVersion)) {
2139
1462
  closeSSEStream = () => {
2140
1463
  this.closeSSEStream(message.id);
2141
1464
  };
@@ -2213,6 +1536,8 @@ var WebStandardStreamableHTTPServerTransport = class {
2213
1536
  }
2214
1537
  }
2215
1538
  async close() {
1539
+ if (this._closed) return;
1540
+ this._closed = true;
2216
1541
  for (const { cleanup } of this._streamMapping.values()) cleanup();
2217
1542
  this._streamMapping.clear();
2218
1543
  this._requestResponseMap.clear();
@@ -2292,5 +1617,5 @@ function fromJsonSchema(schema, validator) {
2292
1617
  }
2293
1618
 
2294
1619
  //#endregion
2295
- export { AjvJsonSchemaValidator, CfWorkerJsonSchemaValidator, DEFAULT_NEGOTIATED_PROTOCOL_VERSION, DEFAULT_REQUEST_TIMEOUT_MSEC, ExperimentalMcpServerTasks, ExperimentalServerTasks, INTERNAL_ERROR, INVALID_PARAMS, INVALID_REQUEST, InMemoryTaskMessageQueue, InMemoryTaskStore, JSONRPC_VERSION, LATEST_PROTOCOL_VERSION, METHOD_NOT_FOUND, McpServer, OAuthError, OAuthErrorCode, PARSE_ERROR, ProtocolError, ProtocolErrorCode, RELATED_TASK_META_KEY, ReadBuffer, ResourceTemplate, SUPPORTED_PROTOCOL_VERSIONS, SdkError, SdkErrorCode, Server, StdioServerTransport, UriTemplate, UrlElicitationRequiredError, WebStandardStreamableHTTPServerTransport, assertClientRequestTaskCapability, assertCompleteRequestPrompt, assertCompleteRequestResourceTemplate, assertToolsCallTaskCapability, checkResourceAllowed, completable, createFetchWithInit, deserializeMessage, fromJsonSchema, getDisplayName, hostHeaderValidationResponse, isCompletable, isInitializeRequest, isInitializedNotification, isJSONRPCErrorResponse, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResultResponse, isTaskAugmentedRequestParams, isTerminal, localhostAllowedHostnames, parseJSONRPCMessage, resourceUrlFromServerUrl, serializeMessage, takeResult, toArrayAsync, validateHostHeader };
1620
+ export { BAGGAGE_META_KEY, CLIENT_CAPABILITIES_META_KEY, CLIENT_INFO_META_KEY, DEFAULT_NEGOTIATED_PROTOCOL_VERSION, DEFAULT_REQUEST_TIMEOUT_MSEC, INTERNAL_ERROR, INVALID_PARAMS, INVALID_REQUEST, InMemoryTransport, JSONRPC_VERSION, LATEST_PROTOCOL_VERSION, LOG_LEVEL_META_KEY, METHOD_NOT_FOUND, McpServer, OAuthError, OAuthErrorCode, PARSE_ERROR, PROTOCOL_VERSION_META_KEY, ProtocolError, ProtocolErrorCode, RELATED_TASK_META_KEY, ReadBuffer, ResourceTemplate, STDIO_DEFAULT_MAX_BUFFER_SIZE, SUPPORTED_PROTOCOL_VERSIONS, SdkError, SdkErrorCode, SdkHttpError, Server, TRACEPARENT_META_KEY, TRACESTATE_META_KEY, UnsupportedProtocolVersionError, UriTemplate, UrlElicitationRequiredError, WebStandardStreamableHTTPServerTransport, assertCompleteRequestPrompt, assertCompleteRequestResourceTemplate, checkResourceAllowed, completable, createFetchWithInit, deserializeMessage, fromJsonSchema, getDisplayName, hostHeaderValidationResponse, isCallToolResult, isCompletable, isInitializeRequest, isInitializedNotification, isJSONRPCErrorResponse, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResponse, isJSONRPCResultResponse, isSpecType, isTaskAugmentedRequestParams, localhostAllowedHostnames, parseJSONRPCMessage, resourceUrlFromServerUrl, serializeMessage, specTypeSchemas, validateHostHeader };
2296
1621
  //# sourceMappingURL=index.mjs.map