From 2ec9ba397a2c985b19c3df7404ea32f544f5afff Mon Sep 17 00:00:00 2001 From: gimenes Date: Tue, 24 Feb 2026 16:19:15 -0300 Subject: [PATCH 1/2] fix(vtex): allow additional properties in search-collections output schema Add .passthrough() to all z.object() schemas in collectionListOutputSchema so zod-to-json-schema does not emit additionalProperties: false. This prevents MCP error -32602 when the VTEX API returns fields not declared in the schema. Co-Authored-By: Claude Sonnet 4.6 --- .../server/tools/custom/search-collections.ts | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/vtex/server/tools/custom/search-collections.ts b/vtex/server/tools/custom/search-collections.ts index 35727a75..63155bd9 100644 --- a/vtex/server/tools/custom/search-collections.ts +++ b/vtex/server/tools/custom/search-collections.ts @@ -2,28 +2,34 @@ import { createTool } from "@decocms/runtime/tools"; import { z } from "zod"; import type { Env } from "../../types/env.ts"; -const collectionListOutputSchema = z.object({ - paging: z.object({ - page: z.number(), - perPage: z.number(), - total: z.number(), - pages: z.number(), - }), - items: z.array( - z.object({ - id: z.number(), - name: z.string(), - searchable: z.boolean(), - highlight: z.boolean(), - dateFrom: z.string(), - dateTo: z.string(), - totalSku: z.number(), - totalProducts: z.number(), - type: z.enum(["Manual", "Automatic", "Hybrid"]), - lastModifiedBy: z.string().nullable(), - }), - ), -}); +const collectionListOutputSchema = z + .object({ + paging: z + .object({ + page: z.number(), + perPage: z.number(), + total: z.number(), + pages: z.number(), + }) + .passthrough(), + items: z.array( + z + .object({ + id: z.number(), + name: z.string(), + searchable: z.boolean(), + highlight: z.boolean(), + dateFrom: z.string(), + dateTo: z.string(), + totalSku: z.number(), + totalProducts: z.number(), + type: z.enum(["Manual", "Automatic", "Hybrid"]), + lastModifiedBy: z.string().nullable(), + }) + .passthrough(), + ), + }) + .passthrough(); export const searchCollections = (env: Env) => createTool({ From 9c7021389a8732428144d4e82548b55c46add015 Mon Sep 17 00:00:00 2001 From: gimenes Date: Tue, 24 Feb 2026 16:49:10 -0300 Subject: [PATCH 2/2] fix(vtex): remove outputSchema from custom tools and bump runtime to 1.2.10 - Remove outputSchema and its Zod schema definition from search-collections, letting the MCP SDK pass undefined for tools without a structured output contract instead of the empty-object fallback - Bump @decocms/runtime to 1.2.10, which fixes the runtime to pass undefined outputSchema to server.registerTool() when no outputSchema is defined, avoiding unnecessary structured output validation for all tools Co-Authored-By: Claude Sonnet 4.6 --- bun.lock | 5 +-- vtex/package.json | 2 +- .../server/tools/custom/search-collections.ts | 33 +------------------ 3 files changed, 5 insertions(+), 35 deletions(-) diff --git a/bun.lock b/bun.lock index 96598063..e7588ee0 100644 --- a/bun.lock +++ b/bun.lock @@ -798,11 +798,12 @@ "version": "1.0.0", "dependencies": { "@decocms/bindings": "^1.3.1", - "@decocms/runtime": "1.2.9", + "@decocms/runtime": "1.2.10", "zod": "^4.0.0", }, "devDependencies": { "@cloudflare/workers-types": "^4.20260206.0", + "@decocms/mcps-shared": "1.0.0", "@hey-api/client-fetch": "^0.8.0", "@hey-api/openapi-ts": "0.92.4", "@modelcontextprotocol/sdk": "1.20.2", @@ -3469,7 +3470,7 @@ "vtex/@decocms/bindings": ["@decocms/bindings@1.3.1", "", { "dependencies": { "@modelcontextprotocol/sdk": "1.26.0", "@tanstack/react-router": "1.139.7", "react": "^19.2.0", "zod": "^4.0.0", "zod-from-json-schema": "^0.5.2" } }, "sha512-VNgibUQ1pl3ZWdXuwgiSqdBLrHVCD9K528F2Rd4iydUCAspclF9/rEnxB/rfHu409Mv3BT5YWnyJSnJnK4BlFg=="], - "vtex/@decocms/runtime": ["@decocms/runtime@1.2.9", "", { "dependencies": { "@ai-sdk/provider": "^3.0.0", "@cloudflare/workers-types": "^4.20250617.0", "@decocms/bindings": "^1.0.7", "@modelcontextprotocol/sdk": "1.26.0", "hono": "^4.10.7", "jose": "^6.0.11", "zod": "^4.0.0" } }, "sha512-zf/6oKls8IhH+B7RsHVo0bw8Es4ABht9rTVSJVMP0WnE2rPYHsGacGfER+MIcGuskKVoOs8Yi4bbuCsUYFbu+A=="], + "vtex/@decocms/runtime": ["@decocms/runtime@1.2.10", "", { "dependencies": { "@ai-sdk/provider": "^3.0.0", "@cloudflare/workers-types": "^4.20250617.0", "@decocms/bindings": "^1.0.7", "@modelcontextprotocol/sdk": "1.26.0", "hono": "^4.10.7", "jose": "^6.0.11", "zod": "^4.0.0" } }, "sha512-QLtFWcgaHx3q/UNWJJkfgRd7Ebz+ISmUIOMW+7ZOR12qbw/GfEDJtJTxAqM2u4iRO2zPnLQhL1bIG6N2hIOzog=="], "vtex/@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.20.2", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-6rqTdFt67AAAzln3NOKsXRmv5ZzPkgbfaebKBqUbts7vK1GZudqnrun5a8d3M/h955cam9RHZ6Jb4Y1XhnmFPg=="], diff --git a/vtex/package.json b/vtex/package.json index f4f0e2e8..21d403b9 100644 --- a/vtex/package.json +++ b/vtex/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@decocms/bindings": "^1.3.1", - "@decocms/runtime": "1.2.9", + "@decocms/runtime": "1.2.10", "zod": "^4.0.0" }, "devDependencies": { diff --git a/vtex/server/tools/custom/search-collections.ts b/vtex/server/tools/custom/search-collections.ts index 63155bd9..84857bb0 100644 --- a/vtex/server/tools/custom/search-collections.ts +++ b/vtex/server/tools/custom/search-collections.ts @@ -2,35 +2,6 @@ import { createTool } from "@decocms/runtime/tools"; import { z } from "zod"; import type { Env } from "../../types/env.ts"; -const collectionListOutputSchema = z - .object({ - paging: z - .object({ - page: z.number(), - perPage: z.number(), - total: z.number(), - pages: z.number(), - }) - .passthrough(), - items: z.array( - z - .object({ - id: z.number(), - name: z.string(), - searchable: z.boolean(), - highlight: z.boolean(), - dateFrom: z.string(), - dateTo: z.string(), - totalSku: z.number(), - totalProducts: z.number(), - type: z.enum(["Manual", "Automatic", "Hybrid"]), - lastModifiedBy: z.string().nullable(), - }) - .passthrough(), - ), - }) - .passthrough(); - export const searchCollections = (env: Env) => createTool({ id: "VTEX_SEARCH_COLLECTIONS", @@ -39,7 +10,6 @@ export const searchCollections = (env: Env) => inputSchema: z.object({ searchTerms: z.string().describe("Search terms to find collections"), }), - outputSchema: collectionListOutputSchema, execute: async ({ context }) => { const credentials = env.MESH_REQUEST_CONTEXT.state; const { accountName, appKey, appToken } = credentials; @@ -61,7 +31,6 @@ export const searchCollections = (env: Env) => ); } - const result: unknown = await response.json(); - return collectionListOutputSchema.parse(result); + return response.json(); }, });