3.6 KiB
ADR-2026-08-01-validate-mcp-tool-arguments: Validate MCP Tool Arguments at the Shared Server Boundary
Status: accepted Date: 2026-08-01 Area: backend, protocol
Context
Kandev registers JSON Schema for every MCP tool, but mcp-go v0.43.2 dispatches tools/call directly to the handler without validating arguments against that schema. Handlers commonly read known keys with permissive getters, so unknown keys and mistyped optional values can disappear while the tool reports success. Per-handler checks would leave current tools inconsistent and allow every newly registered tool to repeat the same failure mode.
Decision
All Kandev MCP tool calls are validated in apps/backend/internal/mcp/server before their handlers or backend actions run.
- The currently registered tool schema is the source of truth for required fields, value types, arrays, objects, enums, and other declared constraints.
- Validation treats the root argument object as closed even when the advertised schema omits
additionalProperties: false; unknown top-level arguments fail without increasing every tool schema's context-token cost. - Nested objects retain their declared schema behavior. Open maps such as executor configuration and MCP server configuration remain open unless their own schema closes them.
- Schemas are compiled once for the active tool set and rebuilt whenever
SetModereplaces that set. A schema that cannot compile fails closed for calls to that tool and is covered by a registration test. - Explicit compatibility normalization may run before validation for an established caller mismatch.
create_task_kandevadvertisespromptfor agent instructions and accepts the formerdescriptionname as an unadvertised alias; supplying both is an error. The handler mapspromptto the backend's existingdescriptionfield. Such exceptions require focused tests and do not weaken unknown-argument rejection for other keys. - Argument failures return MCP tool error results and do not invoke the tool handler or dispatch a backend action.
Consequences
Invalid calls fail visibly and consistently across task, configuration, external, and Office MCP modes. Future tools inherit the validation boundary automatically when they use the standard registration and wrapHandler path. Kandev adds a JSON Schema validation dependency and must keep every registered schema compilable. Closing only the root preserves dynamic nested configuration maps while preventing accidental top-level parameter loss. Using prompt for agent instructions aligns create-task with the other agent-starting MCP tools without advertising both names or increasing the tool schema's parameter count; description remains appropriate for descriptive metadata in other contracts.
Alternatives Considered
- Validate only
create_task_kandev. Rejected because the same permissive dispatch behavior applies to every handler and every future tool. - Add checks independently inside each handler. Rejected because duplicated allowlists and type checks drift from registered schemas and are easy to omit on new tools.
- Only advertise
additionalProperties: false. Rejected because the current MCP server does not enforce advertised schemas, and repeating metadata across all tools increases agent context without guaranteeing correctness. - Close every nested object recursively. Rejected because several tool inputs intentionally carry arbitrary configuration maps.
- Upgrade
mcp-goas the repair. Rejected because the current library path does not provide the required dispatch validation, and a broad protocol dependency upgrade is unnecessary for this invariant.