Skip to content

MCP server: tools/list crashes on enrichment_create — z.union() schema triggers '_zod' TypeError #1

@LucianaCedalio

Description

@LucianaCedalio

Summary

instantly mcp registers all 171 tools successfully, but every tools/list request fails with:

Cannot read properties of undefined (reading '_zod')

As a result, no MCP client can enumerate any tools — the server is effectively unusable end-to-end, even though the stdio handshake and tool registration succeed.

Environment

  • instantly-cli@0.1.17 (latest)
  • Node v20.20.2, macOS
  • @modelcontextprotocol/sdk@1.29.0 (bundled)
  • zod@4.3.6 (bundled)

Repro

export INSTANTLY_API_KEY=...
(printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'; \
 sleep 2) | instantly mcp

Observed:

Instantly MCP server started. Tools registered: 171
{"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message":"Cannot read properties of undefined (reading '_zod')"}}

Root cause

I patched the vendored @modelcontextprotocol/sdk ListToolsRequestSchema handler to wrap each tool's serialization in a try/catch and log the failing name. One and only one of the 171 tools triggers the crash:

[BROKEN TOOL] enrichment_create: Cannot read properties of undefined (reading '_zod')

Looking at dist/index.js around the enrichmentCreateCommand definition (≈line 3188), its inputSchema is the only schema in the whole CLI that uses z.union([...]):

inputSchema: z72.object({
  resource_id: z72.string().describe(...),
  type: z72.enum(ENRICHMENT_TYPES).describe(...),
  limit: z72.coerce.number().optional().describe(...),
  filters: z72.union([                                    // <-- unique in the codebase
    z72.string(),
    z72.array(z72.record(z72.unknown()))
  ]).optional().describe(...),
  custom_flow: z72.string().optional().describe(...)
}),

grep -c "z\.union\|z72\.union" across dist/index.js returns 1. That single z.union is the crash trigger — the SDK's toJsonSchemaCompat(..., { strictUnions: true, pipeStrategy: 'input' }) path (called from server/mcp.js ListToolsRequestSchema handler) dereferences ._zod on something undefined when walking the union branches in zod v4 Mini's compat layer.

Skipping enrichment_create via a try/catch patch returns the other 170 tools correctly and the MCP becomes fully functional.

Suggested fixes (pick one)

  1. Quick: replace the union with two separate optional fields, or accept a string and JSON-parse it in the handler (the handler already does typeof input.filters === "string" ? JSON.parse(input.filters) : input.filters, so a plain z.string() plus validation at call time would work).
  2. Correct: bump @modelcontextprotocol/sdk if a later version handles v4 unions + z.record(z.unknown()) inside arrays correctly, or drop strictUnions: true for the tools/list serialization.

Happy to PR the first option if useful.

Impact

Until fixed, any MCP client (Claude Desktop, Cursor, Gemini CLI) connecting to instantly mcp sees zero tools — the server is unusable without a manual patch to the vendored SDK.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions