<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Data-Api-Builder | The .NET Blog</title><link>https://thedotnetblog.com/tags/data-api-builder/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>en</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Tue, 05 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/tags/data-api-builder/index.xml" rel="self" type="application/rss+xml"/><item><title>SQL MCP Server on Azure App Service — No Containers Required</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/sql-mcp-server-azure-app-service-no-containers/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/sql-mcp-server-azure-app-service-no-containers/</guid><description>The SQL MCP Server can now run on Azure App Service without Docker or Kubernetes. Here's what that means for .NET developers building AI agents that talk to SQL databases.</description><content:encoded>&lt;p&gt;Let me be honest with you: every time I see &amp;ldquo;requires a container&amp;rdquo; in a tutorial, a little part of me sighs. Containers are great — until your team doesn&amp;rsquo;t have a container strategy, and suddenly a feature that looked simple is blocked behind orchestration overhead you didn&amp;rsquo;t plan for.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why this one caught my eye. The SQL MCP Server can now run on Azure App Service — no Docker, no Kubernetes, just the same Data API builder (DAB) configuration that exposes your SQL database through MCP, REST, and GraphQL.&lt;/p&gt;
&lt;h2 id="whats-sql-mcp-server-again"&gt;What&amp;rsquo;s SQL MCP Server, Again?&lt;/h2&gt;
&lt;p&gt;Quick context if you haven&amp;rsquo;t run into it yet. SQL MCP Server sits between your AI agent and your SQL database. Instead of giving your agent direct database access (which is a terrible idea), it exposes your tables and views as an abstraction layer — entities with defined permissions.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s built on top of &lt;a href="https://learn.microsoft.com/en-us/azure/data-api-builder/"&gt;Data API builder&lt;/a&gt;, which means one configuration file drives MCP &lt;em&gt;and&lt;/em&gt; REST &lt;em&gt;and&lt;/em&gt; GraphQL simultaneously. Your agent talks to the MCP endpoint. Your traditional app talks to REST or GraphQL. Same config, same runtime, different surfaces.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s genuinely useful. You&amp;rsquo;re not maintaining two separate API layers.&lt;/p&gt;
&lt;h2 id="the-container-problem-and-the-solution"&gt;The Container Problem (and the Solution)&lt;/h2&gt;
&lt;p&gt;The original deployment model for SQL MCP Server was containers. That works well in many shops — but not all. Plenty of .NET teams standardize on Azure App Service or VMs. Requiring a container runtime just to expose a SQL endpoint adds friction nobody asked for.&lt;/p&gt;
&lt;p&gt;The new walkthrough shows you how to skip the container entirely. The whole thing runs with a &lt;code&gt;dab start&lt;/code&gt; command, hosted on App Service as a standard .NET 8 web process.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the local setup flow in a nutshell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install Data API builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet tool install microsoft.dataapibuilder --prerelease -g
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Initialize the configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab init --database-type mssql --host-mode Development --connection-string &lt;span class="s2"&gt;&amp;#34;@env(&amp;#39;SQL_CONNECTION_STRING&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Add an entity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab add products --source dbo.products --permissions &lt;span class="s2"&gt;&amp;#34;authenticated:*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Configure App Service auth provider&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab configure --runtime.host.authentication.provider AppService
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Start the server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point you have MCP at &lt;code&gt;/mcp&lt;/code&gt;, REST and GraphQL from the same process, and nothing running in a container.&lt;/p&gt;
&lt;h2 id="authentication-that-doesnt-involve-shared-api-keys"&gt;Authentication That Doesn&amp;rsquo;t Involve Shared API Keys&lt;/h2&gt;
&lt;p&gt;This is the part I appreciate most. When you deploy to App Service, you configure Microsoft Entra ID as the authentication provider. No shared secrets embedded in config files, no API keys to rotate.&lt;/p&gt;
&lt;p&gt;The connection string stays in an App Service environment variable (not in &lt;code&gt;dab-config.json&lt;/code&gt;), and the MCP endpoint is protected by platform authentication. If you&amp;rsquo;re already aligned to Entra ID across your Azure workloads — which you probably are if you&amp;rsquo;re using Azure AI Foundry agents — this fits naturally.&lt;/p&gt;
&lt;p&gt;For local development, you switch to &lt;code&gt;Simulator&lt;/code&gt; mode and STDIO transport. Flip back to &lt;code&gt;AppService&lt;/code&gt; mode when deploying. Clean and explicit.&lt;/p&gt;
&lt;h2 id="deploying-to-app-service"&gt;Deploying to App Service&lt;/h2&gt;
&lt;p&gt;The actual deployment is straightforward Azure CLI work:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create the App Service plan&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;az appservice plan create &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &amp;lt;plan-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --resource-group &amp;lt;resource-group&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --sku B1 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --is-linux
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create the web app (.NET 8 runtime)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;az webapp create &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &amp;lt;app-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --resource-group &amp;lt;resource-group&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --plan &amp;lt;plan-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --runtime &lt;span class="s2"&gt;&amp;#34;DOTNETCORE:8.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Set the startup command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;az webapp config &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &amp;lt;app-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --resource-group &amp;lt;resource-group&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --startup-file &lt;span class="s2"&gt;&amp;#34;dab start&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then deploy your DAB project using whatever code deployment path your team already uses — VS Code, GitHub Actions, Zip Deploy. The key detail: it&amp;rsquo;s a &lt;strong&gt;code&lt;/strong&gt; deployment, not a container deployment. No image to build, push, or manage.&lt;/p&gt;
&lt;h2 id="why-this-matters-for-net-developers"&gt;Why This Matters for .NET Developers&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re building AI agents in .NET — whether with the Microsoft Agent Framework, Semantic Kernel, or Azure AI Foundry hosted agents — eventually your agent needs to talk to a database. SQL MCP Server gives you a structured way to do that without exposing raw connection strings or writing a custom API layer.&lt;/p&gt;
&lt;p&gt;Running it on App Service closes the gap for teams that aren&amp;rsquo;t running containers. It&amp;rsquo;s the same DAB config, the same Entra auth, the same MCP protocol — just on infrastructure you already know.&lt;/p&gt;
&lt;p&gt;Check out the full walkthrough in the &lt;a href="https://devblogs.microsoft.com/azure-sql/sql-mcp-server-app-service/"&gt;original blog post&lt;/a&gt; and the &lt;a href="https://github.com/Azure-Samples/SQL-MCP-NoContainer"&gt;sample repo on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;The SQL MCP Server on App Service is a solid pragmatic option for .NET teams that want to give their agents structured access to SQL data without a container strategy. The combination of DAB&amp;rsquo;s entity model, App Service&amp;rsquo;s built-in Entra auth, and the &lt;code&gt;dab start&lt;/code&gt; startup command makes for a deployment that&amp;rsquo;s simple to explain and easy to operate.&lt;/p&gt;
&lt;p&gt;Give it a try. Your agents will appreciate the clean API surface. Your ops team will appreciate not having to deal with container registries.&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server — The Right Way to Give AI Agents Database Access</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</guid><description>SQL MCP Server from Data API builder gives AI agents secure, deterministic database access without exposing schemas or relying on NL2SQL. RBAC, caching, multi-database support — all built in.</description><content:encoded>&lt;p&gt;Let&amp;rsquo;s be honest: most database MCP servers available today are terrifying. They take a natural language query, generate SQL on the fly, and run it against your production data. What could go wrong? (Everything. Everything could go wrong.)&lt;/p&gt;
&lt;p&gt;The Azure SQL team just &lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;introduced SQL MCP Server&lt;/a&gt;, and it takes a fundamentally different approach. Built as a feature of Data API builder (DAB) 2.0, it gives AI agents structured, deterministic access to database operations — without NL2SQL, without exposing your schema, and with full RBAC at every step.&lt;/p&gt;
&lt;h2 id="why-no-nl2sql"&gt;Why no NL2SQL?&lt;/h2&gt;
&lt;p&gt;This is the most interesting design decision. Models aren&amp;rsquo;t deterministic, and complex queries are the most likely to produce subtle errors. The exact queries users hope AI can generate are also the ones that need the most scrutiny when produced non-deterministically.&lt;/p&gt;
&lt;p&gt;Instead, SQL MCP Server uses an &lt;strong&gt;NL2DAB&lt;/strong&gt; approach. The agent works with Data API builder&amp;rsquo;s entity abstraction layer and built-in query builder to produce accurate, well-formed T-SQL deterministically. Same result for the user, but without the risk of hallucinated JOINs or accidental data exposure.&lt;/p&gt;
&lt;h2 id="seven-tools-not-seven-hundred"&gt;Seven tools, not seven hundred&lt;/h2&gt;
&lt;p&gt;SQL MCP Server exposes exactly seven DML tools, regardless of database size:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;describe_entities&lt;/code&gt; — discover available entities and operations&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_record&lt;/code&gt; — insert rows&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read_records&lt;/code&gt; — query tables and views&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update_record&lt;/code&gt; — modify rows&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete_record&lt;/code&gt; — remove rows&lt;/li&gt;
&lt;li&gt;&lt;code&gt;execute_entity&lt;/code&gt; — run stored procedures&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aggregate_records&lt;/code&gt; — aggregation queries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is smart because context windows are the agent&amp;rsquo;s thinking space. Flooding them with hundreds of tool definitions leaves less room for reasoning. Seven fixed tools keep the agent focused on &lt;em&gt;thinking&lt;/em&gt; rather than &lt;em&gt;navigating&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Each tool can be individually enabled or disabled:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;runtime&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;dml-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;describe-entities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;create-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;read-records&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;update-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;delete-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;execute-entity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;aggregate-records&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="getting-started-in-three-commands"&gt;Getting started in three commands&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab init &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --database-type mssql &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --connection-string &lt;span class="s2"&gt;&amp;#34;@env(&amp;#39;sql_connection_string&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab add Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --source dbo.Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --permissions &lt;span class="s2"&gt;&amp;#34;anonymous:*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s a running SQL MCP Server exposing your Customers table. The entity abstraction layer means you can alias names and columns, limit fields per role, and control exactly what agents see — without exposing internal schema details.&lt;/p&gt;
&lt;h2 id="the-security-story-is-solid"&gt;The security story is solid&lt;/h2&gt;
&lt;p&gt;This is where Data API builder&amp;rsquo;s maturity pays off:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RBAC at every layer&lt;/strong&gt; — each entity defines which roles can read, create, update, or delete, and which fields are visible&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Key Vault integration&lt;/strong&gt; — connection strings and secrets managed securely&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Entra + custom OAuth&lt;/strong&gt; — production-grade authentication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content Security Policy&lt;/strong&gt; — agents interact through a controlled contract, not raw SQL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The schema abstraction is particularly important. Your internal table and column names never get exposed to the agent. You define entities, aliases, and descriptions that make sense for the AI interaction — not your database ERD.&lt;/p&gt;
&lt;h2 id="multi-database-and-multi-protocol"&gt;Multi-database and multi-protocol&lt;/h2&gt;
&lt;p&gt;SQL MCP Server supports Microsoft SQL, PostgreSQL, Azure Cosmos DB, and MySQL. And because it&amp;rsquo;s a DAB feature, you get REST, GraphQL, and MCP endpoints simultaneously from the same configuration. Same entity definitions, same RBAC rules, same security — across all three protocols.&lt;/p&gt;
&lt;p&gt;Auto-configuration in DAB 2.0 can even inspect your database and build the configuration dynamically, if you&amp;rsquo;re comfortable with less abstraction for rapid prototyping.&lt;/p&gt;
&lt;h2 id="my-take"&gt;My take&lt;/h2&gt;
&lt;p&gt;This is how enterprise database access for AI agents should work. Not &amp;ldquo;hey LLM, write me some SQL and YOLO it against production.&amp;rdquo; Instead: a well-defined entity layer, deterministic query generation, RBAC at every step, caching, monitoring, and telemetry. It&amp;rsquo;s boring in the best possible way.&lt;/p&gt;
&lt;p&gt;For .NET developers, the integration story is clean — DAB is a .NET tool, the MCP Server runs as a container, and it works with Azure SQL, which most of us are already using. If you&amp;rsquo;re building AI agents that need data access, start here.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;SQL MCP Server is free, open-source, and runs anywhere. It&amp;rsquo;s the prescriptive approach from Microsoft for giving AI agents secure database access. Check out the &lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;full post&lt;/a&gt; and the &lt;a href="https://aka.ms/sql/mcp"&gt;documentation&lt;/a&gt; to get started.&lt;/p&gt;</content:encoded></item></channel></rss>