Skip to content

t27mcp: tool_schema.t27 -- one row per tool and per field, so the MCP JSON schemas are generated, not written by hand (Closes #10444) - #10446

Merged
gHashTag merged 1 commit into
masterfrom
claude/peaceful-jennings-de9177
Oct 18, 2026
Merged

gHashTag merged 1 commit into
masterfrom
claude/peaceful-jennings-de9177

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #10444

What

specs/t27mcp/tool_schema.t27 (module T27mcpToolSchema) declares the input and output schema of every tool of the t27 MCP server (gHashTag/t27-mcp): 27 tool rows (the 26 on t27-mcp master plus t27_paper_claims from t27-mcp#23) and 270 field rows. The MCP JSON schemas are generated from it by t27c gen-js and a table-driven builder in t27-mcp (companion PR there). The idea comes from the morluto/rea 6.6.0 "MCP contracts" fix: self-contained inputs, tuple/array/boolean/nested-object constraints kept in every profile, the output-schema profile in the catalog identity.

The catalog identity is this spec's seal spec_hash plus the output profile, so a client can tell that a schema changed. The seal is committed here (.trinity/seals/t27mcp_T27mcpToolSchema.json).

Measured: before and after

Measured on t27-mcp master (792c0e4) by reading server.mjs and telegram.mjs.

Before After
No tool declared an outputSchema (0 of 26) 15 of 27 tools declare an object output (t27_format as a bare object, because it returns a catalog row of open shape); the other 12 are honest: 11 return text (4 t27* and the 7 tg_*), t27_raw returns arbitrary JSON
Integer fields typed number, unbounded: limit (x6), maxSpecs, maxHitsPerSpec, bits, minLines, maxLines, Telegram limit (x5) integer with minimum; maxSpecs 1..150, find.limit 1..20, Telegram limit 0..100
Closed sets typed as free string: health, status, sort, state, paper, verdict enums: ok/warn/fail, five catalog statuses, eight sort keys (incl. the depth and bytes the handler already accepts), open/closed, paper and verdict sets
t27f_view ranges undeclared: scene, preset, look, status, labels, rows scene 0..4, preset 0..2, look 0..1, status array of at most 27 items each 0..255, labels at most 27, rows at most 4
t27f_graph.fixture undeclared range 0..1
t27_raw.path no description or pattern pattern ^/[^/] and a description
Telegram chat a bare string, required: [] on tools that need an argument pattern of telegram.t27's chat rule; chat and query required; query 1..200 characters
t27f_outline.path and t27f_graph.path free strings pattern for a corpus .t27 path
fresh, ref, fields, source mostly without description described once as shared constants
No input refused unknown keys every top-level input object gets additionalProperties: false
required and enums only in prose machine-readable rows
8 tools copied the same filter block one G_SPEC_FILTERS group
No catalog identity seal hash + profile
Tuples: none existed t27_game rules.cycle is a five-step tuple (prefixItems + minItems/maxItems)

Not done here: defaults are still in descriptions ("Default 50"), not a default column.

Tests

t27c test-report specs/t27mcp/tool_schema.t27 on the Railway lab: 12 of 12 pass, 0 vacuous. Covers table sizes and names, unique tool names, contiguous blocks, per-row laws (depth steps, names vs parent kind, child counts, bounds, enum/pattern only on strings, required/nullable), unique property names, every tool has rows or declares text/any, the filter group, the input constraints that used to be missing (23 integers, 6 enums, 6 patterns), and fixtures for a tuple, nested arrays/objects, a required boolean and a bounded array. Three negative-control tests prove the laws can fail. Mutating the cycle tuple's hi from 5 to 6 fails 2 tests.

t27c gen-js accepts the struct arrays and emits wasm/tool_schema_table.mjs in t27-mcp.

Language budget

No hand-written non-t27 code in this PR.

🤖 Generated with Claude Code

… JSON schemas are generated, not written by hand (Closes #10444)

27 tools (26 on t27-mcp master plus t27_paper_claims), 270 field rows,
inputs and outputs, with tuple, array, boolean, nested-object, enum,
pattern and bounds rows; the spec filters of t27_specs and t27_grep are
one group. 12 tests, 0 vacuous, negative controls for step, name,
children, bounds, text and flags laws. Its seal hash is the catalog
identity a client caches.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-18 12:03:25 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 49
PRs with All Checks Green 1
READY 0
FAILING 49
PENDING 0
NO CHECKS YET 0

These columns do not partition: 0 + 49 + 0 + 0 = 49, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=fad12492937a != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag enabled auto-merge (squash) October 18, 2026 12:18
@gHashTag
gHashTag merged commit b200c3a into master Oct 18, 2026
28 of 31 checks passed
gHashTag added a commit that referenced this pull request Oct 18, 2026
… with provider/schema's Tool (Closes #10459) (#10460)

#10446 added a second type named Tool beside specs/provider/schema.t27's Tool,
and the types ratchet on master turned red ("+ Tool NEW conflict"). The newer
one is renamed; the spec is resealed (12/12 tests, 0 vacuous) and
tri types ratchet is CLEAN on the lab.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t27mcp: one spec declares every tool's input and output schema; the MCP JSON schemas are generated from it

1 participant