Skip to content

fix: preprocess JSON string params in Zod schemas for MCP compatibility#607

Open
Yanndotai wants to merge 1 commit intoczlonkowski:mainfrom
Yanndotai:fix/preprocess-json-string-params
Open

fix: preprocess JSON string params in Zod schemas for MCP compatibility#607
Yanndotai wants to merge 1 commit intoczlonkowski:mainfrom
Yanndotai:fix/preprocess-json-string-params

Conversation

@Yanndotai
Copy link
Copy Markdown

Summary

  • Some MCP clients (e.g. Claude Code) serialize array and object tool parameters as JSON strings instead of native JavaScript types
  • This causes Zod validation to fail with Expected array, received string on n8n_update_partial_workflow, n8n_update_full_workflow, and n8n_create_workflow
  • Added z.preprocess() wrappers that transparently parse JSON strings back to arrays/objects before validation, while leaving native types untouched

Affected schemas

  • workflowDiffSchemaoperations field
  • createWorkflowSchemanodes, connections fields
  • updateWorkflowSchemanodes, connections, settings fields

How it works

const jsonArrayPreprocess = (val: unknown): unknown => {
  if (typeof val === 'string') {
    try { const parsed = JSON.parse(val); if (Array.isArray(parsed)) return parsed; } catch {}
  }
  return val;
};

// Before: fails when MCP client sends string
operations: z.array(z.object({...}))

// After: transparently handles both string and native array
operations: z.preprocess(jsonArrayPreprocess, z.array(z.object({...})))

Test plan

  • TypeScript build passes with no errors
  • Tested with Claude Code MCP client: n8n_update_partial_workflow now accepts operations as JSON string
  • Tested with Claude Code MCP client: n8n_update_full_workflow now accepts nodes and connections as JSON strings
  • Native array/object parameters continue to work unchanged (preprocess is a no-op for non-string values)

Some MCP clients (e.g. Claude Code) serialize array and object parameters
as JSON strings instead of native types. This causes Zod validation to
fail with "Expected array, received string" on tools like
n8n_update_partial_workflow, n8n_update_full_workflow, and
n8n_create_workflow.

Add z.preprocess() wrappers that transparently parse JSON strings back
to arrays/objects before validation, while leaving native types untouched.

Affected schemas:
- workflowDiffSchema (operations)
- createWorkflowSchema (nodes, connections)
- updateWorkflowSchema (nodes, connections, settings)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant