How Zod Schemas Are Converted to MCP Tool Definitions in DesktopCommanderMCP

DesktopCommanderMCP converts Zod schemas to MCP tool definitions by mapping each tool's argument schema in src/server.ts and transforming them into JSON Schema using the zodToJsonSchema function from the zod-to-json-schema library, which is then attached as the inputSchema field in tool definitions sent to clients.

The DesktopCommanderMCP repository implements a type-safe pipeline for defining tool arguments using Zod schemas located in src/tools/schemas.ts. When the MCP server initializes and prepares tool definitions for client consumption, these TypeScript-first schemas are dynamically converted into standard JSON Schema format that any MCP-compatible client can parse for validation, form generation, or LLM prompt engineering.

The Zod Schema Definition Layer

All argument validation schemas are centralized in src/tools/schemas.ts. Each tool exports a Zod object schema that defines required parameters, optional fields, default values, and type constraints. This file serves as the single source of truth for both runtime validation and schema documentation.

Defining Arguments in schemas.ts

The repository defines schemas using standard Zod object constructors. For example, the read_file tool uses the following schema definition:

import { z } from "zod";

export const ReadFileArgsSchema = z.object({
  path: z.string(),
  isUrl: z.boolean().optional().default(false),
  offset: z.number().optional().default(0),
  length: z.number().optional().default(1000),
  sheet: z.string().optional(),
  range: z.string().optional(),
  options: z.record(z.any()).optional(),
  origin: z.enum(['ui', 'llm']).optional(),
});

This schema enforces that path is a required string while providing sensible defaults for pagination parameters like offset and length.

Mapping Schemas to Tool Names

The conversion process relies on a registry called toolArgSchemas that is imported into src/server.ts from the schemas module. This object maps string tool names to their corresponding Zod schema objects, creating a lookup table that the server uses during tool registration.

When the server prepares its tool list for the list_tools RPC response, it iterates through the available tool implementations and retrieves the matching Zod schema from this registry. This decouples the validation logic from the tool implementation while maintaining type safety.

Converting to JSON Schema for MCP Clients

MCP clients expect tool argument specifications in JSON Schema format rather than Zod objects. The conversion happens during server initialization when constructing the tool definition array.

Using zodToJsonSchema

The server imports the zodToJsonSchema function from the zod-to-json-schema package to handle the transformation. This utility converts Zod object schemas into valid JSON Schema (Draft 7 or 2019-09) while preserving type information, required field arrays, and default values.

Attaching inputSchema to Tool Definitions

The resulting JSON Schema object is assigned to the inputSchema property of each tool definition. This standardized field name is part of the MCP protocol specification, allowing clients to understand exactly what arguments each tool expects without needing to parse TypeScript or Zod-specific syntax.

import { toolArgSchemas } from "./tools/schemas.js";
import { zodToJsonSchema } from "zod-to-json-schema";

// Constructing tool definitions for list_tools response
const allTools = Object.entries(toolImpls).map(([name, impl]) => ({
  name,
  description: impl.description,
  inputSchema: zodToJsonSchema(toolArgSchemas[name]),
}));

Complete Example: From Zod to Client Response

Consider the complete flow for the read_file tool. First, the Zod schema is defined in src/tools/schemas.ts as shown above. When the server starts, it processes this schema through the conversion pipeline:

// Server-side conversion (src/server.ts)
const toolDefinition = {
  name: "read_file",
  description: "Read a file from the filesystem",
  inputSchema: zodToJsonSchema(ReadFileArgsSchema)
};

The resulting JSON Schema sent to the client looks like this:

{
  "name": "read_file",
  "description": "Read a file from the filesystem",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": { "type": "string" },
      "isUrl": { "type": "boolean", "default": false },
      "offset": { "type": "number", "default": 0 },
      "length": { "type": "number", "default": 1000 },
      "sheet": { "type": "string" },
      "range": { "type": "string" },
      "options": { "type": "object", "additionalProperties": true },
      "origin": { "type": "string", "enum": ["ui", "llm"] }
    },
    "required": ["path"]
  }
}

This JSON Schema preserves the optional flags, default values, and enum constraints defined in the original Zod schema, enabling clients to generate accurate UI forms or validation logic.

Summary

  • Zod schemas are defined in src/tools/schemas.ts to provide TypeScript-first argument validation with automatic type inference.
  • The toolArgSchemas registry in src/server.ts maps each tool name to its corresponding Zod schema object.
  • zodToJsonSchema converts Zod definitions to standard JSON Schema format during server initialization, preserving types, defaults, and constraints.
  • Converted schemas are attached to the inputSchema field in tool definitions returned by the list_tools RPC method.
  • MCP clients receive standard JSON Schema compatible with form generators, validation libraries, and LLM function-calling specifications.

Frequently Asked Questions

What library does DesktopCommanderMCP use to convert Zod schemas to JSON Schema?

DesktopCommanderMCP uses the zod-to-json-schema npm package. The server imports the zodToJsonSchema function in src/server.ts and calls it for each tool schema when constructing the tool list for MCP clients.

Where are the Zod schemas for tool arguments defined?

All argument schemas are defined and exported from src/tools/schemas.ts. Each tool has a corresponding Zod object schema (such as ReadFileArgsSchema or EditBlockArgsSchema) that validates incoming arguments before the tool logic executes.

How does the MCP client receive the schema information?

The client receives schemas through the inputSchema field in each tool definition during the list_tools RPC call. This field contains the JSON Schema representation derived from the original Zod schema, allowing clients to understand expected parameters without accessing the server's TypeScript code.

Are optional fields and default values preserved in the conversion?

Yes, the zodToJsonSchema function preserves Zod-specific metadata including optional fields, default values, and enum constraints. The resulting JSON Schema accurately reflects the intended argument structure, enabling clients to pre-populate forms with default values or mark fields as optional in the UI.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →