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
mcpx: JSON Schema validation of tool inputs/outputs and elicitation schemas (7 conformance rows) #1951
Relocated from dezren39/darwin-nix#254 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
Gap key json-schema-validation in docs/spec/conformance-matrix.md: mcpx does not validate tool arguments against inputSchema, structuredContent against outputSchema, or schema dialects (2020-12 default, unsupported-dialect error, no network $ref deref, composition bounds). Needs a validator decision (no new Go dependency without cause; internal/mcpspec has a subset validator for tests).
Acceptance criteria
Tool arguments are validated against inputSchema and structuredContent against outputSchema, with spec-correct errors on failure.
Elicitation schemas are validated with the same mechanism.
Dialect handling matches the matrix: 2020-12 default, unsupported dialect errors, no network $ref dereferencing, composition bounds enforced.
The validator decision (extend internal/mcpspec subset vs a dependency) is recorded on the issue before implementation; no new Go dependency without cause.
Reference implementation worth reading: https://github.com/wileai/codex-connectors-mcp validates tool arguments against each tool's original input schema -- draft-07, 2019-09 and 2020-12 -- without coercing or stripping, before dispatch. All three drafts are feasible: they differ mainly in definitions vs $defs, tuple items vs prefixItems, dependencies vs dependentRequired/dependentSchemas, and $recursiveRef vs $dynamicRef; the schema's $schema says which applies, 2020-12 when absent (the MCP default since 2025-11-25). Tracked under the codex-connectors adoption umbrella.
Related: the 2026-09-30 mcpx conformance set — parent analysis #252, siblings #253, #254, #255, #256, #257, #258, #259 (filed together from docs/spec/conformance-matrix.md in dezren39/nix). Treat the set as one body of work; do not re-file per-gap issues.
Notes: 7 conformance rows under the single gap key json-schema-validation. The body already names the key decision (validator choice) — that decision is the first deliverable, per the acceptance criteria.
Risks: A hand-rolled validator that diverges from 2020-12 semantics on composition bounds; the matrix rows are the test oracle.
Suggested approach: run the conformance rows against the existing internal/mcpspec subset validator first to size the gap before deciding on a dependency.
Triage verdict (task 2306): LARGELY IMPLEMENTED since filing — remainder routed, issue stays open for it.
Verified at developing-today/code main 35726e8e (mcpx source lives in pkgs/mcpx there):
Validator decision (acceptance 4): taken and recorded in pkgs/mcpx/docs/schema-validation.md and the internal/schemaval package doc — a dedicated runtime validator wrapping github.com/santhosh-tekuri/jsonschema/v6 (its only import site in the module); internal/mcpspec stays test-only for protocol frames. It was not recorded on this issue before implementation; this comment records it now.
Inputs (acceptance 1, first half): done. internal/mcpclient/schemacheck.go compiles schemas at list time (uncompilable tools excluded with a warning) and validateToolArgs rejects invalid arguments before transport with InvalidParamsError (mcpclient.TestCallToolRejectsInvalidArgumentsBeforeTheTransport).
Outputs (acceptance 1, second half): partial. checkToolOutput validates structuredContent against outputSchema but is warn-only — violations are delivered unchanged, not spec-correct errors. Whether that is the intended policy was never recorded.
Dialects (acceptance 3): done in code — absent $schema = 2020-12; declared dialects limited to 2020-12/2019-09/draft-07/draft-06/draft-04 with a typed UnsupportedDialectError; the compiler refuses all network $ref loading (UnresolvedRefError); schema size bounded at 1 MiB. Matrix rows for these are marked tested (schemaval.TestDeclaredDialectsCompile, schemaval.TestUnsupportedDialect, …).
The matrix still marks json-schema-document-dialects as **gap** #254: no document states which dialects mcpx supports (conformance-matrix.md:1382 and :2070) — stale: docs/schema-validation.md states the dialect policy in full. Update both rows.
Record/implement the structuredContent output policy explicitly (warn-only with rationale, or enforce) in docs/schema-validation.md and on this issue.
Only those two items keep this issue open; do not re-implement the validator.
🤖 Agent note · implementation complete, blocked only on the repo-wide merge-queue freeze (#2403)
Agent: queue worker repo-worker-code, OpenChamber scheduled lane. Task 2875 (claim), escalated to you after three park cycles.
Work is done and verified. PR mcpx: close #1951 remainder — stale dialect-gap rows + structuredContent warn-only policy doc #2190 — queue/2875-1951-schema-dialect-remainder, OPEN / CLEAN / MERGEABLE, all reported checks green (basic: proxy port fallbacks SUCCESS, mcpx conformance basic: spec parity SUCCESS, mcpx basic: test SUCCESS, CodeRabbit neutral). Five files, matching the packet's two items plus the third-row check:
docs/spec/conformance-matrix.md — both json-schema-document-dialects rows (was :1382 / :2070) no longer read **gap** #254; they cite the tests that pin the documented dialect set. The json-schema-bound-composition-cost row (n/a: no validator) was also stale and now cites schemaval.TestSchemaTooLarge (the 1 MiB MaxSchemaBytes bound).
docs/spec/requirements.md — the two catalogue rows updated to match (matrix is generated from these).
internal/conformance/coverage_messages.go — the Server and Client Gap registrations for both IDs removed, replaced by coverage entries with the reason in comments.
Why it is not merged:ci: merge queue ejects every PR — no merge since #2233 (10:57Z), entries dropped 2-6 min into AWAITING_CHECKS #2403. main has not moved since 5a34fa7 (10:57:51Z, ~11 h); every merge-queue entry is ejected with reason=branch_protection_failure within 24–51 s of its required check going green. Ruleset 26115813 has bypass_actors: [], and main's classic protection carries a push restrictions block (users: [], teams: [codeowners], apps: [github-actions]) that the merge group cannot satisfy. This is not a PR defect and not something a worker can change.
Activity
developing-today commentedon Oct 28, 2026
CODE-876
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#254 (verbatim, oldest first):
@dezren39 · 2026-10-02T08:56:04Z
Reference implementation worth reading: https://github.com/wileai/codex-connectors-mcp validates tool arguments against each tool's original input schema -- draft-07, 2019-09 and 2020-12 -- without coercing or stripping, before dispatch. All three drafts are feasible: they differ mainly in
definitionsvs$defs, tupleitemsvsprefixItems,dependenciesvsdependentRequired/dependentSchemas, and$recursiveRefvs$dynamicRef; the schema's$schemasays which applies, 2020-12 when absent (the MCP default since 2025-11-25). Tracked under the codex-connectors adoption umbrella.@dezren39 · 2026-10-27T15:36:06Z
Intake review
Fleet monitor intake pass, 2026-10-27 (repo-fleet-monitor).
Related: the 2026-09-30 mcpx conformance set — parent analysis #252, siblings #253, #254, #255, #256, #257, #258, #259 (filed together from
docs/spec/conformance-matrix.mdin dezren39/nix). Treat the set as one body of work; do not re-file per-gap issues.Notes: 7 conformance rows under the single gap key
json-schema-validation. The body already names the key decision (validator choice) — that decision is the first deliverable, per the acceptance criteria.Risks: A hand-rolled validator that diverges from 2020-12 semantics on composition bounds; the matrix rows are the test oracle.
Suggested approach: run the conformance rows against the existing
internal/mcpspecsubset validator first to size the gap before deciding on a dependency.@dezren39 · 2026-10-28T19:08:57Z
Triage verdict (task 2306): LARGELY IMPLEMENTED since filing — remainder routed, issue stays open for it.
Verified at developing-today/code main
35726e8e(mcpx source lives inpkgs/mcpxthere):pkgs/mcpx/docs/schema-validation.mdand theinternal/schemavalpackage doc — a dedicated runtime validator wrappinggithub.com/santhosh-tekuri/jsonschema/v6(its only import site in the module);internal/mcpspecstays test-only for protocol frames. It was not recorded on this issue before implementation; this comment records it now.internal/mcpclient/schemacheck.gocompiles schemas at list time (uncompilable tools excluded with a warning) andvalidateToolArgsrejects invalid arguments before transport withInvalidParamsError(mcpclient.TestCallToolRejectsInvalidArgumentsBeforeTheTransport).checkToolOutputvalidatesstructuredContentagainstoutputSchemabut is warn-only — violations are delivered unchanged, not spec-correct errors. Whether that is the intended policy was never recorded.$schema= 2020-12; declared dialects limited to 2020-12/2019-09/draft-07/draft-06/draft-04 with a typedUnsupportedDialectError; the compiler refuses all network$refloading (UnresolvedRefError); schema size bounded at 1 MiB. Matrix rows for these are marked tested (schemaval.TestDeclaredDialectsCompile,schemaval.TestUnsupportedDialect, …).Remainder (2 items), routed as task 2486 (queue
repo-health-nix-pilot, deduperepo-health:v1:fix:dezren39/nix:issue:254):json-schema-document-dialectsas**gap** #254: no document states which dialects mcpx supports(conformance-matrix.md:1382and:2070) — stale:docs/schema-validation.mdstates the dialect policy in full. Update both rows.docs/schema-validation.mdand on this issue.Only those two items keep this issue open; do not re-implement the validator.
dezren39 commentedon Oct 28, 2026
🤖 Agent note · picked up
158 remaining items
dezren39 commentedon Oct 29, 2026
🤖 Agent note · parked
16c54b1completed with no findings), but its merge-queue entry — enqueued this shift, position 1, AWAITING_CHECKS — was ejected after ~2 minutes (mergeQueueEntry null, PR still OPEN), exactly the ci: merge queue ejects every PR — no merge since #2233 (10:57Z), entries dropped 2-6 min into AWAITING_CHECKS #2403 pattern. Datapoint posted on ci: merge queue ejects every PR — no merge since #2233 (10:57Z), entries dropped 2-6 min into AWAITING_CHECKS #2403.dezren39 commentedon Oct 29, 2026
🤖 Agent note · parked
5a34fa70, ci: merge queue ejects every PR — no merge since #2233 (10:57Z), entries dropped 2-6 min into AWAITING_CHECKS #2403 is still open, and PR mcpx: close #1951 remainder — stale dialect-gap rows + structuredContent warn-only policy doc #2190 is still OPEN / CLEAN and merge-ready. Re-parking with a 1-hour delay so the task stops recirculating while the merge-queue stall persists; the resume condition is unchanged.dezren39 commentedon Oct 29, 2026
🤖 Agent note · implementation complete, blocked only on the repo-wide merge-queue freeze (#2403)
Agent: queue worker
repo-worker-code, OpenChamber scheduled lane. Task 2875 (claim), escalated to you after three park cycles.Work is done and verified. PR mcpx: close #1951 remainder — stale dialect-gap rows + structuredContent warn-only policy doc #2190 —
queue/2875-1951-schema-dialect-remainder, OPEN / CLEAN / MERGEABLE, all reported checks green (basic: proxy port fallbacksSUCCESS,mcpx conformance basic: spec paritySUCCESS,mcpx basic: testSUCCESS, CodeRabbit neutral). Five files, matching the packet's two items plus the third-row check:docs/spec/conformance-matrix.md— bothjson-schema-document-dialectsrows (was :1382 / :2070) no longer read**gap** #254; they cite the tests that pin the documented dialect set. Thejson-schema-bound-composition-costrow (n/a: no validator) was also stale and now citesschemaval.TestSchemaTooLarge(the 1 MiBMaxSchemaBytesbound).docs/spec/requirements.md— the two catalogue rows updated to match (matrix is generated from these).internal/conformance/coverage_messages.go— the Server and ClientGapregistrations for both IDs removed, replaced by coverage entries with the reason in comments.docs/schema-validation.md— new "Output policy:structuredContentis warn-only" section: inputs enforced (-32602), outputs validated bycheckToolOutputbut delivered unchanged with aWarning, the rationale (mcpx is a gateway for schemas it does not own), and the design(mcpx): JSON Schema validation of tool input and output — one validator at the client choke point #1481 / mcpx: Phase 2 of #1481 — validate tool arguments at CallTool (enforce, -32602) + structuredContent against outputSchema (warn-only) #1483 pointers, with an explicit statement that flipping to enforcing is a separate decision.Nothing left to implement. The validator was not touched, elicitation (Phase 3 / mcpx: Phase 3 of #1481 — validate elicitation form answers against requestedSchema in client.answer #1484) not touched,
dezren39/nixnot touched.Why it is not merged: ci: merge queue ejects every PR — no merge since #2233 (10:57Z), entries dropped 2-6 min into AWAITING_CHECKS #2403.
mainhas not moved since 5a34fa7 (10:57:51Z, ~11 h); every merge-queue entry is ejected withreason=branch_protection_failurewithin 24–51 s of its required check going green. Ruleset26115813hasbypass_actors: [], andmain's classic protection carries a pushrestrictionsblock (users: [],teams: [codeowners],apps: [github-actions]) that the merge group cannot satisfy. This is not a PR defect and not something a worker can change.Your decision (one of two config changes): (a) drop the classic push
restrictionsonmain(or add the merge-queue actor to them), or (b) move the required checkbasic: proxy port fallbacksinto ruleset26115813. Either unblocks mcpx: close #1951 remainder — stale dialect-gap rows + structuredContent warn-only policy doc #2190 and the other ~15 CLEAN PRs parked on the same condition.Resume condition: the first PR that merges through the queue → re-enqueue mcpx: close #1951 remainder — stale dialect-gap rows + structuredContent warn-only policy doc #2190, merge, close this issue. Task 2875 is blocked (
escalated-to-user), not parked, so it stops recirculating in the worker pool.Links: PR mcpx: close #1951 remainder — stale dialect-gap rows + structuredContent warn-only policy doc #2190 · ci: merge queue ejects every PR — no merge since #2233 (10:57Z), entries dropped 2-6 min into AWAITING_CHECKS #2403 · task 2875
Merge pull request #2659 from developing-today/docs/roadmap-sync-json…