diff --git a/directory/differ/.claude-plugin/plugin.json b/directory/differ/.claude-plugin/plugin.json index d71e46e..b4ce4d4 100644 --- a/directory/differ/.claude-plugin/plugin.json +++ b/directory/differ/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "differ", - "version": "0.6.0", + "version": "0.6.1", "description": "Create, preview, publish and revise interactive social posts.", "author": { "name": "Sky Valley", diff --git a/directory/differ/.codex-plugin/plugin.json b/directory/differ/.codex-plugin/plugin.json index 1fbc95e..5d60d63 100644 --- a/directory/differ/.codex-plugin/plugin.json +++ b/directory/differ/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "differ", - "version": "0.6.0", + "version": "0.6.1", "description": "Create, preview, publish and revise interactive social posts.", "author": { "name": "Sky Valley", diff --git a/directory/differ/plugin.json b/directory/differ/plugin.json index 40fff64..cf449b8 100644 --- a/directory/differ/plugin.json +++ b/directory/differ/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "differ", - "version": "0.6.0", + "version": "0.6.1", "description": "Create, preview, publish and revise interactive social posts.", "author": { "name": "Sky Valley", diff --git a/package-lock.json b/package-lock.json index fddaa25..685fc5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "differ-plugin", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "differ-plugin", - "version": "0.6.0", + "version": "0.6.1", "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "1.30.0", + "@modelcontextprotocol/sdk": "1.32.1", "zod": "4.6.5" }, "devDependencies": { @@ -474,9 +474,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", - "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.1.tgz", + "integrity": "sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==", "license": "MIT", "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", diff --git a/package.json b/package.json index 8956d2f..77209eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "differ-plugin", - "version": "0.6.0", + "version": "0.6.1", "private": true, "type": "module", "engines": { @@ -17,7 +17,7 @@ "check-service": "node scripts/check-service.mjs" }, "dependencies": { - "@modelcontextprotocol/sdk": "1.30.0", + "@modelcontextprotocol/sdk": "1.32.1", "zod": "4.6.5" }, "devDependencies": { diff --git a/plugins/differ/.claude-plugin/plugin.json b/plugins/differ/.claude-plugin/plugin.json index d71e46e..b4ce4d4 100644 --- a/plugins/differ/.claude-plugin/plugin.json +++ b/plugins/differ/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "differ", - "version": "0.6.0", + "version": "0.6.1", "description": "Create, preview, publish and revise interactive social posts.", "author": { "name": "Sky Valley", diff --git a/plugins/differ/.codex-plugin/plugin.json b/plugins/differ/.codex-plugin/plugin.json index 1fbc95e..5d60d63 100644 --- a/plugins/differ/.codex-plugin/plugin.json +++ b/plugins/differ/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "differ", - "version": "0.6.0", + "version": "0.6.1", "description": "Create, preview, publish and revise interactive social posts.", "author": { "name": "Sky Valley", diff --git a/plugins/differ/THIRD_PARTY_NOTICES.txt b/plugins/differ/THIRD_PARTY_NOTICES.txt index d85558b..c9386b8 100644 --- a/plugins/differ/THIRD_PARTY_NOTICES.txt +++ b/plugins/differ/THIRD_PARTY_NOTICES.txt @@ -1,4 +1,4 @@ -@modelcontextprotocol/sdk@1.30.0 (MIT) +@modelcontextprotocol/sdk@1.32.1 (MIT) MIT License diff --git a/plugins/differ/plugin.json b/plugins/differ/plugin.json index 40fff64..cf449b8 100644 --- a/plugins/differ/plugin.json +++ b/plugins/differ/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "differ", - "version": "0.6.0", + "version": "0.6.1", "description": "Create, preview, publish and revise interactive social posts.", "author": { "name": "Sky Valley", diff --git a/plugins/differ/scripts/differ.cjs b/plugins/differ/scripts/differ.cjs index bd2ca81..2a499ba 100644 --- a/plugins/differ/scripts/differ.cjs +++ b/plugins/differ/scripts/differ.cjs @@ -33887,6 +33887,9 @@ var Protocol = class { this.setRequestHandler(GetTaskPayloadRequestSchema, async (request2, extra) => { const handleTaskResult = async () => { const taskId = request2.params.taskId; + if (!await this._taskStore.getTask(taskId, extra.sessionId)) { + throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`); + } if (this._taskMessageQueue) { let queuedMessage; while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) { @@ -33917,12 +33920,12 @@ var Protocol = class { throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`); } if (!isTerminal(task.status)) { - await this._waitForTaskUpdate(taskId, extra.signal); + await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId); return await handleTaskResult(); } if (isTerminal(task.status)) { const result = await this._taskStore.getTaskResult(taskId, extra.sessionId); - this._clearTaskQueue(taskId); + this._clearTaskQueue(taskId, extra.sessionId); return { ...result, _meta: { @@ -33959,7 +33962,7 @@ var Protocol = class { throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`); } await this._taskStore.updateTaskStatus(request2.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId); - this._clearTaskQueue(request2.params.taskId); + this._clearTaskQueue(request2.params.taskId, extra.sessionId); const cancelledTask = await this._taskStore.getTask(request2.params.taskId, extra.sessionId); if (!cancelledTask) { throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request2.params.taskId}`); @@ -34087,6 +34090,19 @@ var Protocol = class { const handler = this._requestHandlers.get(request2.method) ?? this.fallbackRequestHandler; const capturedTransport = this._transport; const relatedTaskId = request2.params?._meta?.[RELATED_TASK_META_KEY]?.taskId; + const sessionId = capturedTransport?.sessionId; + const store = this._taskStore; + let relatedTaskFound = true; + let relatedTaskLookup; + if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) { + relatedTaskFound = false; + relatedTaskLookup = (async () => { + if (!await store.getTask(relatedTaskId, sessionId)) { + throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`); + } + relatedTaskFound = true; + })(); + } if (handler === void 0) { const errorResponse = { jsonrpc: "2.0", @@ -34096,7 +34112,10 @@ var Protocol = class { message: "Method not found" } }; - if (relatedTaskId && this._taskMessageQueue) { + if (relatedTaskId && relatedTaskLookup) { + const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() }; + relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error63) => this._onerror(new Error(`Failed to send an error response: ${error63}`))); + } else if (relatedTaskId && this._taskMessageQueue) { this._enqueueTaskMessage(relatedTaskId, { type: "error", message: errorResponse, @@ -34147,7 +34166,10 @@ var Protocol = class { closeSSEStream: extra?.closeSSEStream, closeStandaloneSSEStream: extra?.closeStandaloneSSEStream }; - Promise.resolve().then(() => { + (relatedTaskLookup ?? Promise.resolve()).then(() => { + if (relatedTaskLookup && abortController.signal.aborted) { + throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled"); + } if (taskCreationParams) { this.assertTaskHandlerCapability(request2.method); } @@ -34182,7 +34204,7 @@ var Protocol = class { ...error63["data"] !== void 0 && { data: error63["data"] } } }; - if (relatedTaskId && this._taskMessageQueue) { + if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) { await this._enqueueTaskMessage(relatedTaskId, { type: "error", message: errorResponse, @@ -34662,7 +34684,7 @@ var Protocol = class { throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured"); } const maxQueueSize = this._options?.maxTaskQueueSize; - await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize); + await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize); } /** * Clears the message queue for a task and rejects any pending request resolvers. @@ -34691,12 +34713,13 @@ var Protocol = class { * Uses polling to check for updates at the task's configured poll interval. * @param taskId The task ID to wait for * @param signal Abort signal to cancel the wait + * @param sessionId Session of the request that waits, passed to the task store * @returns Promise that resolves when an update occurs or rejects if aborted */ - async _waitForTaskUpdate(taskId, signal) { + async _waitForTaskUpdate(taskId, signal, sessionId) { let interval = this._options?.defaultTaskPollInterval ?? 1e3; try { - const task = await this._taskStore?.getTask(taskId); + const task = await this._taskStore?.getTask(taskId, sessionId); if (task?.pollInterval) { interval = task.pollInterval; } @@ -35575,6 +35598,42 @@ var ExperimentalMcpServerTasks = class { }; // node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +function toolInputElementCount(value, max) { + let count = 0; + const stack = [value]; + while (stack.length > 0) { + const node2 = stack.pop(); + if (node2 === null || typeof node2 !== "object") + continue; + if (Array.isArray(node2)) { + for (const child of node2) { + if (++count > max) + return count; + if (child !== null && typeof child === "object") + stack.push(child); + } + } else { + for (const key in node2) { + if (!Object.prototype.hasOwnProperty.call(node2, key)) + continue; + if (++count > max) + return count; + const child = node2[key]; + if (child !== null && typeof child === "object") + stack.push(child); + } + } + } + return count; +} +function resolveMaxToolInputElements(value) { + if (value === void 0 || value === Infinity) + return void 0; + if (typeof value !== "number" || Number.isNaN(value) || value < 1) { + throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`); + } + return value; +} var McpServer = class { constructor(serverInfo, options) { this._registeredResources = {}; @@ -35586,6 +35645,7 @@ var McpServer = class { this._resourceHandlersInitialized = false; this._promptHandlersInitialized = false; this.server = new Server(serverInfo, options); + this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements); } /** * Access experimental features. @@ -35716,12 +35776,15 @@ var McpServer = class { * Validates tool input arguments against the tool's input schema. */ async validateToolInput(tool, args, toolName) { + if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) { + throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`); + } if (!tool.inputSchema) { return void 0; } const inputObj = normalizeObjectSchema(tool.inputSchema); const schemaToParse = inputObj ?? tool.inputSchema; - const parseResult = await safeParseAsync2(schemaToParse, args); + const parseResult = await safeParseAsync2(schemaToParse, args ?? {}); if (!parseResult.success) { const error63 = "error" in parseResult ? parseResult.error : "Unknown error"; const errorMessage = getParseErrorMessage(error63); @@ -35959,7 +36022,7 @@ var McpServer = class { } if (prompt.argsSchema) { const argsObj = normalizeObjectSchema(prompt.argsSchema); - const parseResult = await safeParseAsync2(argsObj, request2.params.arguments); + const parseResult = await safeParseAsync2(argsObj, request2.params.arguments ?? {}); if (!parseResult.success) { const error63 = "error" in parseResult ? parseResult.error : "Unknown error"; const errorMessage = getParseErrorMessage(error63); @@ -37138,7 +37201,7 @@ function inspectVideo(input2) { // package.json var package_default = { name: "differ-plugin", - version: "0.6.0", + version: "0.6.1", private: true, type: "module", engines: { @@ -37155,7 +37218,7 @@ var package_default = { "check-service": "node scripts/check-service.mjs" }, dependencies: { - "@modelcontextprotocol/sdk": "1.30.0", + "@modelcontextprotocol/sdk": "1.32.1", zod: "4.6.5" }, devDependencies: {