Is your feature request related to a problem?
The MCP aggregate_records tool accepts only one aggregate per call (function + field). To retrieve several metrics over the same grouping, a client must issue N separate calls, each generating its own query with the same GROUP BY:
SELECT region, SUM(amount) FROM dbo.Sales WHERE ... GROUP BY region
SELECT region, AVG(amount) FROM dbo.Sales WHERE ... GROUP BY region
SELECT region, SUM(cost) FROM dbo.Sales WHERE ... GROUP BY region
This scans the same rows and recomputes the same GROUP BY N times, plus N× query-planning / result-shaping / round-trip overhead. On large tables/views this is a real, avoidable database cost. Issuing the N calls concurrently on the client side only reduces latency — it does not reduce total DB work and can increase peak load/contention.
Describe the solution you'd like
Allow aggregate_records to accept multiple aggregations in a single call, producing one SELECT with one GROUP BY pass, e.g.:
{
"entity": "Sales",
"aggregations": [
{ "function": "sum", "field": "amount", "alias": "sum_amount" },
{ "function": "avg", "field": "amount", "alias": "avg_amount" },
{ "function": "sum", "field": "cost", "alias": "sum_cost" }
],
"groupby": ["region"],
"orderby": ["sum_amount desc"]
}
which maps to a single query:
SELECT region, SUM(amount) AS sum_amount, AVG(amount) AS avg_amount, SUM(cost) AS sum_cost
FROM dbo.Sales
WHERE ...
GROUP BY region
orderby/having should be able to reference the aggregate aliases (e.g. sum_amount), consistent with how grouped results are projected.
Why this looks feasible
DAB already builds multi-aggregation queries internally for GraphQL: the shared SqlQueryStructure.GroupByMetadata.Aggregations is a List<AggregationOperation> and BaseTSqlQueryBuilder.BuildAggregationColumns(...) emits all requested aggregate expressions into a single SELECT. The MCP aggregate_records tool (AggregateRecordsTool) currently parses and loads only a single AggregationOperation. Extending its argument parsing to accept an array and pushing multiple AggregationOperations onto the existing structure would reuse the machinery GraphQL already relies on.
Backward compatibility
Keep the current single-metric form (function + field) working as-is; add the new optional aggregations array alongside it. Single-metric callers are unaffected; multi-metric callers opt in.
Additional context
Is your feature request related to a problem?
The MCP
aggregate_recordstool accepts only one aggregate per call (function+field). To retrieve several metrics over the same grouping, a client must issue N separate calls, each generating its own query with the sameGROUP BY:This scans the same rows and recomputes the same
GROUP BYN times, plus N× query-planning / result-shaping / round-trip overhead. On large tables/views this is a real, avoidable database cost. Issuing the N calls concurrently on the client side only reduces latency — it does not reduce total DB work and can increase peak load/contention.Describe the solution you'd like
Allow
aggregate_recordsto accept multiple aggregations in a single call, producing oneSELECTwith oneGROUP BYpass, e.g.:{ "entity": "Sales", "aggregations": [ { "function": "sum", "field": "amount", "alias": "sum_amount" }, { "function": "avg", "field": "amount", "alias": "avg_amount" }, { "function": "sum", "field": "cost", "alias": "sum_cost" } ], "groupby": ["region"], "orderby": ["sum_amount desc"] }which maps to a single query:
orderby/havingshould be able to reference the aggregate aliases (e.g.sum_amount), consistent with how grouped results are projected.Why this looks feasible
DAB already builds multi-aggregation queries internally for GraphQL: the shared
SqlQueryStructure.GroupByMetadata.Aggregationsis aList<AggregationOperation>andBaseTSqlQueryBuilder.BuildAggregationColumns(...)emits all requested aggregate expressions into a singleSELECT. The MCPaggregate_recordstool (AggregateRecordsTool) currently parses and loads only a singleAggregationOperation. Extending its argument parsing to accept an array and pushing multipleAggregationOperations onto the existing structure would reuse the machinery GraphQL already relies on.Backward compatibility
Keep the current single-metric form (
function+field) working as-is; add the new optionalaggregationsarray alongside it. Single-metric callers are unaffected; multi-metric callers opt in.Additional context
ORDER BYfordwsql). This enhancement is independent of that fix.