Skip to content

Commit 209b2cd

Browse files
anushakolanCopilotsouvikghosh04
authored
Updated tool descriptions for aggregate_record tool. (#3310)
## Why make this change? - Closes #3281 - The `aggregate_records` MCP tool descriptions were too abstract and caused LLM confusion. The descriptions needed concrete examples, prerequisite guidance, and error recovery instructions to improve LLM accuracy when using the tool. ## What is this change? Updates the `aggregate_records` tool metadata in `AggregateRecordsTool.cs` to provide clearer, more actionable descriptions: | Property | Change | |----------|--------| | `description` | Full rewrite with prerequisites (call `describe_entities` first), workflow examples, alias pattern (`{function}_{field}`), and error recovery guidance | | `field` | Changed `'*'` → `*` (removed quotes around asterisk) | | `distinct` | Changed `'*'` → `*` (removed quotes around asterisk) | | `filter` | Added unsupported string pattern operators note and example without quotes | | `groupby` | Added "includes the group fields and the aggregated value" | | `orderby` | Added example (`avg_unitPrice`), added "Cannot sort by entity fields", removed default value (defaults cause LLMs to always send orderby) | | `having` | Added "Supported operators: eq, neq, gt, gte, lt, lte, in." | | `first` | Changed "paginated response" → "cursor pagination with endCursor and hasNextPage" | ## How was this tested? - [ ] Integration Tests - [x] Unit Tests - All 59 `AggregateRecordsTool` unit tests pass including description validation tests - [x] Manual Testing - Verified descriptions render correctly in MCP Inspector at `https://localhost:5001/mcp` ## Sample Request(s) MCP Inspector tool listing shows the updated descriptions: ``` aggregate_records Computes aggregations (count, avg, sum, min, max) on entity data. Prerequisite: 1) Call describe_entities in the current session to discover valid entity names and field names. 2) Call this tool using only names returned by that call. Do not use entity or field names from memory, prior conversations, or assumptions. count supports field * to count all rows. avg, sum, min, and max must reference a field with a numeric data type as returned by describe_entities. ... ``` --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
1 parent 75b8eec commit 209b2cd

1 file changed

Lines changed: 25 additions & 14 deletions

File tree

src/Azure.DataApiBuilder.Mcp/BuiltInTools/AggregateRecordsTool.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,24 @@ public class AggregateRecordsTool : IMcpTool
4545
{
4646
Name = "aggregate_records",
4747
Description = "Computes aggregations (count, avg, sum, min, max) on entity data. "
48-
+ "WORKFLOW: 1) Call describe_entities first to get entity names and field names. "
49-
+ "2) Call this tool with entity, function, and field from step 1. "
50-
+ "RULES: field '*' is ONLY valid with count. "
51-
+ "orderby, having, first, and after ONLY apply when groupby is provided. "
52-
+ "RESPONSE: Result is aliased as '{function}_{field}' (e.g. avg_unitPrice). "
53-
+ "For count(*), the alias is 'count'. "
54-
+ "With groupby and first, response includes items, endCursor, and hasNextPage for pagination.",
48+
+ "Prerequisite: 1) Call describe_entities in the current session to discover valid entity names and field names. "
49+
+ "2) Call this tool using only names returned by that call. "
50+
+ "Do not use entity or field names from memory, prior conversations, or assumptions. "
51+
+ "count supports field * to count all rows. "
52+
+ "avg, sum, min, and max must reference a field with a numeric data type as returned by describe_entities. "
53+
+ "distinct removes duplicate values before aggregation and is not valid with field *. "
54+
+ "filter applies an OData WHERE clause before aggregation. Supported operators: eq, ne, gt, ge, lt, le, and, or, not. "
55+
+ "String pattern operators such as startswith, endswith, contains, and regex are NOT supported. "
56+
+ "Use groupby to compute aggregated rows per group. All groupby fields must exist on the entity and must be discovered through describe_entities. "
57+
+ "Grouped results include the groupby fields and the aggregated value. "
58+
+ "orderby, having, first, and after apply only when groupby is present. "
59+
+ "orderby controls the sort direction of groups based on the aggregation result value. Allowed values are 'asc' and 'desc'; if omitted, 'desc' is used. It cannot sort by entity fields. "
60+
+ "having filters groups based on the aggregated value produced by the function. Supported operators: eq, neq, gt, gte, lt, lte, in. "
61+
+ "When groupby and first are used together, the response includes items, endCursor, and hasNextPage. "
62+
+ "To retrieve the next page, pass the returned endCursor value as the after parameter in a subsequent call with the same inputs. "
63+
+ "Aggregated values are aliased as {function}_{field} (example: avg_unitPrice). "
64+
+ "count(*) is the sole exception to this pattern and returns the alias 'count', not count_*. "
65+
+ "If the call fails due to an unrecognized entity or field name, call describe_entities again to verify valid names, then retry with corrected inputs.",
5566
InputSchema = JsonSerializer.Deserialize<JsonElement>(
5667
@"{
5768
""type"": ""object"",
@@ -67,32 +78,32 @@ public class AggregateRecordsTool : IMcpTool
6778
},
6879
""field"": {
6980
""type"": ""string"",
70-
""description"": ""Field name to aggregate, or '*' with count to count all rows.""
81+
""description"": ""Field name to aggregate, or * with count to count all rows.""
7182
},
7283
""distinct"": {
7384
""type"": ""boolean"",
74-
""description"": ""Remove duplicate values before aggregating. Not valid with field '*'."",
85+
""description"": ""Remove duplicate values before aggregating. Not valid with field *."",
7586
""default"": false
7687
},
7788
""filter"": {
7889
""type"": ""string"",
79-
""description"": ""OData WHERE clause applied before aggregating. Operators: eq, ne, gt, ge, lt, le, and, or, not. Example: 'unitPrice lt 10'."",
90+
""description"": ""OData WHERE clause applied before aggregating. Operators: eq, ne, gt, ge, lt, le, and, or, not. String pattern operators such as startswith, endswith, contains, and regex are not supported. Example: unitPrice lt 10."",
8091
""default"": """"
8192
},
8293
""groupby"": {
8394
""type"": ""array"",
8495
""items"": { ""type"": ""string"" },
85-
""description"": ""Field names to group by. Each unique combination produces one aggregated row. Enables orderby, having, first, and after."",
96+
""description"": ""Field names to group by. Each unique combination produces one aggregated row that includes the group fields and the aggregated value. Enables orderby, having, first, and after."",
8697
""default"": []
8798
},
8899
""orderby"": {
89100
""type"": ""string"",
90101
""enum"": [""asc"", ""desc""],
91-
""description"": ""Sort direction for grouped results by the aggregated value. Only applies when groupby is provided; ignored otherwise.""
102+
""description"": ""Sort direction for grouped results by the aggregated value (ascending or descending). Requires groupby. Cannot sort by entity fields. If omitted, the default sort direction is used.""
92103
},
93104
""having"": {
94105
""type"": ""object"",
95-
""description"": ""Filter groups by the aggregated value (HAVING clause). Requires groupby. Multiple operators are AND-ed."",
106+
""description"": ""Filter groups by the aggregated value (HAVING clause). Supported operators: eq, neq, gt, gte, lt, lte, in. Requires groupby. Multiple operators are AND-ed."",
96107
""properties"": {
97108
""eq"": { ""type"": ""number"", ""description"": ""Equals."" },
98109
""neq"": { ""type"": ""number"", ""description"": ""Not equals."" },
@@ -109,7 +120,7 @@ public class AggregateRecordsTool : IMcpTool
109120
},
110121
""first"": {
111122
""type"": ""integer"",
112-
""description"": ""Max grouped results to return. Requires groupby. Enables paginated response with endCursor and hasNextPage."",
123+
""description"": ""Max grouped results to return. Requires groupby. Enables cursor pagination with endCursor and hasNextPage."",
113124
""minimum"": 1
114125
},
115126
""after"": {

0 commit comments

Comments
 (0)