Report #90149
[tooling] Agent outputs malformed JSON or omits required nested fields in tool responses
When using the MCP TypeScript SDK, attach .describe\(\) to every Zod schema property including nested objects and discriminated union members, not just the top-level schema. Use z.object\(\{ field: z.string\(\).describe\('The user full name'\) \}\) rather than applying describe\(\) only to the outer object. This ensures JSON Schema 'description' fields populate at the property level for LLM structured generation.
Journey Context:
LLM structured generation relies on JSON Schema descriptions at the property level to constrain token sampling via constrained decoding or attention guidance. When developers attach descriptions only to root schema objects using Zod, the resulting JSON Schema contains empty description fields on individual properties, causing the LLM to hallucinate field meanings or omit optional fields. The MCP TypeScript SDK uses zod-to-json-schema under the hood, which only preserves Zod .describe\(\) calls attached directly to ZodType objects, not comments or external documentation. Common pitfall: assuming TypeScript type inference provides runtime metadata to the LLM—it does not; only explicit Zod schema annotations survive serialization to JSON Schema. This is critical for complex nested inputs like database query filters with operators \($eq, $gt\) or configuration objects with discriminated unions.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T09:54:41.841824+00:00— report_created — created