You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
api: advertised tool schemas drift from the pydantic models and unknown keys are silently ignored (C-10, M-02) #236
From the 2026-09-01 codebase review (plans/codebase-review-2026-09-01.md), C-10 (MEDIUM, reproduced) with M-02.
The tool input schemas advertised over MCP are maintained by hand, separately from the pydantic models that actually validate the arguments. Two failure modes follow:
Drift: the advertised schema and the enforced model disagree, so an agent that obeys the published contract can still be rejected — and worse, a schema can keep advertising a parameter the model no longer honours.
Silent acceptance: the models do not set extra="forbid", so a misspelled or hallucinated key is accepted and ignored rather than refused. For an agent-facing API this is the wrong default: the caller gets success and different behaviour than it asked for, with nothing to notice.
Fix (review's estimate: M): generate the advertised schemas from the pydantic models, and set extra="forbid". Generation removes the drift by construction rather than by discipline.
Worth pinning with a test in the drift direction specifically — a test that asserts "the advertised schema equals the model's schema" for every registered tool will fail the moment someone hand-edits one, which is the regression that matters. Note that extra="forbid" is a behaviour change for existing callers that currently send extra keys and get away with it; that deserves a CHANGELOG note and possibly a release-note callout.
Status: the plan merged as #291 and piece A merged as #300 (cdaf3c6). Advertised gateway tool schemas are now derived from their models, and unregistered names fail closed.
#296 (record tools/call gate rejections in the scoped audit) is merged as #306, so piece B (extra="forbid") is no longer blocked by it. #301 (the pre-release host tools/list smoke test for piece A) is still open.
SchemaRouter overlap / possible benchmark question:
PMCP already solves progressive disclosure and schema-on-demand at the gateway layer. SchemaRouter is a typed capability retrieval layer that indexes provider/endpoint/field semantics while leaving execution authority with the host.
Rather than proposing a competing gateway, I'd be interested in a reproducible comparison on the same downstream catalog: PMCP native discovery vs typed field-aware preselection feeding PMCP, measuring required-tool recall, unsupported/no-route rejection, revealed schema bytes, shortlist size, and routing latency.
This also seems adjacent to #236: SchemaRouter can consume generated schemas, but PMCP should remain authoritative for schema generation/validation and execution. The useful question is only whether field-level retrieval improves discovery once that schema contract is trustworthy.
Thanks for the thoughtful note, and for offering to report negative results as they come. We're going to pass on a joint or co-run comparison: pmcp isn't taking part in or endorsing outside benchmarks. We do agree discovery quality is worth measuring, and we plan to publish our own reproducible discovery benchmark for pmcp. Anyone, including SchemaRouter, will be welcome to run it independently. Best of luck with the project.
Activity
docs(plan): embed the measurement probe and de-session the executor i…
wip(schemas): keep the hand-written argument descriptions; walk nulla…
docs(plan): revision 2 — A1/A2/A3/X1 from the board (see #236)
docs(plan): re-embed piece A from d0722f4; descriptions resolved to o…
wip(schemas): fail closed on an unregistered name inside the audited …
docs(plan): board round 2 — X1 structural, F1-F5; re-embed piece A from
wip(schemas): guard before the scoped-audit check; digest lengths pin…
test(schemas): the module docstring names the regex-dialect class too…
docs(plan): board round 3 — N1-N4; re-embed piece A from 972bc90 (see #…
docs(plan): re-embed the test module from a25dce0; drop the docstring…
wip(schemas): advertise task.ttl's int64 bound (see #236)
docs(plan): board round 4 — F1 integer range; re-embed piece A from c…
wip(schemas): task.ttl bounded on both sides; every advertised intege…
docs(plan): board round 5 — G1 integer range both sides; re-embed pie…
wip(schemas): task.ttl's lower bound stops one short of float(-2**63)…
1 remaining item
docs(plan): board round 6 — exhaustive differential class table, N6-1…
docs(plan): re-embed the test module from 3d0d437; drop the docstring…
test(schemas): the docstring states the ttl bounds and the open class…
docs(plan): board round 7 — class 7 two-sided, row 8 = 804; re-embed …
docs(plan): quote the test docstring as it reads at cb6afa4 (see #236)
docs(plan): derive the gateway's advertised tool schemas from their m…
feat(schemas): derive the gateway's advertised tool schemas from thei…
ViperJuice commentedon Sep 26, 2026
Status: the plan merged as #291 and piece A merged as #300 (
cdaf3c6). Advertised gateway tool schemas are now derived from their models, and unregistered names fail closed.Remaining for this issue:
extra="forbid") is gated on Record tools/call gate rejections in the scoped-advisor audit (prerequisite for piece B of #236) #296, which records gate rejections in the scoped audit.tools/listsmoke test for nullable schema types).task.ttlnegatives,poll_intervalNaN/Infinity/range).docs(plan): rev 4 rebased on main 876fd33 (see #296)
docs(plan): record tools/call gate rejections in the scoped audit (see …
ViperJuice commentedon Sep 27, 2026
#296 (record tools/call gate rejections in the scoped audit) is merged as #306, so piece B (
extra="forbid") is no longer blocked by it. #301 (the pre-release host tools/list smoke test for piece A) is still open.🤖 Generated with Claude Code
JDeun commentedon Oct 2, 2026
SchemaRouter overlap / possible benchmark question:
PMCP already solves progressive disclosure and schema-on-demand at the gateway layer. SchemaRouter is a typed capability retrieval layer that indexes provider/endpoint/field semantics while leaving execution authority with the host.
Rather than proposing a competing gateway, I'd be interested in a reproducible comparison on the same downstream catalog: PMCP native discovery vs typed field-aware preselection feeding PMCP, measuring required-tool recall, unsupported/no-route rejection, revealed schema bytes, shortlist size, and routing latency.
This also seems adjacent to #236: SchemaRouter can consume generated schemas, but PMCP should remain authoritative for schema generation/validation and execution. The useful question is only whether field-level retrieval improves discovery once that schema contract is trustworthy.
If this boundary is useful, I can prepare an optional benchmark/example and report negative results as-is. SchemaRouter: https://github.com/JDeun/SchemaRouter
docs: resolve the #358 panel's text findings
ViperJuice commentedon Oct 5, 2026
Thanks for the thoughtful note, and for offering to report negative results as they come. We're going to pass on a joint or co-run comparison: pmcp isn't taking part in or endorsing outside benchmarks. We do agree discovery quality is worth measuring, and we plan to publish our own reproducible discovery benchmark for pmcp. Anyone, including SchemaRouter, will be welcome to run it independently. Best of luck with the project.
docs(plan): rev 2 -- rebased on b8e4305; unfold nullable refusals bef…