Add aggregate_records MCP tool with query-timeout support#3186
Closed
Add aggregate_records MCP tool with query-timeout support#3186
Conversation
…pport - Add AggregateRecordsTool with validation for field/function compatibility - Reject count+star+distinct=true with InvalidArguments - Reject field='*' with non-count functions - Add QueryTimeout to McpRuntimeOptions and converter - Add AggregateRecords to DmlToolsConfig and converter - Add TIMEOUT error code to McpTelemetryErrorCodes - Add timeout wrapping and aggregate_records mapping to McpTelemetryHelper - Update JSON schema with query-timeout and aggregate-records - Update CLI ConfigGenerator and ConfigureOptions for aggregate-records - Add AggregateRecordsToolTests with validation, aggregation, and pagination tests - Add timeout and aggregate_records tests to McpTelemetryTests Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Update PR #3179 by implementing review fixes
Add aggregate_records MCP tool with query-timeout support and validation fixes
Mar 2, 2026
…-tool - Add comprehensive AggregateRecordsTool.cs (with validation fixes from update branch) - Add McpTelemetryErrorCodes.cs updates - Add ConfigureOptions.cs with query-timeout CLI option - Add ConfigGenerator.cs with query-timeout and aggregate-records support - Add RuntimeConfigValidator.cs query-timeout validation - Add comprehensive AggregateRecordsToolTests.cs (Mcp/ folder, 63 tests) - Add McpQueryTimeoutTests.cs (21 tests, fixed assertion for '1 second') - Update EntityLevelDmlToolConfigurationTests.cs - Remove unused _numericFunctions field (dotnet format clean) This branch now contains all work from both: - copilot/add-aggregate-records-tool (comprehensive implementation + tests) - copilot/update-aggregate-records-tool-fixes (validation fixes + grammar fix) Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copilot
AI
changed the title
Add aggregate_records MCP tool with query-timeout support and validation fixes
Add aggregate_records MCP tool with validation fixes and query-timeout support
Mar 2, 2026
Copilot
AI
changed the title
Add aggregate_records MCP tool with validation fixes and query-timeout support
Add aggregate_records MCP tool with query-timeout support
Mar 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a new
aggregate_recordsbuilt-in MCP tool that enables models to answer aggregation questions (count, avg, sum, min, max) over entity data, with optional groupby/having/pagination. Adds configurablequery-timeoutfor all MCP tool executions.Why make this change?
What is this change?
aggregate_recordstool (AggregateRecordsTool.cs)count,avg,sum,min,maxwith optionalfilter(OData WHERE),distinct,groupby,having(post-aggregation),orderby, and cursor-basedfirst/afterpagination{function}_{field}(e.g.avg_unitPrice);countforcount(*)DmlToolsConfig.AggregateRecords; CLI:--runtime.mcp.dml-tools.aggregate-records.enabledValidation (deterministic, model-facing errors)
field='*'with non-countfunction →InvalidArgumentscount(*) + distinct=true→InvalidArguments(was silently returning 0)query-timeout(default 30s)McpRuntimeOptions.QueryTimeoutserialized asquery-timeoutin JSON configMcpTelemetryHelper.ExecuteWithTelemetryAsyncwraps every tool call with a linkedCancellationTokenSource.CancelAfter; timeout firesTimeoutExceptionwith model-facing guidance, distinct from client cancellation (OperationCanceledException)RuntimeConfigProviderper call, no restart needed--runtime.mcp.query-timeoutSchema/config
dab.draft.schema.jsonupdated withquery-timeout(integer, min 1, default 30) andaggregate-recordsRuntimeConfigValidatorrejectsquery-timeout < 1McpRuntimeOptionsConverterFactoryreads/writesquery-timeoutin both Read and Write pathsHow was this tested?
Mcp/AggregateRecordsToolTests.cs— 63 tests covering all 13 documented spec examples, groupby/having/orderby, cursor pagination, edge casesMcp/McpQueryTimeoutTests.cs— 21 tests: timeout firing, client cancellation, error message content, hot-reload behaviorUnitTests/AggregateRecordsToolTests.cs— 31 tests: validation paths (invalid field/function combos,count(*)+distinct, pagination cursor semantics)UnitTests/McpTelemetryTests.cs— expanded with timeout andaggregate_records→"aggregate"operation-mapping testsSample Request(s)
Config: enable aggregate-records with custom timeout
{ "runtime": { "mcp": { "enabled": true, "query-timeout": 60, "dml-tools": { "aggregate-records": true } } } }CLI
dab configure --runtime.mcp.query-timeout 60 dab configure --runtime.mcp.dml-tools.aggregate-records.enabled trueTool call: count all products
{ "entity": "Product", "function": "count", "field": "*" }Response:
{ "count": 77 }Tool call: top categories by avg price (grouped, paginated)
{ "entity": "Product", "function": "avg", "field": "unitPrice", "groupby": ["categoryName"], "having": { "gt": 25 }, "orderby": "desc", "first": 5 }Response:
{ "items": [...], "endCursor": "<opaque>", "hasNextPage": true }Original prompt
This pull request was created from Copilot chat.
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.