-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat: add optional strict parameter to registerTool for Zod validation #846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add optional strict parameter to registerTool for Zod validation #846
Conversation
This test demonstrates the current issue where tools accept unknown parameters (e.g. incorrect capitalization) without validation errors. The test uses 'username' and 'itemcount' instead of the expected 'userName' and 'itemCount' parameters, which should be rejected but currently aren't. This test is expected to fail until strict validation is implemented.
Add strict parameter to registerTool config that defaults to false for backward compatibility. When strict=true, applies .strict() to Zod schema creation for tool input validation to throw errors on unknown parameters instead of silently ignoring them. - Add strict?: boolean to registerTool config interface - Modify _createRegisteredTool to accept and use strict parameter - Apply z.object(inputSchema).strict() when strict=true - Update legacy tool() method to pass strict=false (backward compatibility) - Update test to verify strict validation rejects unknown parameters - All existing tests continue to pass (no breaking changes) This fixes the issue where parameter name typos are silently dropped, leading to confusing behavior where tools execute with missing data.
Add Advanced Usage section explaining the strict parameter for registerTool: - Show examples of strict vs lenient validation - Explain when to use each mode (development vs production) - Document that strict parameter is only available in registerTool() - Note that legacy tool() method uses lenient validation for compatibility This helps developers understand when and how to use strict validation to catch parameter name typos and unexpected data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @abloomston !
strict: true // Reject { username: "test", itemcount: 42 } | ||
}, handler); | ||
|
||
// Lenient validation for production - handles client variations gracefully |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure about advising leniency in prod tbh, or maybe explain why (e.g. to allow some kind of forward compatibility maybe, although I'm struggling to imagine a valid use case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ochafik I did this to maintain backwards compatibility for users of this sdk. Let me know which (or another) you'd like me to do:
- Revise this comment, maintaining backwards compatibility
- Do not maintain backwards compatibility, making strict the default
@@ -774,14 +774,19 @@ export class McpServer { | |||
inputSchema: ZodRawShape | undefined, | |||
outputSchema: ZodRawShape | undefined, | |||
annotations: ToolAnnotations | undefined, | |||
strict: boolean | undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd name this more explicitly, e.g. rejectUnexpectedInputs, given this isn't turning registerTool as fully strict (e.g. I'd expect structuredContent to be checked against outputSchema, and potentially content text to be checked against structuredContent)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ochafik would the variable name strictInputSchemaValidation
work for you?
Add optional
strict
parameter toregisterTool()
config that enables Zod's strict validation to reject unknown parameters instead of silently ignoring them.Motivation and Context
The MCP TypeScript SDK currently silently ignores unknown parameters in tool calls, which causes issues where parameter name typos are silently dropped, leading to confusing behavior where tools execute with missing data.
How Has This Been Tested?
Breaking Changes
None. The
strict
parameter defaults tofalse
for backward compatibility. Existing code will continue to work unchanged.Types of changes
Checklist
Additional context
You should consider this PR in concert with #792 which makes changes that may be related.
Implementation Details:
strict?: boolean
toregisterTool
config interfacestrict=true
, appliesz.object(inputSchema).strict()
to reject unknown parametersstrict=false
(default), maintains current lenient behaviorregisterTool()
method - legacytool()
method uses lenient validation for compatibilityUse Cases:
The feature follows existing patterns in the codebase and maintains full backward compatibility while solving a real pain point for developers.
LLM Disclosure
This PR was created with the assistance of Claude Code, Claude Haiku 3.5, Claude Sonnet 4.0, and Chat-GPT 4.1 nano.