confetti / confetti/confetti-node
schemaToJsonSchema discards helpText/placeholder/values — the only field documentation consumers have
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 51m
- Merged PRs (30d)
- 2
Description
What happens
src/utils/to-json-schema.ts strips the meta keys that carry the human-written documentation:
const metaKeysToStrip = ['label', 'helpText', 'placeholder', 'values']
// ...
for (const key of metaKeysToStrip) delete ctx.jsonSchema[key]
Those are removed because they are not standard JSON Schema keywords — which is correct — but the information is then simply lost, rather than mapped onto the keywords that do exist.
Why it matters
schemaToJsonSchema is exported from the package root, so its output is what consumers hand to an LLM as a tool schema. Building an MCP server on this package, we measured 135 of 340 input fields (40%) carrying any description. Recovering the stripped meta ourselves moved that to 56%.
The fields that lose most are the ones a caller cannot guess:
ticket.sendEmailConfirmationis required, and its strippedhelpTextis the only place that says it sends the invite email. A model setting ittrue"to be safe" emails real attendees.ticket.ticketBatchId's strippedhelpTextis "Required for ticket events" — the only statement of that rule.ticket.statusserialises asanyOf[string, array-of-enum], so its valid values (attending,invited) exist only in the strippedvaluesmeta and are invisible in the schema.contact.phone's format example+46701234567is stripped.
Suggested fix
Fold the meta into the standard keywords rather than deleting it:
const meta = ctx.zodSchema.meta?.() ?? {}
const extra = [meta.helpText, meta.placeholder && `Example: ${meta.placeholder}`]
.filter(Boolean).join(' ')
if (!ctx.jsonSchema.description && extra) ctx.jsonSchema.description = extra
if (Array.isArray(meta.values) && meta.values.every(v => typeof v === 'string')) {
// enum is the standard keyword for exactly this
ctx.jsonSchema.enum ??= meta.values
}
for (const key of metaKeysToStrip) delete ctx.jsonSchema[key]
label is not worth mapping — of 131 occurrences, nearly all are Title-Case echoes of the field name ("Rsvp Limit"), which add nothing.
This is a few lines in one function and it would improve every consumer at once. We currently reimplement it downstream by walking the Zod shape in parallel with the generated schema, which is strictly worse than doing it here.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/utils/to-json-schema.ts at schemaToJsonSchema and inspect how the Zod metadata is available before metaKeysToStrip is applied. Done means helpText and placeholder information can appear in standard descriptions, string values can become enum values, and the nonstandard metadata keys are still absent from the generated schema.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100