Deploy a hosted Azure SQL Model Context Protocol (MCP) server to Azure Connector Namespace. The sample provisions Azure SQL Database, exposes a BlogPost table through Data API Builder MCP, and configures managed identity access so MCP clients such as GitHub Copilot in Visual Studio Code can query the database.
About this sample
Before you begin
Run this sample
Sample details
Clean up
Related links
- Applies to: Azure SQL Database
- Key features: Azure Connector Namespace, hosted MCP server, Data API Builder, managed identity, Application Insights
- Workload: AI agent data access
- Programming Language: Bicep, PowerShell, Bash, JSON
This sample deploys a hosted mcp-sql server in Azure Connector Namespace. The hosted MCP server uses Data API Builder configuration to expose a SQL table through MCP tools. The SQL database is seeded with a dbo.BlogPost table containing links to Microsoft Learn and .NET Blog posts. For more background, see Hosted MCP servers in Azure Connector Namespace.
To run this sample, you need the following prerequisites.
Software prerequisites:
- Azure CLI (
az) - Azure Developer CLI (
azd) - PowerShell 7+ on Windows, or Bash on Linux/macOS
Azure prerequisites:
- An Azure subscription with permissions to create resource groups and resources.
- Permission to create Azure SQL Database, Application Insights, Log Analytics workspace, and Connector Namespace resources.
- Permission to create an Azure SQL Microsoft Entra administrator for the signed-in user.
From this folder:
azd auth login
azd init
azd upWhen you run azd init for the first time, it detects the existing azure.yaml and Bicep templates:
- "How do you want to initialize your app?" — Select Use code in the current directory.
- "Confirm and continue initializing this app" — Press Enter to confirm the detected services.
- "Enter a new environment name" — Pick any name, for example
mcp-dev. This name is used as a prefix for Azure resource names.
You only need to run azd init once. Subsequent deployments only require azd up.
When you run azd up, you are prompted for:
-
Azure Subscription: Select the Azure subscription to deploy to.
-
Azure location: Choose a supported region (e.g.
eastasia,westcentralus). -
deployerLoginNameinfrastructure parameter: Enter your Azure sign-in email or user principal name, for exampleuser@contoso.com. If you don't know the value, run the following command in a different terminal instance and use the result:az account show --query user.name -o tsv
-
connectorNamespaceIdentityTypeinfrastructure parameter: EnterSystemAssignedfor the default Connector Namespace managed identity, orUserAssignedto create and attach a user-assigned managed identity.
The deployerLoginName value is used to create the Azure SQL server with Microsoft Entra-only authentication and set you as the SQL Entra admin.
When azd up prompts for connectorNamespaceIdentityType, enter UserAssigned to test with a user-assigned managed identity.
When set to UserAssigned, the template creates a user-assigned managed identity, attaches it to the Connector Namespace, passes its client ID to the hosted MCP server, and grants that identity access to Azure SQL.
Choose the identity type before the first deployment. Connector Namespace doesn't allow changing attached user-assigned identities after the namespace is created. To switch between SystemAssigned and UserAssigned, create a new azd environment or run azd down --purge and deploy again.
After azd up completes, the MCP endpoint URL is printed. Add it to VS Code using the UI:
- In VS Code, open the Command Palette:
- Windows/Linux: Ctrl+Shift+P
- macOS: Cmd+Shift+P
- Run MCP: Add Server.
- Choose HTTP as the server type.
- Paste the MCP endpoint URL printed by
azd up. - Enter a server name, for example
sql-mcp. - Choose whether to save the server in user settings or workspace settings.
- Start the
sql-mcpserver when VS Code prompts you.
VS Code prompts you to sign in with Microsoft. Then use Copilot Chat to query your database, for example: "List the blog posts in the database."
┌─────────────────────────────────────┐
│ Connector Namespace │
│ (Microsoft.Web/connectorGateways) │
│ │
│ ┌───────────────────────────────┐ │
│ │ Hosted SQL MCP Server │ │
│ │ (Data API Builder) │ │
│ │ │ │
│ │ MI ───► Azure SQL DB │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
▲
│ MCP (HTTP + SSE)
│
VS Code / Copilot / MCP Client
| Resource | Purpose |
|---|---|
| Resource Group | Container for all deployed resources |
| Azure SQL Server | Entra-only auth, with you as SQL admin |
| Azure SQL Database | Basic SKU database with a BlogPost sample table used by the MCP server |
| SQL Firewall Rules | Allows Azure services/resources, Azure Portal Query Editor, and your public IP for setup |
| Log Analytics Workspace | Stores Application Insights telemetry |
| Application Insights | Collects telemetry from the hosted MCP server |
| Connector Namespace | Hosts MCP servers with system-assigned managed identity by default, or user-assigned managed identity when configured |
| Hosted SQL MCP Server | mcp-sql server config on the namespace |
| MCP Access Policy | Grants you access to invoke MCP tools |
Resource names use the pattern <type>-<environment-name>-<short-suffix> where possible, for example sql-mcp-dev-a1b2c3d4. The suffix is deterministic for the subscription, environment name, and location so names are readable and stable across redeployments.
| Step | Action |
|---|---|
| Provision | Deploys Azure SQL, SQL firewall rules, Log Analytics, Application Insights, Connector Namespace, hosted mcp-sql, and MCP access policy. |
| Post-provision | Allows your public IP through the SQL firewall, creates and seeds dbo.BlogPost, creates the Connector Namespace managed identity SQL user, grants SQL permissions, generates dab-config.generated.json, and prints the MCP endpoint plus Azure Portal resource group link. |
The hosted MCP server receives:
- the included
dab-config.jsonasproperties.hostedMcpServer.configuration.configFile - the generated SQL connection string as
SQL_CONNECTION_STRING - the Application Insights connection string as
APPLICATIONINSIGHTS_CONNECTION_STRING AZURE_CLIENT_IDwhen the sample is configured to use a user-assigned managed identity
No SQL or Application Insights connection string is checked in.
This sample includes a ready-to-use dab-config.json. If you want to create or customize a Data API Builder configuration from scratch, install the DAB CLI and use it to generate a config file. For more information, see Install the Data API Builder CLI.
For details about the hosted MCP server resource model and supported server types, see Hosted MCP servers in Azure Connector Namespace. For a walkthrough focused on the SQL hosted MCP server, see Hosted MCP server quickstart for SQL.
After deployment, the post-provision output includes a link to the Azure resource group in the Azure Portal. Use that page to inspect the SQL server, Application Insights resource, Log Analytics workspace, Connector Namespace, and hosted MCP server.
To allow additional users to connect to the MCP server:
- Open the deployed Connector Namespace resource in the Azure Portal.
- Open the hosted MCP server configuration, for example
sql-mcp. - Add an access policy for each additional user or group that should be allowed to invoke the MCP server.
The post-provision hook creates and seeds dbo.BlogPost with these entries:
| Title | Source |
|---|---|
| Hosted MCP servers in Azure Connector Namespace | Microsoft Learn |
| Durable Workflows in Microsoft Agent Framework | .NET Blog |
The deployment configures two SQL firewall paths:
| Rule | When | Purpose |
|---|---|---|
AllowAzureServices |
During Bicep provisioning | Allows Azure services/resources, including Azure Portal Query Editor, to reach the SQL server. |
AllowDeployerIp |
During post-provision | Detects your current public IP and allows your local machine to seed and query the database. |
If SQL reports a different blocked client IP during post-provision, the script adds that IP and retries.
Using azd:
azd down --purgeOr with Azure CLI:
# Replace <environment-name> with your azd environment name.
az group delete --name rg-<environment-name> --yes --no-wait
# Optional: remove the subscription-scope deployment record.
az deployment sub delete --name <environment-name>