Expose required array in custom MCP tool input schema#3688
Expose required array in custom MCP tool input schema#3688souvikghosh04 with Copilot wants to merge 7 commits into
required array in custom MCP tool input schema#3688Conversation
required array in custom MCP tool input schema
There was a problem hiding this comment.
Pull request overview
This pull request enhances MCP custom tool discoverability by emitting a JSON Schema required array in DynamicCustomTool input schemas, allowing agents/clients to distinguish mandatory parameters from optional/defaulted ones.
Changes:
- Add top-level
requiredarray emission to the DB-metadata schema path (BuildInputSchema) when at least one parameter is required. - Add the same
requiredarray emission to the config-fallback schema path (BuildInputSchemaFromConfig). - Add unit and MSSQL integration tests to validate required/optional/defaulted parameter behavior and the zero-parameter omission case.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Azure.DataApiBuilder.Mcp/Core/DynamicCustomTool.cs | Builds MCP tool inputSchema.required based on parameter requirement/default rules for both DB and config-fallback paths. |
| src/Service.Tests/Mcp/DynamicCustomToolTests.cs | Adds unit tests asserting required array inclusion/exclusion and omission for zero-parameter procedures, including config-fallback validation. |
| src/Service.Tests/Mcp/DynamicCustomToolMsSqlIntegrationTests.cs | Adds MSSQL integration coverage validating required against live stored procedure metadata and config defaults. |
|
|
||
| properties[paramName] = paramSchema; | ||
|
|
||
| // A parameter is required unless config marks it optional or supplies a default |
There was a problem hiding this comment.
Here, this call to IsParameterRequired is not for config. the comment conveys config. Should be fixed to mention db metadata
| /// When falling back to config-based schema, parameters without a default are required. | ||
| /// </summary> | ||
| [TestMethod] | ||
| public void GetToolMetadata_ConfigFallback_MarksParamsWithoutDefaultsRequired() |
There was a problem hiding this comment.
There should be a test for config defining defaults and also having the parameter specified as required. In this case, the parameter should still be present in the required array.
There was a problem hiding this comment.
@copilot check if this is covered already or add this test.
There was a problem hiding this comment.
Added explicit config-fallback coverage in 0c38640. The new test verifies that a parameter with Required = true and a config default is excluded from inputSchema.required, matching the current default-application behavior.
Aniruddh25
left a comment
There was a problem hiding this comment.
Needs 1 more test for combination of required and default
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Why make this change?
DynamicCustomTool) build aninputSchemawith typedpropertiesfrom stored procedure metadata, but never emitted a JSON Schemarequiredarray. AI agents had no way to tell which parameters are mandatory and had to fall back to description text ordescribe_entities.What is this change?
DynamicCustomTool.BuildInputSchemaFromDbMetadata: collects parameter names while iterating SP parameters and adds a top-levelrequiredarray when non-empty.DynamicCustomTool.BuildInputSchemaFromConfig(fallback path): same treatment for config-declared parameters.IsParameterRequired(bool? configuredRequired, bool hasDefault)helper centralizes the rule: a parameter is required unless config explicitly marks it optional (required: false) or supplies a default the engine applies when the caller omits it. Consistent with the execution-time default-application logic anddescribe_entitiessemantics.Resulting schema:
How was this tested?
DynamicCustomToolTests: required params listed, params with defaults /required:falseexcluded, zero-param SP omits the array, config-fallback path.DynamicCustomToolMsSqlIntegrationTests: validatesrequiredagainst live DB metadata (GetBook.idrequired;InsertBookdefaulted params excluded; zero-paramGetBooksomits the array).Sample Request(s)
MCP
tools/listresponse for a custom tool overget_book_by_id(@id int):{ "name": "get_book", "description": "Executes the get_book stored procedure", "inputSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "Parameter id" } }, "required": [ "id" ] } }