Repository navigation
Description
Phase 2 of design #1481 (JSON Schema validation of tool input and output). Design doc: files/designs/code-mcpx-json-schema-validation.md in the keep-the-four-repos-healthy goal workspace. Origin gap: dezren39/darwin-nix#254.
Dependency gate: do not start until Phase 1 (the internal/schemaval core) is merged — this phase consumes its compile/validate API. If claimed earlier, park naming the dependency.
Scope
Enforce at the one choke point every call surface funnels through — internal/mcpclient:
- List time: in
Client.ListTools(internal/mcpclient/client.go:1051), compile each tool'sInputSchemaandOutputSchemawithschemaval, as a sibling pass tocheckToolHeaders(internal/mcpclient/modern.go:495). A tool whose schema does not compile (unsupported dialect, unresolvable/external$ref, invalid or oversized schema) is excluded from the list with aWarningcarrying the cause — the x-mcp-header precedent; the pool already surfaces warnings asserver.warninglifecycle events. Compiled validators are cached per client, per tool, keyed by schema hash so a re-list recompiles only changed schemas. - Inputs, enforced:
Client.CallTool(client.go:1164) validates the marshalled arguments against the tool's compiled input validator before the transport is touched. Failure returns an Invalid Params (-32602) error naming the tool and the path-qualified reason. Surfaces that translate generic call errors into anisErrortool result (the gateway invoke path ininternal/mcpserver) must pass this error through as the protocol error it is — a caller bug is not a tool failure. Scripts,mcpx_call,/v1/calland pass-through inherit the check viaPool.Call→CallTool; no per-surface duplication. - Outputs, warn-only: when a
CallToolresult carriesstructuredContentand the tool declared anoutputSchema, validate it. Failure produces aWarning(+ the lifecycle event that follows from it) and the result is delivered unchanged. Do not enforce outputs in this phase — the flip decision is an open question on design(mcpx): JSON Schema validation of tool input and output — one validator at the client choke point #1481, answered with this phase's warning data. - Tools with no
inputSchema/outputSchemabehave exactly as today.
Out of scope: elicitation answer validation (Phase 3); format assertion; any per-server validation-mode config; codegen changes; closing the conformance rows for elicitation (Phase 3) — this phase updates the matrix/gap registry for the tool input/output + dialect rows it closes.
Acceptance
- Defining test: a call whose arguments violate the tool's
inputSchema(wrong type; missing required; forbidden additional property — at least the first two) fails with -32602 naming the path, and the fake upstream's call count stays 0. - Defining test: valid arguments reach the upstream byte-identical to today's behaviour (existing call tests unmodified and green).
- Defining test: a tool whose schema declares an unsupported dialect (or carries an unresolvable
$ref) is absent fromListTools, absent from a gateway tools/list, and aWarningwith the cause was emitted. - Defining test: a result whose
structuredContentviolatesoutputSchemais returned to the caller unchanged, with aWarningrecorded; a conforming one records none. - Benchmark sanity: argument validation on a representative nested schema (triage picks it from a real catalog tool) stays within a triage-set per-call budget; record the measured number on this issue.
- Conformance matrix rows for
json-schema-support-2020-12,json-schema-validate-per-dialect-and-error-on-unsupported,json-schema-document-dialects,json-schema-reject-unresolved-refand the matching gap-registry entries are updated to reflect enforcement (server + client sides as each applies). - Full suite passes:
cd pkgs/mcpx && go test ./...(via CI on the PR per fleet policy).
agent-note:v1 — filed by the repo design architect (dedicated code job, pass 3, 2026-10-27) as a sub-issue of design #1481. Filed as task/triage: triage confirms scope against current main once Phase 1 has landed (gate above) and enqueues the implementation packet; do not implement in the triage task.
Activity
developing-today commentedon Oct 27, 2026
CODE-554
dezren39 commentedon Oct 27, 2026
Intake review
🤖 Agent note · filed
Related: #1481 (parent design, decision recorded there), #1482 / #1483 / #1484 (the three phases), dezren39/darwin-nix#254 (origin).
Liveness: searched merged PRs for
schemaval/ schema-validation work — none merged. Not solved; the Phase 1 dependency gate in the body still governs start order.Notes / risks: the body's
## Acceptancesection is a full acceptance-criteria set in substance (defining tests enumerated), so no duplicate criteria section was appended;status/needs-triageadded to complete the filed-state label set. This item already carries queue/queued — triage via the queue, do not implement in the triage task (per the filer's note).Suggested approach: exactly as scoped in the body; park on claim if the Phase 1 gate has not cleared, naming the dependency.
184 remaining items
dezren39 commentedon Oct 28, 2026
🤖 Agent note · picked up
queue/1616-1483-calltool-validationfix(mcpx): explicit null for an optional argument is an omission, not…
Merge pull request #1596 from developing-today/queue/1616-1483-callto…
dezren39 commentedon Oct 28, 2026
🤖 Agent note · done
9176f1dewith every check green, includingclient-2026-07-28conformance at the expected 67/68.