fix: convert MCP tool schemas from JSON Schema to Zod for SDK v1.29.0
All checks were successful
CI / ci (push) Successful in 28s
CI / ci (pull_request) Successful in 25s
CI / e2e (push) Successful in 1m2s
CI / e2e (pull_request) Successful in 1m3s

The MCP SDK v1.29.0 changed server.tool() to require Zod schemas
(raw shapes) instead of plain JSON Schema objects. The old format
triggered "expected a Zod schema or ToolAnnotations" errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 20:54:20 +02:00
parent 0a40d7627f
commit 68f6647f76
5 changed files with 89 additions and 169 deletions

View File

@@ -1,3 +1,4 @@
import { z } from "zod";
import type { db as prodDb } from "../../../db/index.ts";
import {
createItem,
@@ -29,24 +30,14 @@ export const itemToolDefinitions = [
description:
"List all items in the gear collection, optionally filtered by category.",
inputSchema: {
type: "object" as const,
properties: {
categoryId: {
type: "number",
description: "Filter items by category ID",
},
},
categoryId: z.number().optional().describe("Filter items by category ID"),
},
},
{
name: "get_item",
description: "Get a single item by its ID, including all details.",
inputSchema: {
type: "object" as const,
properties: {
id: { type: "number", description: "The item ID" },
},
required: ["id"],
id: z.number().describe("The item ID"),
},
},
{
@@ -54,60 +45,48 @@ export const itemToolDefinitions = [
description:
"Add a new item to the gear collection. Use this for items you've already decided on. For items you're still researching, use create_thread instead.",
inputSchema: {
type: "object" as const,
properties: {
name: { type: "string", description: "Item name" },
categoryId: { type: "number", description: "Category ID" },
weightGrams: { type: "number", description: "Weight in grams" },
priceCents: { type: "number", description: "Price in cents" },
notes: { type: "string", description: "Notes about the item" },
productUrl: { type: "string", description: "URL to the product page" },
imageFilename: {
type: "string",
description: "Filename of an uploaded image",
},
imageSourceUrl: {
type: "string",
description: "Original URL the image was fetched from",
},
},
required: ["name", "categoryId"],
name: z.string().describe("Item name"),
categoryId: z.number().describe("Category ID"),
weightGrams: z.number().optional().describe("Weight in grams"),
priceCents: z.number().optional().describe("Price in cents"),
notes: z.string().optional().describe("Notes about the item"),
productUrl: z.string().optional().describe("URL to the product page"),
imageFilename: z
.string()
.optional()
.describe("Filename of an uploaded image"),
imageSourceUrl: z
.string()
.optional()
.describe("Original URL the image was fetched from"),
},
},
{
name: "update_item",
description: "Update an existing item's fields.",
inputSchema: {
type: "object" as const,
properties: {
id: { type: "number", description: "The item ID to update" },
name: { type: "string", description: "Item name" },
categoryId: { type: "number", description: "Category ID" },
weightGrams: { type: "number", description: "Weight in grams" },
priceCents: { type: "number", description: "Price in cents" },
notes: { type: "string", description: "Notes about the item" },
productUrl: { type: "string", description: "URL to the product page" },
imageFilename: {
type: "string",
description: "Filename of an uploaded image",
},
imageSourceUrl: {
type: "string",
description: "Original URL the image was fetched from",
},
},
required: ["id"],
id: z.number().describe("The item ID to update"),
name: z.string().optional().describe("Item name"),
categoryId: z.number().optional().describe("Category ID"),
weightGrams: z.number().optional().describe("Weight in grams"),
priceCents: z.number().optional().describe("Price in cents"),
notes: z.string().optional().describe("Notes about the item"),
productUrl: z.string().optional().describe("URL to the product page"),
imageFilename: z
.string()
.optional()
.describe("Filename of an uploaded image"),
imageSourceUrl: z
.string()
.optional()
.describe("Original URL the image was fetched from"),
},
},
{
name: "delete_item",
description: "Delete an item from the gear collection by ID.",
inputSchema: {
type: "object" as const,
properties: {
id: { type: "number", description: "The item ID to delete" },
},
required: ["id"],
id: z.number().describe("The item ID to delete"),
},
},
];