LearnNewsExamplesServices
Frontmatter
id10064
titleMCP: OpenApiValidator emits array schemas without items, crashing strict validators (Copilot)
stateClosed
labels
bugai
assigneestobiu
createdAtApr 18, 2026, 7:46 PM
updatedAtMay 15, 2026, 2:42 PM
githubUrlhttps://github.com/neomjs/neo/issues/10064
authortobiu
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtApr 18, 2026, 7:58 PM

MCP: OpenApiValidator emits array schemas without items, crashing strict validators (Copilot)

tobiu
tobiu commented on Apr 18, 2026, 7:46 PM

Problem

GitHub Copilot (via its Neural Link bridge) crashes when listing neo.mjs-neural-link tools:

Failed to validate tool mcp_neo_mjs-neura_call_method: Error: tool parameters array type must have items. Please open an issue for the MCP server or extension which provides this tool

Claude Desktop / Cursor tolerate the malformed schema; Copilot's validator is strictly draft-compliant and rejects any {"type":"array"} lacking items.

Architectural Reality

Three-stage pipeline produces the defect:

  1. ai/mcp/server/neural-link/openapi.yaml at CallMethodRequest.properties.args (and three /data/store/inspect response properties) declares type: array with no items — permitted by OpenAPI 3.x but ambiguous.
  2. ai/mcp/validation/OpenApiValidator.mjs:115-116 fallback produces z.array(z.any()) (correct Zod behavior).
  3. zod-to-json-schema with target: 'openApi3' serializes z.array(z.any()) as {"type":"array"}silently strips items. Verified:
       zodToJsonSchema(z.array(z.any()),     {target:'openApi3'}) === {"type":"array"}                  // bug
    zodToJsonSchema(z.array(z.unknown()), {target:'openApi3'}) === {"type":"array","items":{}}       // fix

This is orthogonal to prior fixes:

  • #10043 (closed) removed the hardcoded z.array(z.string()) regression.
  • #9837 (open) covers nested array schemas.
  • This ticket covers arrays with no items at all — the residual third case.

Blast Radius (audited)

Only neural-link/openapi.yaml is affected. Four locations:

  • .components.schemas.CallMethodRequest.properties.argsbreaks call_method on Copilot
  • /data/store/inspect response: .properties.filters, .properties.sorters, .properties.items — breaks inspect_store output schema (if validated)

The other four MCP servers are clean.

Proposed Fix (Two Layers)

Layer 1 — defense-in-depth in ai/mcp/validation/OpenApiValidator.mjs:116:

- zodSchema = z.array(z.any());
+ zodSchema = z.array(z.unknown());

z.unknown() round-trips through zod-to-json-schema as items: {}, forcing a compliant emission regardless of YAML quality.

Layer 2 — source-of-truth in ai/mcp/server/neural-link/openapi.yaml:

  • CallMethodRequest.args → add items: {} (heterogeneous method args, intentionally untyped)
  • /data/store/inspect response filters, sorters, items → add items: {type: object}

Avoided "Gold Standards" / Traps

  • Rejected: Forcing z.array(z.string()) fallback. That was the regression #10043 fixed — would break typed args.
  • Rejected: Post-processing the emitted JSON Schema to inject items: {}. Adds a second serialization layer; z.unknown() achieves the same outcome natively in Zod.
  • Rejected: Silently widening every array on the YAML side. We want the YAML to remain the source of intent; Layer 1 exists as safety net, not primary contract.

Verification

Permanent Playwright regression test (per AGENTS.md §10 rule 3) that calls listTools on the neural-link server and asserts every array-typed schema node includes an items property.

Origin Session ID

97343e6e-9d1c-4170-b3a5-6e58d41511b6

tobiu added the bug label on Apr 18, 2026, 7:46 PM
tobiu added the ai label on Apr 18, 2026, 7:46 PM
tobiu referenced in commit 3ef1c0a - "fix(mcp): emit items for array schemas to satisfy strict validators (#10064)" on Apr 18, 2026, 7:50 PM
tobiu cross-referenced by PR #10065 on Apr 18, 2026, 7:51 PM
tobiu assigned to @tobiu on Apr 18, 2026, 7:53 PM
tobiu referenced in commit 779183f - "fix(mcp): emit items for array schemas to satisfy strict validators (#10064) (#10065)" on Apr 18, 2026, 7:58 PM
tobiu closed this issue on Apr 18, 2026, 7:58 PM
tobiu cross-referenced by PR #10066 on Apr 18, 2026, 8:42 PM
tobiu cross-referenced by #9837 on Apr 18, 2026, 9:08 PM
tobiu cross-referenced by PR #10067 on Apr 18, 2026, 9:18 PM
tobiu cross-referenced by PR #10071 on Apr 18, 2026, 10:50 PM