Status: implemented
toJsonSchema(s) writes a schema as a JSON Schema of draft 2020-12, the form an MCP server advertises as a tool's inputSchema.
toJsonSchema({ id: bigint, note: or(option, string) })
// { "type": "object",
// "properties": { "id": { "type": "integer" }, "note": { "type": "string" } },
// "required": ["id"],
// "additionalProperties": { "not": {} } }
It goes through the data form, so two spellings of one set usually write one JSON Schema (the exceptions are the data form's own known limits), a union's members come in canonical order, and a recursive schema is written once under $defs and referred to with $ref.
| rtti | JSON Schema |
|---|---|
boolean, number, string | { "type": … } |
bigint | { "type": "integer" } |
unknown | {} |
never, the constant undefined | { "not": {} } |
| a constant | { "const": … } |
| a struct | properties, required for the keys excluding absence, additionalProperties for the rest |
| a tuple | prefixItems, minItems for the positions excluding absence, items for the rest |
array(t), record(t) | items, additionalProperties |
or(…) | anyOf, or one type when the union is a whole kind |
JSON cannot write every value a schema describes, so the conversion is lossy. These are the cases:
- a
bigintbecomes an integer, and a bigint constant the nearest double:9007199254740993nis written9007199254740992; -0is a constant of its own to rtti, but JSON Schema compares numbers by value, sotoJsonSchema(-0),{ "const": -0 }, admits0as well;undefinedhas no JSON value, so the constant becomes{ "not": {} };NaNand the infinities are numbers to rtti and not JSON values at all;- JSON has no holes, so absence is kept only at the end of a tuple:
[or(option, number), string]admits[, 'x'], and its JSON Schema requires both positions ("minItems": 2).
The demo on this page runs the Lossy integers lesson: { id: bigint, max: 9007199254740993n, note: or(option, string) }, whose JSON Schema has "type": "integer" for id, the constant 9007199254740992 for max, and only id and max under required. The lesson is defined in sample.f.mjs, and the module page's demo lists it among all the others.
- JSON Schema: the reference and
$defsand$ref
toJsonSchema and dataToJsonSchema in media/json/schema, which also declares JSON Schema itself as an rtti schema.