{"id":6925,"date":"2026-05-04T09:30:34","date_gmt":"2026-05-04T16:30:34","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=6925"},"modified":"2026-05-01T19:54:30","modified_gmt":"2026-05-02T02:54:30","slug":"sql-mcp-server-app-service","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/sql-mcp-server-app-service\/","title":{"rendered":"SQL MCP Server as an App Service"},"content":{"rendered":"<p>Placing SQL MCP Server between your AI agent and your SQL database lets your agent interact with data through a controlled API surface instead of direct database access. Built on Data API builder (DAB), SQL MCP Server brings DAB features to agentic solutions, including caching, telemetry, authentication, and entity-based abstraction. That abstraction helps your agent operate within your organization\u2019s guardrails, follow your application model, and avoid depending directly on the physical database schema.<\/p>\n<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>More than just an MCP server<\/strong><\/p>SQL MCP Server is powered by Data API builder (DAB), which also supports REST and GraphQL from the same configuration. This means a single DAB configuration can expose MCP, REST, and GraphQL endpoints at the same time, allowing one runtime to support agents and traditional applications without duplicating API logic.<\/div><\/p>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/mcp\/\">SQL MCP Server | Microsoft Learn<\/a><\/p>\n<h2>Without a container<\/h2>\n<p>The standard deployment model for SQL MCP Server is a container. That works well for many distributed solutions, but not every environment has a container strategy in place. Some teams standardize on Azure App Service, virtual machines, or other application hosting models.<\/p>\n<p>For those scenarios, SQL MCP Server can run without a container. This walkthrough shows how to host SQL MCP Server on Azure App Service using a code-based deployment model, while keeping the same DAB configuration that exposes MCP, REST, and GraphQL.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Container overhead<\/strong><\/p>In many scenarios, container orchestration can increase solution complexity. Running SQL MCP Server on Azure App Service removes that requirement while preserving the same DAB configuration model. You still expose MCP, REST, and GraphQL from a single runtime, but deploy using a familiar code-based App Service workflow instead of building, publishing, and managing container images.<\/div><\/p>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/deployment\/\">Deployment options for Data API builder | Microsoft Learn<\/a><\/p>\n<h2>Command-line<\/h2>\n<p>It starts with the cross-platform Data API builder CLI. The CLI enables the local developer loop and lets SQL MCP Server run on any machine with .NET, without requiring Docker or Kubernetes.<\/p>\n<p>The command <code>dab start<\/code> starts the runtime, reads your configuration, and hosts the MCP endpoint. The same model works locally, in a virtual machine, or in Azure App Service, giving you a simple path to run SQL MCP Server without a container.<\/p>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/\">Data API builder CLI reference | Microsoft Learn<\/a><\/p>\n<h2>Azure App Service<\/h2>\n<p>Azure App Service is a natural fit for hosting SQL MCP Server as an MCP endpoint. It is designed for web apps and APIs, with built-in support for TLS, custom domains, scaling, monitoring, and Microsoft Entra authentication.<\/p>\n<p>For SQL MCP Server, this means your MCP endpoint can run like a standard production HTTPS API. You can scale out with more instances, scale up with a larger SKU, and use the same operational controls as other App Service workloads.<\/p>\n<p>App Service also gives you a clean authentication model. By protecting the endpoint with Microsoft Entra ID, you can avoid shared API keys and align access with the identity patterns used by agent platforms such as Azure AI Foundry.<\/p>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/app-service\/configure-authentication-mcp\">Configure App Service authentication for MCP servers | Microsoft Learn<\/a><\/p>\n<h2>Walkthrough<\/h2>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/04\/mcp-foundry.svg\"><img decoding=\"async\" class=\"alignnone wp-image-6940 size-full\" role=\"img\" src=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/04\/mcp-foundry.svg\" alt=\"SQL MCP Server solution overview diagram. \" width=\"555\" height=\"195\" \/><\/a><\/p>\n<p>This walkthrough shows how to run SQL MCP Server on Azure App Service without containers. Starting from a clean environment, you will install Data API builder (DAB), connect to your SQL database, configure authentication, run SQL MCP Server locally, and then publish it to Azure App Service.<\/p>\n<p>By the end, you will have one DAB configuration exposing MCP, REST, and GraphQL endpoints from a cloud-hosted App Service endpoint.<\/p>\n<p>Reference: <a href=\"https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/README.md\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/README.md<\/a><\/p>\n<h2>Prerequisites<\/h2>\n<p>Before starting, you need a SQL data source, a local development environment, and access to Azure resources. This walkthrough assumes you are familiar with basic Azure concepts and command-line tooling.<\/p>\n<p>You will need:<\/p>\n<ul>\n<li>A SQL database, such as a Fabric SQL database or Azure SQL<\/li>\n<li>Access to Microsoft Entra ID to register an application and configure authentication<\/li>\n<li>.NET installed locally, with the <code>dotnet<\/code> CLI available<\/li>\n<li>A terminal, such as PowerShell<\/li>\n<li>Visual Studio Code or another editor for updating configuration files<\/li>\n<li>An Azure subscription with permission to create and configure Azure App Service<\/li>\n<\/ul>\n<h2>Install &amp; initialize Data API builder<\/h2>\n<p>Starting with the local developer loop, install the Data API builder CLI and create the initial configuration file. This file drives SQL MCP Server and defines the runtime that exposes MCP, REST, and GraphQL from your SQL database.<\/p>\n<p>Reference: <a href=\"https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/How-to-setup-DAB.md\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/How-to-setup-DAB.md<\/a><\/p>\n<h3><strong>Using the dotnet CLI, install DAB:<\/strong><\/h3>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dotnet tool install microsoft.dataapibuilder --prerelease -g<\/code><\/pre>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/install\">Install the DAB CLI | Microsoft Learn<\/a><\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Prerelease timeline<\/strong><\/p>Using the CLI with the <code>--prerelease<\/code> flag installs the latest Data API builder prerelease. This walkthrough uses the prerelease version to reflect the latest MCP capabilities and configuration model.<\/div><\/p>\n<h3><strong>Using the DAB CLI, initialize your configuration:<\/strong><\/h3>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dab init --database-type mssql --host-mode Development --connection-string \"@env('SQL_CONNECTION_STRING')\"<\/code><\/pre>\n<p>After initialization, you will see a <code>dab-config.json<\/code> file. This file defines the data source, runtime settings, entities, permissions, and endpoint behavior. From this point forward, SQL MCP Server runs from this configuration.<\/p>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/dab-init?tabs=bash-cli\">Initialize a config with the DAB CLI | Microsoft Learn<\/a><\/p>\n<h3>Add a table entity<\/h3>\n<p>With the initial configuration created, add a table entity that DAB can expose through REST, GraphQL, and MCP. An entity maps a database object, such as a table, view, or stored procedure, to an API surface with defined permissions.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dab add products --source dbo.products --permissions \"authenticated:*\"<\/code><\/pre>\n<p>This updates <code>dab-config.json<\/code> with a new <code>products<\/code> entity. The entity points to <code>dbo.products<\/code> and defines which roles can access it.<\/p>\n<p>The resulting configuration includes an <code>entities<\/code> section similar to this:<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">\"entities\": {\r\n  \"products\": {\r\n    \"source\": {\r\n      \"object\": \"dbo.products\",\r\n      \"type\": \"table\"\r\n    },\r\n    \"permissions\": [\r\n      {\r\n        \"role\": \"authenticated\",\r\n        \"actions\": [ \"*\" ]\r\n      }\r\n    ]\r\n  }\r\n}<\/code><\/pre>\n<p>This is the first place where DAB\u2019s abstraction layer becomes concrete. The agent will not talk to the table directly. It will talk to the <code>products<\/code> entity, using the actions and permissions defined in configuration.<\/p>\n<h2>Configure authentication and database access<\/h2>\n<p>Next, configure authentication through Microsoft Entra ID and connect SQL MCP Server to your SQL database. This keeps endpoint access under platform authentication while keeping the database connection out of your configuration file.<\/p>\n<p>Register an application in Microsoft Entra ID and create a service principal. Grant that identity the appropriate permissions in your SQL database, then construct a connection string that uses that identity. Store the value as an environment variable so it is not embedded in <code>dab-config.json<\/code>.<\/p>\n<h3><strong>Using the DAB CLI, configure your authentication provider:<\/strong><\/h3>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dab configure --runtime.host.authentication.provider AppService<\/code><\/pre>\n<p>Reference: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/dab-configure?tabs=bash-cli\">Configure runtime and data source with the DAB CLI | Microsoft Learn<\/a><\/p>\n<p>This command updates your configuration file to include the App Service authentication provider under the runtime host settings:<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">\"runtime\": {\r\n  \"host\": {\r\n    \"authentication\": {\r\n      \"provider\": \"AppService\"\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Security best practice<\/strong><\/p>Keep using an environment-based connection string so credentials are not stored in the configuration file. Combined with Microsoft Entra authentication, this creates a clean separation between configuration, endpoint identity, and database access.<\/div><\/p>\n<h3>Choose the MCP transport<\/h3>\n<p>SQL MCP Server can run in HTTP mode or STDIO mode. Use HTTP mode when you need a hosted endpoint, such as Azure App Service. Use STDIO mode when a local tool, such as Visual Studio Code, launches SQL MCP Server as a local process.<\/p>\n<table>\n<thead>\n<tr>\n<th>Mode<\/th>\n<th>Use when<\/th>\n<th>Authentication provider<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>HTTP<\/td>\n<td>Hosting in App Service or connecting remote clients<\/td>\n<td><code>AppService<\/code><\/td>\n<\/tr>\n<tr>\n<td>STDIO<\/td>\n<td>Running from local tools such as Visual Studio Code<\/td>\n<td><code>Simulator<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For this walkthrough, HTTP mode is the primary path because the goal is to host SQL MCP Server on Azure App Service.<\/p>\n<h2>Start SQL MCP Server locally<\/h2>\n<p>With the configuration in place, start SQL MCP Server from the project folder.<\/p>\n<h3>Using the DAB CLI, start SQL MCP Server in HTTP mode:<\/h3>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dab start<\/code><\/pre>\n<p>This starts the server in HTTP mode and exposes the MCP endpoint at <code>\/mcp<\/code>, along with REST and GraphQL endpoints.<\/p>\n<p>Reference: Start the runtime with the DAB CLI | Microsoft Learn<\/p>\n<p>For local agent scenarios, you can also run in STDIO mode. Before starting the server, switch the authentication provider to <code>Simulator<\/code>:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dab configure --runtime.host.authentication.provider Simulator\r\ndab start --mcp-stdio role:anonymous<\/code><\/pre>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Local agents<\/strong><\/p>STDIO mode is useful for tools like VS Code agent integrations where the MCP server runs as a local process instead of an HTTP endpoint.<\/div><\/p>\n<p>Before returning to HTTP mode, switch the authentication provider back to <code>AppService<\/code>:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">dab configure --runtime.host.authentication.provider AppService<\/code><\/pre>\n<p>At this point, SQL MCP Server is running locally and ready for endpoint testing.<\/p>\n<p>Reference: <a href=\"https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/How-to-Run-MCP.md\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/How-to-Run-MCP.md<\/a><\/p>\n<h3>Test the local endpoints<\/h3>\n<p>With SQL MCP Server running locally, test the endpoints exposed by your DAB configuration. This confirms the runtime can read the configuration, connect to SQL, and expose your entities through the enabled endpoint types.<\/p>\n<p>Start with REST by opening the generated Swagger or OpenAPI page and running a simple request against the <code>products<\/code> entity.<\/p>\n<p>Next, test GraphQL by running a simple query against the same entity. The result should match the data exposed through REST because both endpoints are generated from the same DAB configuration.<\/p>\n<p>Finally, confirm the MCP endpoint is available at <code>\/mcp<\/code>.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">http:\/\/localhost:&lt;port&gt;\/mcp<\/code><\/pre>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>MCP in the browser<\/strong><\/p>The <code>\/mcp<\/code> endpoint may show an error-looking response in the browser. That is expected. MCP endpoints are designed for MCP clients, not direct browser navigation.<\/div><\/p>\n<p>At this point, the local runtime is working and ready to be published to Azure App Service.<\/p>\n<h2>Deploy SQL MCP Server to Azure App Service<\/h2>\n<p>With the local runtime working, publish SQL MCP Server to Azure App Service using a code-based deployment. This avoids building and managing a container image while keeping the same <code>dab-config.json<\/code> file you tested locally.<\/p>\n<h3>Using Azure CLI, create the App Service resources:<\/h3>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">az group create --name &lt;resource-group&gt; --location &lt;location&gt;\r\n\r\naz appservice plan create `\r\n  --name &lt;plan-name&gt; `\r\n  --resource-group &lt;resource-group&gt; `\r\n  --sku B1 `\r\n  --is-linux\r\n\r\naz webapp create `\r\n  --name &lt;app-name&gt; `\r\n  --resource-group &lt;resource-group&gt; `\r\n  --plan &lt;plan-name&gt; `\r\n  --runtime \"DOTNETCORE:8.0\"<\/code><\/pre>\n<h3>Configure the SQL connection string as an App Service setting:<\/h3>\n<pre class=\"prettyprint language-powershell\"><code class=\"language-powershell\">az webapp config appsettings set `\r\n  --name &lt;app-name&gt; `\r\n  --resource-group &lt;resource-group&gt; `\r\n  --settings SQL_CONNECTION_STRING=\"&lt;connection-string&gt;\"<\/code><\/pre>\n<h3>Configure the startup command so App Service starts DAB:<\/h3>\n<pre class=\"prettyprint language-powershell\"><code class=\"language-powershell\">az webapp config set `\r\n  --name &lt;app-name&gt; `\r\n  --resource-group &lt;resource-group&gt; `\r\n  --startup-file \"dab start\"<\/code><\/pre>\n<p>Then publish the project to App Service using your preferred code deployment path, such as Visual Studio Code, GitHub Actions, or Zip Deploy. The important detail for this walkthrough is that the App Service is configured for code deployment, not container deployment.<\/p>\n<h2>Test the App Service endpoint<\/h2>\n<p>After publishing, open the App Service URL and confirm the app is running.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">https:\/\/&lt;app-name&gt;.azurewebsites.net<\/code><\/pre>\n<h3>Then confirm the health endpoint<\/h3>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">https:\/\/&lt;app-name&gt;.azurewebsites.net\/health<\/code><\/pre>\n<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>MCP error response<\/strong><\/p>Going to the raw <code>\/mcp<\/code> endpoint will show an error-looking response in the browser. That is expected. MCP endpoints are designed for MCP clients, not direct browser navigation. The important signal is that App Service routes the request to the running DAB app rather than returning an App Service startup or deployment error.<\/div><\/p>\n<p>If App Service authentication is enabled, sign in with Microsoft Entra ID before calling protected endpoints. This confirms the hosted endpoint is running through App Service, using platform authentication, and reading its database connection from App Service configuration.<\/p>\n<p>Next, test REST and GraphQL using the same entities you tested locally. Because the deployed app uses the same <code>dab-config.json<\/code>, the endpoint behavior should match your local runtime.<\/p>\n<p>SQL MCP Server is now running on Azure App Service without a container.<\/p>\n<h2>Next steps<\/h2>\n<p>At this point, SQL MCP Server is running on Azure App Service without a container. From here, connect your MCP client or agent platform to the hosted <code>\/mcp<\/code> endpoint, then test the same read and write operations you tested locally.<\/p>\n<p>Reference: <a href=\"https:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/tree\/main\">Deploy SQL MCP Server from the sample repo<\/a><\/p>\n<p><div  class=\"d-flex justify-content-left\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/sql\/mcp\" target=\"_blank\">Get started with SQL MCP Server<\/a><\/div><\/p>\n<h2>Want GitHub Copilot&#8217;s help?<\/h2>\n<p>Copy the following prompt into VS Code with GitHub Copilot (or your favorite agentic coding tool) and submit the prompt to your model.<\/p>\n<h3>Prerequisites for the prompt user:<\/h3>\n<ol>\n<li><strong>Azure subscription with permission to create<\/strong>: Resource group, Azure SQL logical server, Azure SQL database, App Service plan, Azure App Service, Microsoft Entra app registration<\/li>\n<li><strong>Local tools<\/strong>: Visual Studio Code, GitHub Copilot agent mode, Azure CLI, .NET SDK, PowerShell, Git, ZIP support<\/li>\n<li><strong>Azure sign-in<\/strong>: User must be signed in with <code>az login<\/code> and have the intended subscription selected with <code>az account set<\/code><\/li>\n<li><strong>Microsoft Entra permissions<\/strong>: Permission to create app registrations, Permission to create service principals, Permission to create client secrets, Permission to assign or grant database access<\/li>\n<li><strong>SQL permissions<\/strong>: Ability to configure Microsoft Entra admin on the SQL server, Ability to create database users, Ability to grant <code>db_datareader<\/code> and <code>db_datawriter<\/code><\/li>\n<li><strong>Network access<\/strong>: Ability to add the current client IP to the SQL firewall, Ability to allow App Service to reach Azure SQL<\/li>\n<\/ol>\n<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Not a simulation.<\/strong><\/p>Users should expect Copilot to create real Azure resources. They should review resource names, subscription, region, and cost settings before running the prompt.<\/div><\/p>\n<h3>Agent prompt<\/h3>\n<blockquote><p>You are GitHub Copilot running in agent mode with terminal access. Build, configure, deploy, and verify a complete SQL MCP Server on Azure App Service without containers.<\/p>\n<p>Goal<\/p>\n<p>Create a complete working sample from an empty local folder that deploys SQL MCP Server on Azure App Service using Data API builder. Use a new Azure Resource Group. Use the lowest practical App Service cost tier. Use the Azure SQL Database free offer when available. The final solution must expose MCP, REST, and GraphQL from one dab-config.json file and must not use Docker, Azure Container Apps, Azure Container Registry, Kubernetes, or any container image.<\/p>\n<p>Orchestration<\/p>\n<p>Use to-do lists, handoffs, and subagents when work can be run in parallel. Work hard to minimize context consumption over large, long operations.<\/p>\n<p>Before starting, create a concise execution plan with phases, dependencies, and validation checkpoints.<\/p>\n<p>Maintain a visible task list and update it as each phase completes.<\/p>\n<p>Use separate subagents or isolated workstreams for independent tasks, such as documentation review, Azure CLI command validation, DAB configuration, SQL schema creation, App Service deployment, and endpoint testing.<\/p>\n<p>Do not pass full logs, full files, or large command outputs between steps unless required. Summarize findings and preserve only the values needed for the next step.<\/p>\n<p>Store generated names, resource IDs, endpoint URLs, and important decisions in a small state file, such as <code>deployment-state.json<\/code>, so later steps do not rely on chat history.<\/p>\n<p>For long-running Azure operations, poll status with concise output. Do not repeatedly dump full JSON unless troubleshooting requires it.<\/p>\n<p>When a step fails, diagnose the smallest failing unit first, capture the exact error, and continue only after confirming the fix.<\/p>\n<p>Prefer deterministic scripts over one-off terminal commands when a step may need to be rerun.<\/p>\n<p>Do not report completion until the final validation checklist passes.<\/p>\n<p>Important constraints<\/p>\n<p>1. Use Azure CLI or Azure Developer CLI where appropriate.\n2. Prefer Azure CLI for explicit, auditable commands.\n3. Create a new Resource Group.\n4. Use Azure SQL Database free offer if available in this subscription and region.\n5. Assume the Azure SQL Database free offer may require Azure portal creation.\n6. Before creating a paid SQL database, check whether the free offer can be created through the current Azure CLI. If it cannot, stop and output the exact portal instruction for creating the free database manually. Do not treat this as a failure. Treat it as the expected safe path when the free offer is portal-only.\n7. Do not silently create a paid SQL database unless explicitly confirmed.\n8. Use the lowest cost App Service plan that supports the required runtime and startup command. Prefer Free F1 if it supports this scenario. If F1 does not support the required runtime or startup command reliably, use Basic B1 and clearly explain why.\n9. Deploy as code to Azure App Service. Do not deploy a container.\n10. Install Data API builder using dotnet tool install microsoft.dataapibuilder &#8211;prerelease.\n11. Use a local .NET tool manifest for DAB in the deployed App Service content.\n12. Create a working SQL table named dbo.products.\n13. Add the DAB entity named products.\n14. Enable MCP, REST, and GraphQL.\n15. Use AppService authentication provider for HTTP mode.\n16. Use Simulator authentication provider only for STDIO local testing.\n17. Store the SQL connection string in an environment variable or App Service setting named SQL_CONNECTION_STRING.\n18. Do not hardcode secrets into dab-config.json.\n19. Explicitly verify that dab-config.json uses @env(&#8216;SQL_CONNECTION_STRING&#8217;) before deployment.\n20. Do not print full connection strings, client secrets, SQL admin passwords, or access tokens. When logging values, redact secrets and show only resource names, server names, database names, and endpoint URLs.\n21. Produce all final files and a README.md.\n22. Verify local endpoints before deployment.\n23. Verify Azure endpoints after deployment.\n24. Include cleanup commands at the end.\n25. Configure App Service CORS only if testing from a browser-based MCP or agent client requires it. Do not use wildcard CORS unless clearly marked as temporary demo configuration.\n26. Do not report success until App Service logs show DAB started successfully, and REST, GraphQL, and MCP paths are reachable.<\/p>\n<p>Reference documentation<\/p>\n<p>Use these Microsoft Learn and sample repository references while implementing. Prefer these sources over guessing command syntax or behavior.<\/p>\n<p>SQL MCP Server:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/mcp\/<\/p>\n<p>Data API builder deployment options:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/deployment\/<\/p>\n<p>Data API builder CLI reference:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/<\/p>\n<p>Install the DAB CLI:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/install<\/p>\n<p>Initialize a DAB config:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/dab-init<\/p>\n<p>Configure DAB runtime and data source:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/data-api-builder\/command-line\/dab-configure<\/p>\n<p>Azure App Service authentication for MCP servers:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/app-service\/configure-authentication-mcp<\/p>\n<p>Azure App Service ZIP deployment:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/app-service\/deploy-zip<\/p>\n<p>Azure SQL Database free offer:\nhttps:\/\/learn.microsoft.com\/en-us\/azure\/azure-sql\/database\/free-offer<\/p>\n<p>Azure sample repository:\nhttps:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer<\/p>\n<p>Setup walkthrough:\nhttps:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/How-to-setup-DAB.md<\/p>\n<p>Run MCP walkthrough:\nhttps:\/\/github.com\/Azure-Samples\/SQL-MCP-NoContainer\/blob\/main\/How-to-Run-MCP.md<\/p>\n<p>Assumptions<\/p>\n<p>Use PowerShell syntax for commands unless the current shell is not PowerShell. If the terminal is bash, translate commands safely.<\/p>\n<p>When uncertain about syntax or behavior, consult the reference documentation above first, then inspect local CLI help such as az &#8211;help, az webapp &#8211;help, and dab &#8211;help.<\/p>\n<p>Use these default names unless a conflict requires unique suffixes:<\/p>\n<p>Resource group prefix: rg-sql-mcp-appservice\nLocation: eastus\nSQL logical server prefix: sqlmcp\nSQL database name: sqldb-sqlmcp-free\nSQL admin login: sqlmcpadmin\nProduct table: dbo.products\nApp Service plan prefix: asp-sql-mcp\nWeb app prefix: app-sql-mcp\nProject folder: sql-mcp-appservice<\/p>\n<p>Use a random short suffix for globally unique Azure resources.<\/p>\n<p>Required local project output<\/p>\n<p>Create a local folder with at least:<\/p>\n<p>README.md\ndab-config.json\nschema.sql\nseed.sql\ndeploy.ps1\ntest-local.ps1\ntest-azure.ps1\ncleanup.ps1\nstartup.sh for Linux App Service if Linux is used\nstartup.cmd for Windows App Service if Windows is used\n.config\/dotnet-tools.json\npackage or deployment files required for App Service code deployment<\/p>\n<p>Implementation steps<\/p>\n<p>Step 1: Inspect prerequisites<\/p>\n<p>Check whether these are installed:<\/p>\n<p>az\ndotnet\nPowerShell\nzip support\nDAB CLI\nsqlcmd or another Microsoft-supported SQL execution tool\nPython, only as ZIP fallback<\/p>\n<p>If Azure CLI is not logged in, run az login.<\/p>\n<p>Show the active subscription:<\/p>\n<p>az account show<\/p>\n<p>Ask for no interactive decisions unless absolutely required. If multiple subscriptions exist, use the active subscription and document it.<\/p>\n<p>Step 2: Create names and variables<\/p>\n<p>Generate a unique suffix.<\/p>\n<p>Set variables for:<\/p>\n<p>RESOURCE_GROUP\nLOCATION\nSQL_SERVER\nSQL_DB\nSQL_ADMIN_USER\nSQL_ADMIN_PASSWORD\nAPP_SERVICE_PLAN\nWEB_APP\nSQL_CONNECTION_STRING<\/p>\n<p>Generate a strong SQL admin password locally. Do not print the full password. Store it in script variables only.<\/p>\n<p>Step 3: Create Azure Resource Group<\/p>\n<p>Create a new Resource Group:<\/p>\n<p>az group create &#8211;name $RESOURCE_GROUP &#8211;location $LOCATION<\/p>\n<p>Step 4: Create Azure SQL Database using the free offer if possible<\/p>\n<p>First, investigate current Azure CLI support for creating an Azure SQL Database free offer.<\/p>\n<p>Use official az help and command discovery:<\/p>\n<p>az sql db create &#8211;help\naz sql db list-editions -l $LOCATION -o table<\/p>\n<p>Try to identify whether a free offer parameter exists. If a supported CLI parameter exists, use it.<\/p>\n<p>If the Azure SQL Database free offer cannot be applied through CLI in this environment, stop before creating a paid database and output this required portal instruction:<\/p>\n<p>\u201cCreate the Azure SQL Database from the Azure portal using Start free \/ Free offer applied, in the Resource Group named &lt;RESOURCE_GROUP&gt;, with database name &lt;SQL_DB&gt;. Choose the behavior that auto-pauses the database when the free monthly limit is reached. After creating the database, rerun this prompt or continue from Step 5.\u201d<\/p>\n<p>Do not create a paid SQL database as a fallback unless explicitly told.<\/p>\n<p>If a free SQL database can be created through CLI, create it. Requirements:<\/p>\n<p>Serverless General Purpose\nFree offer applied\nAuto-pause when free limit reached, where configurable\nMaximum size within free offer limits\nLowest cost settings<\/p>\n<p>Step 5: Create SQL logical server and configure access<\/p>\n<p>If not already created by the free offer flow, create the SQL logical server.<\/p>\n<p>Configure Microsoft Entra admin if possible using the current signed-in user. Also configure SQL admin credentials as fallback only for setup.<\/p>\n<p>Add firewall access for the current client IP so setup scripts can connect.<\/p>\n<p>If possible, also allow Azure services to access the server only if needed for App Service connectivity. Prefer the narrowest access compatible with the walkthrough.<\/p>\n<p>Step 6: Create schema and seed data<\/p>\n<p>Create schema.sql:<\/p>\n<p>CREATE TABLE dbo.products\n(\nProductID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_products PRIMARY KEY,\nName nvarchar(100) NOT NULL,\nCategory nvarchar(100) NOT NULL,\nPrice decimal(10,2) NOT NULL,\nInStock bit NOT NULL CONSTRAINT DF_products_InStock DEFAULT (1),\nCreatedAt datetime2 NOT NULL CONSTRAINT DF_products_CreatedAt DEFAULT (sysutcdatetime())\n);<\/p>\n<p>Create seed.sql:<\/p>\n<p>INSERT INTO dbo.products (Name, Category, Price, InStock)\nVALUES\n(N&#8217;Road Bike&#8217;, N&#8217;Cycling&#8217;, 1299.99, 1),\n(N&#8217;Mountain Bike&#8217;, N&#8217;Cycling&#8217;, 1499.99, 1),\n(N&#8217;Helmet&#8217;, N&#8217;Accessories&#8217;, 79.99, 1),\n(N&#8217;Water Bottle&#8217;, N&#8217;Accessories&#8217;, 12.99, 1),\n(N&#8217;Bike Light&#8217;, N&#8217;Accessories&#8217;, 24.99, 0);<\/p>\n<p>Apply schema and seed using sqlcmd if available. If sqlcmd is missing, install it or use an available SQL execution method. Prefer a Microsoft-supported tool. Verify the table exists and rows are present.<\/p>\n<p>Step 7: Create Microsoft Entra app registration and service principal for database access<\/p>\n<p>Create an app registration and service principal for SQL MCP Server database access.<\/p>\n<p>Capture:<\/p>\n<p>APPLICATION_CLIENT_ID\nTENANT_ID\nCLIENT_SECRET<\/p>\n<p>Create a client secret. Do not print the full secret.<\/p>\n<p>Grant the service principal access inside Azure SQL Database.<\/p>\n<p>Use T-SQL similar to:<\/p>\n<p>CREATE USER [&lt;app-display-name-or-client-id&gt;] FROM EXTERNAL PROVIDER;\nALTER ROLE db_datareader ADD MEMBER [&lt;principal-name&gt;];\nALTER ROLE db_datawriter ADD MEMBER [&lt;principal-name&gt;];<\/p>\n<p>If CREATE USER &#8230; FROM EXTERNAL PROVIDER fails, verify that the signed-in user is the Microsoft Entra admin for the SQL logical server. If not, set the Entra admin or provide the exact portal or CLI command required.<\/p>\n<p>If direct EXTERNAL PROVIDER creation fails because Microsoft Entra admin is not configured or service principal resolution fails, diagnose the problem and provide the exact fix. Do not skip this silently.<\/p>\n<p>For a simplified fallback suitable only for demo, allow SQL authentication using the SQL admin connection string, but label it clearly as a demo fallback and keep secrets out of dab-config.json.<\/p>\n<p>Step 8: Install Data API builder locally and globally<\/p>\n<p>Install DAB globally for local convenience:<\/p>\n<p>dotnet tool install microsoft.dataapibuilder &#8211;prerelease -g<\/p>\n<p>If already installed, update it:<\/p>\n<p>dotnet tool update microsoft.dataapibuilder &#8211;prerelease -g<\/p>\n<p>Verify:<\/p>\n<p>dab &#8211;version<\/p>\n<p>Inside the project folder, create a local tool manifest for deployment:<\/p>\n<p>dotnet new tool-manifest\ndotnet tool install microsoft.dataapibuilder &#8211;prerelease<\/p>\n<p>Verify the manifest exists:<\/p>\n<p>.config\/dotnet-tools.json<\/p>\n<p>Step 9: Initialize DAB configuration<\/p>\n<p>Create or move into the project folder.<\/p>\n<p>Set local environment variable:<\/p>\n<p>SQL_CONNECTION_STRING=&lt;connection string&gt;<\/p>\n<p>Use Microsoft Entra service principal authentication where possible:<\/p>\n<p>Server=tcp:&lt;server&gt;.database.windows.net,1433;Database=&lt;database&gt;;Authentication=Active Directory Service Principal;User Id=&lt;client-id&gt;;Password=&lt;client-secret&gt;;Encrypt=True;TrustServerCertificate=False;<\/p>\n<p>Initialize:<\/p>\n<p>dab init &#8211;database-type mssql &#8211;host-mode Development &#8211;connection-string &#8220;@env(&#8216;SQL_CONNECTION_STRING&#8217;)&#8221;<\/p>\n<p>Configure auth provider for HTTP mode:<\/p>\n<p>dab configure &#8211;runtime.host.authentication.provider AppService<\/p>\n<p>Add the products entity:<\/p>\n<p>dab add products &#8211;source dbo.products &#8211;permissions &#8220;authenticated:*&#8221;<\/p>\n<p>Inspect dab-config.json and ensure:<\/p>\n<p>data-source.database-type is mssql\ndata-source.connection-string is @env(&#8216;SQL_CONNECTION_STRING&#8217;)\nruntime.rest.enabled is true\nruntime.graphql.enabled is true\nruntime.mcp.enabled is true\nruntime.host.authentication.provider is AppService\nentities.products exists\nproducts permissions include authenticated all actions<\/p>\n<p>If MCP is not enabled by default, update the configuration to enable it.<\/p>\n<p>Step 10: Test locally in HTTP mode<\/p>\n<p>Start DAB:<\/p>\n<p>dab start<\/p>\n<p>Find the local port from output.<\/p>\n<p>Test:<\/p>\n<p>REST endpoint for products\nGraphQL endpoint\nMCP endpoint path \/mcp<\/p>\n<p>The \/mcp path may show an error-looking response in a browser. That is expected because MCP endpoints are for MCP clients, not browser navigation. The test should confirm routing reaches the DAB app and is not a startup or binding failure.<\/p>\n<p>Document exact local URLs in README.md.<\/p>\n<p>Step 11: Test local STDIO mode<\/p>\n<p>Switch auth provider:<\/p>\n<p>dab configure &#8211;runtime.host.authentication.provider Simulator<\/p>\n<p>Run:<\/p>\n<p>dab start &#8211;mcp-stdio role:anonymous<\/p>\n<p>Do not leave the config in Simulator mode for App Service deployment.<\/p>\n<p>Switch back:<\/p>\n<p>dab configure &#8211;runtime.host.authentication.provider AppService<\/p>\n<p>Step 12: Create App Service resources<\/p>\n<p>Create the lowest cost practical App Service plan.<\/p>\n<p>Before creating the web app, inspect available runtimes:<\/p>\n<p>az webapp list-runtimes &#8211;os windows\naz webapp list-runtimes &#8211;os linux<\/p>\n<p>If creating a Windows App Service, use runtime DOTNET:8.<\/p>\n<p>If creating a Linux App Service, use runtime DOTNETCORE:8.0.<\/p>\n<p>Choose the runtime string that matches the selected operating system.<\/p>\n<p>First attempt to use Free F1 if compatible with the selected OS and runtime. If using Linux and F1 is not supported or not practical for this startup scenario, use B1.<\/p>\n<p>Create App Service Plan and Web App.<\/p>\n<p>For Windows Free F1:<\/p>\n<p>az appservice plan create `\n&#8211;name $APP_SERVICE_PLAN `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;location $LOCATION `\n&#8211;sku F1<\/p>\n<p>az webapp create `\n&#8211;name $WEB_APP `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;plan $APP_SERVICE_PLAN `\n&#8211;runtime &#8220;DOTNET:8&#8221;<\/p>\n<p>For Linux Basic B1 fallback:<\/p>\n<p>az appservice plan create `\n&#8211;name $APP_SERVICE_PLAN `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;location $LOCATION `\n&#8211;sku B1 `\n&#8211;is-linux<\/p>\n<p>az webapp create `\n&#8211;name $WEB_APP `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;plan $APP_SERVICE_PLAN `\n&#8211;runtime &#8220;DOTNETCORE:8.0&#8243;<\/p>\n<p>If the chosen runtime syntax fails, inspect available runtimes again and choose the lowest-cost working runtime. Document the choice.<\/p>\n<p>Step 13: Configure App Service settings<\/p>\n<p>Configure SQL_CONNECTION_STRING as an App Service app setting.<\/p>\n<p>az webapp config appsettings set `\n&#8211;name $WEB_APP `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;settings SQL_CONNECTION_STRING=&#8221;&lt;redacted-connection-string-value&gt;&#8221;<\/p>\n<p>Use the actual connection string in the command, but do not print it in logs or README.<\/p>\n<p>Before deploying, explicitly verify that dab-config.json uses @env(&#8216;SQL_CONNECTION_STRING&#8217;) and does not contain a literal local or Azure SQL connection string.<\/p>\n<p>Step 14: Create startup scripts<\/p>\n<p>Use a local .NET tool manifest for DAB in the deployed App Service content.<\/p>\n<p>Create startup.sh for Linux App Service:<\/p>\n<p>#!\/bin\/sh\ndotnet tool restore\ndotnet tool run dab start<\/p>\n<p>Ensure startup.sh has Unix line endings.<\/p>\n<p>If the environment supports chmod, run:<\/p>\n<p>chmod +x startup.sh<\/p>\n<p>Set Linux App Service startup command to:<\/p>\n<p>startup.sh<\/p>\n<p>Use:<\/p>\n<p>az webapp config set `\n&#8211;name $WEB_APP `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;startup-file &#8220;startup.sh&#8221;<\/p>\n<p>Create startup.cmd for Windows App Service:<\/p>\n<p>dotnet tool restore\ndotnet tool run dab start<\/p>\n<p>Set Windows App Service startup command to:<\/p>\n<p>startup.cmd<\/p>\n<p>Use:<\/p>\n<p>az webapp config set `\n&#8211;name $WEB_APP `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;startup-file &#8220;startup.cmd&#8221;<\/p>\n<p>Do not rely on a globally installed DAB tool inside App Service. The startup script must restore and run the local tool manifest.<\/p>\n<p>Step 15: Package and deploy as code<\/p>\n<p>Create a deployment package containing:<\/p>\n<p>dab-config.json\n.config\/dotnet-tools.json\nstartup.sh if Linux is used\nstartup.cmd if Windows is used\nREADME.md optional\nany project files required for dotnet tool restore<\/p>\n<p>Use ZIP deploy.<\/p>\n<p>If PowerShell Compress-Archive is available:<\/p>\n<p>Compress-Archive -Path * -DestinationPath deploy.zip -Force<\/p>\n<p>If native ZIP tooling is missing, use Python\u2019s built-in zipfile module to create the deployment ZIP. Do not stop only because Compress-Archive or zip is unavailable.<\/p>\n<p>Deploy:<\/p>\n<p>az webapp deploy `\n&#8211;resource-group $RESOURCE_GROUP `\n&#8211;name $WEB_APP `\n&#8211;src-path deploy.zip `\n&#8211;type zip<\/p>\n<p>Or use the current recommended Azure CLI ZIP deployment command if different. Verify against:<\/p>\n<p>az webapp deploy &#8211;help<\/p>\n<p>Step 16: Verify App Service startup<\/p>\n<p>Enable application logging:<\/p>\n<p>az webapp log config &#8211;name $WEB_APP &#8211;resource-group $RESOURCE_GROUP &#8211;application-logging filesystem &#8211;level information<\/p>\n<p>Tail logs:<\/p>\n<p>az webapp log tail &#8211;name $WEB_APP &#8211;resource-group $RESOURCE_GROUP<\/p>\n<p>Open:<\/p>\n<p>https:\/\/&lt;web-app-name&gt;.azurewebsites.net<\/p>\n<p>Open health endpoint if supported:<\/p>\n<p>https:\/\/&lt;web-app-name&gt;.azurewebsites.net\/health<\/p>\n<p>Open MCP endpoint:<\/p>\n<p>https:\/\/&lt;web-app-name&gt;.azurewebsites.net\/mcp<\/p>\n<p>The \/mcp endpoint may show an error-looking response in the browser. That is expected. Confirm the response is from the DAB app and not from App Service default page, deployment failure, or process startup failure.<\/p>\n<p>If the app returns 503, inspect logs, verify dotnet tool restore ran, verify the startup script is included in the ZIP package, verify the startup command points to the correct script, and verify the correct App Service runtime string was used.<\/p>\n<p>Do not report success until App Service logs show DAB started successfully, and REST, GraphQL, and MCP paths are reachable.<\/p>\n<p>Step 17: Verify REST and GraphQL in Azure<\/p>\n<p>Test REST:<\/p>\n<p>https:\/\/&lt;web-app-name&gt;.azurewebsites.net\/api\/products<\/p>\n<p>Test GraphQL:<\/p>\n<p>https:\/\/&lt;web-app-name&gt;.azurewebsites.net\/graphql<\/p>\n<p>If App Service authentication is enabled and requests fail due to auth, document how to sign in or obtain a token.<\/p>\n<p>Step 18: Configure App Service authentication with Microsoft Entra ID<\/p>\n<p>Enable App Service authentication if not already enabled.<\/p>\n<p>Use Microsoft Entra as identity provider.<\/p>\n<p>Configure the hosted SQL MCP Server as a protected MCP endpoint according to Azure App Service MCP authentication guidance.<\/p>\n<p>Ensure the authentication provider in dab-config.json remains:<\/p>\n<p>&#8220;provider&#8221;: &#8220;AppService&#8221;<\/p>\n<p>If dynamic client registration is not supported by the client, document the required preauthorization or client configuration step.<\/p>\n<p>If testing from a browser-based MCP or agent client, configure App Service CORS for the required origin. Do not use wildcard CORS unless this is explicitly marked as a temporary demo setting.<\/p>\n<p>Step 19: Produce VS Code MCP client example<\/p>\n<p>Create .vscode\/mcp.json or equivalent MCP client sample.<\/p>\n<p>Include both HTTP and STDIO examples.<\/p>\n<p>HTTP example should point to:<\/p>\n<p>https:\/\/&lt;web-app-name&gt;.azurewebsites.net\/mcp<\/p>\n<p>STDIO example should use:<\/p>\n<p>dotnet\ntool\nrun\ndab\nstart\n&#8211;mcp-stdio\nrole:anonymous<\/p>\n<p>Make clear that HTTP uses AppService authentication and STDIO uses Simulator authentication.<\/p>\n<p>Step 20: Generate README.md<\/p>\n<p>Create a polished README.md with:<\/p>\n<p>Title: SQL MCP Server on Azure App Service without containers<\/p>\n<p>Sections:<\/p>\n<p>Overview\nArchitecture\nWhat gets created\nCost notes\nPrerequisites\nSetup\nLocal run\nHTTP vs STDIO transport\nDeploy to Azure App Service\nTest endpoints\nMCP browser error note\nTroubleshooting\nCleanup<\/p>\n<p>Include the final resource names and URLs.<\/p>\n<p>Include exact commands used.<\/p>\n<p>Include a clear warning:<\/p>\n<p>\u201cThe Azure SQL Database free offer has monthly limits. Keep the database in auto-pause when free limit reached mode to avoid charges. If the free offer could not be applied automatically, complete the portal step before running deployment.\u201d<\/p>\n<p>Include another clear warning:<\/p>\n<p>\u201cThis prompt creates a complete demo-grade deployment with security-conscious defaults. Review identity, CORS, database permissions, SKU choices, and cost controls before using it for production.\u201d<\/p>\n<p>Step 21: Create cleanup script<\/p>\n<p>Create cleanup.ps1:<\/p>\n<p>az group delete &#8211;name $RESOURCE_GROUP &#8211;yes &#8211;no-wait<\/p>\n<p>Also include optional local cleanup:<\/p>\n<p>Remove generated deploy.zip\nUnset SQL_CONNECTION_STRING\nRemove local DAB tool only if the user requests it, not by default<\/p>\n<p>Step 22: Final validation summary<\/p>\n<p>At the end, output a compact summary:<\/p>\n<p>Resource Group:\nSQL Server:\nSQL Database:\nApp Service Plan:\nWeb App:\nApp URL:\nMCP endpoint:\nREST endpoint:\nGraphQL endpoint:\nLocal config file:\nCleanup command:<\/p>\n<p>Also list any manual steps that could not be automated.<\/p>\n<p>Do not stop early unless a required security or billing decision is blocked. Prefer completing the solution end to end with safe defaults.<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Run SQL MCP Server on Azure App Service without containers. This walkthrough uses Data API builder to configure authentication, expose MCP, REST, and GraphQL endpoints, and deploy as code.<\/p>\n","protected":false},"author":96788,"featured_media":6627,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,597,720],"tags":[727,560,711],"class_list":["post-6925","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sql","category-data-api-builder-2","category-sql-mcp-server-2","tag-azure-app-service","tag-data-api-builder","tag-sql-mcp-server"],"acf":[],"blog_post_summary":"<p>Run SQL MCP Server on Azure App Service without containers. This walkthrough uses Data API builder to configure authentication, expose MCP, REST, and GraphQL endpoints, and deploy as code.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6925","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=6925"}],"version-history":[{"count":3,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6925\/revisions"}],"predecessor-version":[{"id":6939,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6925\/revisions\/6939"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/6627"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=6925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=6925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=6925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}