Repository navigation
t27mcp: one spec declares every tool's input and output schema; the MCP JSON schemas are generated from it #10444
Description
Boundary
The t27 MCP server (gHashTag/t27-mcp) declares each tool's inputSchema by hand in server.mjs and telegram.mjs, and no tool declares an outputSchema. MCP schemas are plumbing a client parses, so by the own-language-first rule they are generated from a .t27 source, never hand-written.
In scope: one spec, specs/t27mcp/tool_schema.t27, with one row per tool and one row per input or output field; its seal; and, in gHashTag/t27-mcp, a generated wasm/tool_schema_table.mjs, a table-driven builder that replaces the inline schemas, and smoke checks. Out of scope: changing what any tool returns, and new tools. No hand-written foreign logic: the glue in t27-mcp is net <= 0 lines.
User Scenarios
- A client calls
tools/listand reads aninputSchemain whichlimitis anintegerwith a minimum,healthis an enum,statusoft27f_viewis an array of at most 27 items each 0..255, andchatof a Telegram tool has the pattern the server enforces. It no longer finds out by failing a call. - A client that cached the catalog sees
_meta["t27/catalog"]change when the spec changes, because the identity is the spec's seal hash plus the output profile. - An author who adds a tool without a row in the spec gets a startup error, not a silently loose schema.
- A client that opts into the output profile receives
outputSchemaand matchingstructuredContent; a client that does not, receives neither (protocol 2024-11-05 has nooutputSchema).
Requirements
specs/t27mcp/tool_schema.t27lists every advertised tool (27 with t27_paper_claims: recompute the numbers printed in the GoldenFloat, Golden Ruler and TNF papers t27-mcp#23) and, per tool, input fields and output fields as rows with kind, required, nullable, bounds, enum, pattern and description. Tuple, array, boolean and nested-object rows are all expressible; the shared spec filters oft27_specsandt27_grepare one group, not two copies.- The spec's tests cover: every row well formed, property names unique, every tool has rows (or declares a text or any result), tuple/array/nested fixtures, and negative controls. 0 vacuous.
t27c gen-jsproduces the table; the JSON Schema is built from it. Inputs are self-contained: no$ref, nodefinitions,additionalProperties: falseat the top. A tuple isprefixItemsplusminItems/maxItems, so it holds in draft-07 and 2020-12 readers.- The catalog identity is
<spec_hash>/p<profile>, carried intools/list_meta. The vendored seal is checked against the table at build. - Two profiles: inputs only (default, protocol 2024-11-05) and inputs plus outputs (opt-in, 2025-06-18, with
structuredContent).
Success Criteria
t27c test-report specs/t27mcp/tool_schema.t27is all pass with 0 vacuous, and a mutated row fails a test.smoke.mjsin t27-mcp asserts every advertised tool has a row, no$refappears in any schema, and the tuple, array, boolean and nested-object constraints survive the round trip.- Lines of hand-written JS in t27-mcp: net <= 0 across the PR.
- The PR lists the tools whose schema was missing or loose before, and what each looks like after.
Requirements
FR-001: The spec specs/t27mcp/tool_schema.t27 MUST list every advertised tool (27 with gHashTag/t27-mcp#23) and, per tool, input fields and output fields as rows with kind, required, nullable, bounds, enum, pattern, and description. Tuple, array, boolean, and nested-object rows MUST be expressible; the shared spec filters of t27_specs and t27_grep MUST be one group, not two copies.
FR-002: The spec's tests MUST cover: every row well formed, property names unique, every tool has rows (or declares a text or any result), tuple/array/nested fixtures, and negative controls. There MUST be 0 vacuous tests.
FR-003: t27c gen-js MUST produce the table; the JSON Schema MUST be built from it. Inputs MUST be self-contained: no $ref, no definitions, additionalProperties: false at the top. A tuple MUST be prefixItems plus minItems/maxItems, so it holds in draft-07 and 2020-12 readers.
FR-004: The catalog identity MUST be <spec_hash>/p<profile>, carried in tools/list _meta. The vendored seal MUST be checked against the table at build.
FR-005: Two profiles MUST exist: inputs only (default, protocol 2024-11-05) and inputs plus outputs (opt-in, 2025-06-18, with structuredContent).
Activity
t27mcp: tool_schema.t27 -- one row per tool and per field, so the MCP…
github-actions commentedon Oct 18, 2026
Closed by the issue-shape gate (specs/policy/issue_shape.t27, #7498): an issue must have the template's sections. Edit the body; an edit that passes reopens it.
FR-001: ... MUST ...t27mcp: tool_schema.t27 -- one row per tool and per field, so the MCP…