-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve on tool input handling and add tests #159
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
Improve on tool input handling and add tests #159
Conversation
…o/inspector into handle-empty-json-fields
|
Hi @jspahrsummers @jerome3o-anthropic @ashwin-ant hoping to get a review on this one - sorry it got big, a few related issues + tests are bundled together here. Thanks! |
jspahrsummers
left a comment
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.
.github/workflows/main.yml
Outdated
| run: | | ||
| cd client | ||
| npm test |
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.
TIOLI:
| run: | | |
| cd client | |
| npm test | |
| working-directory: ./client | |
| run: npm test |
| @@ -0,0 +1,18 @@ | |||
| // Mock for DynamicJsonForm that only exports the types needed for tests | |||
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.
What happens when importing the actual component in tests? Just wondering if we need this file or if it's a structural choice.
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.
It wasn't actually needed anymore, I had temporarily created it while sorting out some test details but tests should run fine without it.
client/src/components/ToolsTab.tsx
Outdated
| value={(params[key] as JsonValue) ?? {}} | ||
| value={ | ||
| (params[key] as JsonValue) ?? | ||
| (prop.type === "array" ? [] : {}) |
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.
Should this use generateDefaultValue?
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 went back and forth on this and ended up using generateDefaultValue here, with the intention of using the tool schema defaults rather than forcing any specific defaults here.
| // Create a ref to store the timeout ID | ||
| const timeoutRef = useRef<ReturnType<typeof setTimeout>>(); | ||
|
|
||
| // Create a debounced function to update parent state |
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.
Just curious, why?
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 added a better clarifying comment here. I added this debounce logic to better handle validation while typing values in JSON editor fields, since validation was getting triggered either immediately or had to be triggered on some other action like switching modes. (Edited)
| onChange={(e) => { | ||
| const val = e.target.value; | ||
| if (!val && !propSchema.required) { | ||
| handleFieldChange(path, 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.
Why don't we want to use generateDefaultValue for all of these?
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.
For some fields I wanted to allow for clearing the field (i.e. setting to undefined) when its not required by the schema.
Intention is to preserve the user's ability to have an empty string input rather than forcing a default value.
jspahrsummers
left a comment
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.
LGTM!
| } | ||
|
|
||
| if (!schema.required) { | ||
| if (schema.type === "array") return []; |
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.
@olaservo - I think this resulted in a regression. I have a schema where an option is an array that is not required. But if you specify it, it should have at least one element.
Like this:
ids: z
.array(z.number())
.min(1)
.optional()
.describe("An optional array of ID#s to search for"),
With the change here, I don't see how you can not specify an array in the UI. This worked before, AFAICT, but broke with this change.
What do you think?
Improve on tool input handling and add tests

Motivation and Context
The ToolTab JSON input handling still has some quirks and testing it manually isn't very sustainable. This PR adds the Jest testing framework to the client side of the MCP Inspector, enabling unit testing for the more complex client-side utilities and components.
The intent here is to improve maintainability by:
jsonPathUtils.ts: Handles JSON path operations (updating and retrieving values)schemaUtils.ts: Handles schema-related operations (generating default values, formatting labels)Another option to consider is using a JSON editing library which handles more of this stuff out of the box. I prefer to avoid adding libraries which might be overkill and introduce their own overhead. But it's still an option, if trying to cover all the more complex tool input testing scenarios doesn't seem sustainable in the long term.
How Has This Been Tested?
The PR includes new Jest tests for the utility functions that were extracted from components:
I also updated the GitHub workflow to run these tests automatically during CI.
After these changes I also confirmed that I could update JSON fields for object tool inputs, which appears to be broken right now.
Breaking Changes
None.
Types of changes
Checklist