{"id":6695,"date":"2026-03-02T13:18:18","date_gmt":"2026-03-02T21:18:18","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=6695"},"modified":"2026-03-02T13:55:56","modified_gmt":"2026-03-02T21:55:56","slug":"data-api-builder-mcp-questions","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/data-api-builder-mcp-questions\/","title":{"rendered":"What questions will you ask your data agent?"},"content":{"rendered":"<p>Since release 1.7, Data API builder (DAB) has had MCP support to securely provide agents access to your production data. To support small and massive databases, DAB consolidates operations into five, shared MCP tools that safely Create, Read, Update, and Delete. These are specifically designed to reduce token context window consumption.<\/p>\n<blockquote>\n<p>Learn more about Data API builder: <a href=\"https:\/\/aka.ms\/dab\/mcp\">https:\/\/aka.ms\/dab\/mcp<\/a><\/p>\n<\/blockquote>\n<p>What makes DAB\u2019s MCP capabilities special is not just protecting the context window, but also protecting the database. RBAC security and custom policies are just the beginning. Data API builder rejects NL2SQL, the SQL injection of the agentic age, and instead provides an abstract query builder that ensures deterministic, safe SQL is sent to your database. It is a game changer.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/03\/sql-mcp-server.svg\" alt=\"SQL MCP Server simple overview\" class=\"aligncenter size-full wp-image-6468\" style=\"width:100%; height:auto;\" role=\"img\" \/><\/p>\n<p>Today, as we prepare for our March update, we are finishing a new tool dedicated to sophisticated aggregates that allows models to ask simple questions like \u201cHow many products do I have?\u201d but also extremely complex questions like the ones below. All of this without requiring your database be exposed through raw sql to an AI agent.<\/p>\n<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Database Enablement<\/strong><\/p>What is important to remember is that denormalization is not required, but it often makes this better. You can operate directly against a clean, normalized schema and still get safe, deterministic aggregates. However, thoughtfully introducing views that eliminate joins, or precomputed fields like inventoryValue or quarterlyRevenue, can simplify queries, improve performance, and make complex questions easier for models to express. The database remains authoritative and protected, while you decide how much shaping improves clarity and speed.<\/div><\/p>\n<h2>Strategic customer importance<\/h2>\n<blockquote>\n<p>Who is our most important customer based on total revenue over the past 12 months, considering only active customers and returning the top customer by totalRevenue?<\/p>\n<\/blockquote>\n<p><strong>Tool syntax your agent will generate<\/strong><\/p>\n<pre><code class=\"json\">{\n  \"entity\": \"CustomerSales\",\n  \"function\": \"sum\",\n  \"field\": \"totalRevenue\",\n  \"filter\": \"isActive eq true and orderDate ge 2025-01-01\",\n  \"groupby\": [\"customerId\", \"customerName\"],\n  \"orderby\": \"desc\",\n  \"first\": 1\n}\n<\/code><\/pre>\n<p><strong>SQL translation Data API builder will create<\/strong><\/p>\n<pre><code class=\"sql\">SELECT customerId, customerName, SUM(totalRevenue) AS sum_totalRevenue\nFROM CustomerSales\nWHERE isActive = 1 AND orderDate &gt;= '2025-01-01'\nGROUP BY customerId, customerName\nORDER BY SUM(totalRevenue) DESC\nLIMIT 1;\n<\/code><\/pre>\n<p><strong>Example data<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>customerId<\/th>\n<th>customerName<\/th>\n<th>sum_totalRevenue<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>C1023<\/td>\n<td>Contoso Ltd<\/td>\n<td>8,450,000<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>Product discontinuation candidate<\/h2>\n<blockquote>\n<p>Which product should we consider discontinuing based on the lowest totalRevenue over the past 12 months among products currently marked as active and in stock?<\/p>\n<\/blockquote>\n<p><strong>Tool syntax your agent will generate<\/strong><\/p>\n<pre><code class=\"json\">{\n  \"entity\": \"ProductSales\",\n  \"function\": \"sum\",\n  \"field\": \"totalRevenue\",\n  \"filter\": \"isActive eq true and inStock gt 0 and orderDate ge 2025-01-01\",\n  \"groupby\": [\"productId\", \"productName\"],\n  \"orderby\": \"asc\",\n  \"first\": 1\n}\n<\/code><\/pre>\n<p><strong>SQL translation Data API builder will create<\/strong><\/p>\n<pre><code class=\"sql\">SELECT productId, productName, SUM(totalRevenue) AS sum_totalRevenue\nFROM ProductSales\nWHERE isActive = 1 AND inStock &gt; 0 AND orderDate &gt;= '2025-01-01'\nGROUP BY productId, productName\nORDER BY SUM(totalRevenue) ASC\nLIMIT 1;\n<\/code><\/pre>\n<p><strong>Example data<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>productId<\/th>\n<th>productName<\/th>\n<th>sum_totalRevenue<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>P884<\/td>\n<td>Legacy Widget X<\/td>\n<td>12,450<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>Forward-looking performance expectation<\/h2>\n<blockquote>\n<p>Based on last year\u2019s performance, what is the average quarterlyRevenue per region, and which regions averaged more than $2,000,000 per quarter?<\/p>\n<\/blockquote>\n<p><strong>Tool syntax your agent will generate<\/strong><\/p>\n<pre><code class=\"json\">{\n  \"entity\": \"QuarterlyPerformance\",\n  \"function\": \"avg\",\n  \"field\": \"quarterlyRevenue\",\n  \"filter\": \"fiscalYear eq 2025\",\n  \"groupby\": [\"region\"],\n  \"having\": { \"gt\": 2000000 },\n  \"orderby\": \"desc\"\n}\n<\/code><\/pre>\n<p><strong>SQL translation Data API builder will create<\/strong><\/p>\n<pre><code class=\"sql\">SELECT region, AVG(quarterlyRevenue) AS avg_quarterlyRevenue\nFROM QuarterlyPerformance\nWHERE fiscalYear = 2025\nGROUP BY region\nHAVING AVG(quarterlyRevenue) &gt; 2000000\nORDER BY AVG(quarterlyRevenue) DESC;\n<\/code><\/pre>\n<p><strong>Example data<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>region<\/th>\n<th>avg_quarterlyRevenue<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Southwest<\/td>\n<td>3,250,000<\/td>\n<\/tr>\n<tr>\n<td>Midwest<\/td>\n<td>2,480,000<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>Revenue concentration across regions<\/h2>\n<blockquote>\n<p>What is the total revenue of active retail customers in the Midwest and Southwest regions, grouped by region and customerTier, returning only tier-region combinations where total revenue exceeds $5,000,000 and ordered from highest to lowest?<\/p>\n<\/blockquote>\n<p><strong>Tool syntax your agent will generate<\/strong><\/p>\n<pre><code class=\"json\">{\n  \"entity\": \"CustomerSales\",\n  \"function\": \"sum\",\n  \"field\": \"totalRevenue\",\n  \"filter\": \"isActive eq true and customerType eq 'Retail' and (region eq 'Midwest' or region eq 'Southwest')\",\n  \"groupby\": [\"region\", \"customerTier\"],\n  \"having\": { \"gt\": 5000000 },\n  \"orderby\": \"desc\"\n}\n<\/code><\/pre>\n<p><strong>SQL translation Data API builder will create<\/strong><\/p>\n<pre><code class=\"sql\">SELECT region, customerTier, SUM(totalRevenue) AS sum_totalRevenue\nFROM CustomerSales\nWHERE isActive = 1\n  AND customerType = 'Retail'\n  AND (region = 'Midwest' OR region = 'Southwest')\nGROUP BY region, customerTier\nHAVING SUM(totalRevenue) &gt; 5000000\nORDER BY SUM(totalRevenue) DESC;\n<\/code><\/pre>\n<p><strong>Example data<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>region<\/th>\n<th>customerTier<\/th>\n<th>sum_totalRevenue<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Southwest<\/td>\n<td>Gold<\/td>\n<td>9,200,000<\/td>\n<\/tr>\n<tr>\n<td>Midwest<\/td>\n<td>Platinum<\/td>\n<td>6,750,000<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>Risk exposure by product line<\/h2>\n<blockquote>\n<p>For discontinued products with onHandValue greater than zero, what is the total onHandValue by productLine and warehouseRegion, showing only groups whose combined value exceeds $2,500,000?<\/p>\n<\/blockquote>\n<p><strong>Tool syntax your agent will generate<\/strong><\/p>\n<pre><code class=\"json\">{\n  \"entity\": \"Inventory\",\n  \"function\": \"sum\",\n  \"field\": \"onHandValue\",\n  \"filter\": \"discontinued eq true and onHandValue gt 0\",\n  \"groupby\": [\"productLine\", \"warehouseRegion\"],\n  \"having\": { \"gt\": 2500000 },\n  \"orderby\": \"desc\"\n}\n<\/code><\/pre>\n<p><strong>SQL translation Data API builder will create<\/strong><\/p>\n<pre><code class=\"sql\">SELECT productLine, warehouseRegion, SUM(onHandValue) AS sum_onHandValue\nFROM Inventory\nWHERE discontinued = 1 AND onHandValue &gt; 0\nGROUP BY productLine, warehouseRegion\nHAVING SUM(onHandValue) &gt; 2500000\nORDER BY SUM(onHandValue) DESC;\n<\/code><\/pre>\n<p><strong>Example data<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>productLine<\/th>\n<th>warehouseRegion<\/th>\n<th>sum_onHandValue<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Appliances<\/td>\n<td>West<\/td>\n<td>3,900,000<\/td>\n<\/tr>\n<tr>\n<td>Tools<\/td>\n<td>Central<\/td>\n<td>2,850,000<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<p>Soon, SQL MCP Server will have this ability and so will you. <strong>What will you ask?<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Data API builder (DAB) 1.7+ delivers secure MCP-based CRUD access with deterministic, policy-enforced query generation and an upcoming aggregate tool that enables complex, production-safe analytical questions without exposing raw SQL to AI agents.<\/p>\n","protected":false},"author":96788,"featured_media":6698,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[597,720],"tags":[680,721],"class_list":["post-6695","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-api-builder-2","category-sql-mcp-server-2","tag-agentic-ai","tag-information-architecture"],"acf":[],"blog_post_summary":"<p>Data API builder (DAB) 1.7+ delivers secure MCP-based CRUD access with deterministic, policy-enforced query generation and an upcoming aggregate tool that enables complex, production-safe analytical questions without exposing raw SQL to AI agents.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6695","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/users\/96788"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=6695"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6695\/revisions"}],"predecessor-version":[{"id":6717,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6695\/revisions\/6717"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/6698"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=6695"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=6695"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=6695"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}