Guide for SQL MCP Server (Data API Builder MCP). Use when configuring databases for AI agent access via Model Context Protocol.
This skill powers GitHub Copilot assistance for SQL MCP Server, a feature of Data API Builder (DAB) version 1.7+ that exposes databases to AI agents via the Model Context Protocol (MCP). It provides conversational guidance for configuring, deploying, and securing SQL MCP Server for AI-powered database workflows.
SQL MCP Server enables AI agents to interact with databases through a secure, typed interface. It's Data API Builder with MCP capabilities, not a separate product. Users who need MCP capabilities but have never heard of DAB should be guided through the complete setup.
/mcp that exposes database entities as MCP toolsdescribe_entities, create_record, read_records, update_record, delete_record, execute_entityread_records operationsAI Agent (VS Code, Foundry, Custom)
→ MCP Protocol
→ SQL MCP Server (/mcp endpoint)
→ DAB Entity Abstraction Layer
→ Database (SQL Server, PostgreSQL, MySQL, etc.)
SQL MCP Server uses the same dab-config.json as regular DAB:
data-source: Database connection settingsruntime.mcp: MCP-specific settings (enabled, path, tool controls)entities: Exposed tables/views/stored procedures with descriptions and permissionsMCP is enabled by default when you have DAB 1.7+. You only need to configure it when you want to restrict what agents can do.
Scenario 1: User comes with MCP needs
Scenario 2: User knows DAB, wants MCP
Scenario 3: User confused about naming
| Term | What It Means |
|---|---|
| SQL MCP Server | Marketing name for DAB's MCP capabilities |
| Data API Builder (DAB) | The underlying engine that powers everything |
| MCP | Model Context Protocol - standard for AI agent tool discovery |
| DML Tools | The six CRUD+execute operations exposed via MCP |
| Entity abstraction | DAB's security layer that protects your database schema |
Critical: SQL MCP Server requires Data API builder 1.7+ (currently in preview/RC).
dotnet tool install microsoft.dataapibuilder --prerelease
Or update existing:
dotnet tool update microsoft.dataapibuilder --prerelease
dab --version
# Should show 1.7.x or higher
Recommended Path:
Example: 5-Minute Setup
# 1. Initialize config (MCP enabled by default)
dab init \
--database-type mssql \
--connection-string "@env('DATABASE_CONNECTION_STRING')" \
--host-mode Development \
--config dab-config.json
# 2. Add entity with description
dab add Products \
--source dbo.Products \
--permissions "anonymous:read" \
--description "Product catalog with pricing, inventory, and supplier information"
# 3. Add field descriptions (critical for AI understanding)
dab update Products \
--fields.name ProductID \
--fields.description "Unique product identifier" \
--fields.primary-key true
dab update Products \
--fields.name ProductName \
--fields.description "Display name of the product"
dab update Products \
--fields.name UnitPrice \
--fields.description "Retail price per unit in USD"
# 4. Validate and start
dab validate && dab start
Connect from VS Code:
Create .vscode/mcp.json:
{
"servers": {
"sql-mcp-server": {
"type": "http",
"url": "http://localhost:5000/mcp"
}
}
}
Default behavior: MCP is enabled with all tools active. Only configure when restricting.
{
"runtime": {
"mcp": {
"enabled": true, // default: true
"path": "/mcp", // default: /mcp
"description": "Optional server description for clients",
"dml-tools": {
"describe-entities": true, // default: true
"create-record": true, // default: true
"read-records": true, // default: true
"update-record": true, // default: true
"delete-record": true, // default: true
"execute-entity": true // default: true
}
}
}
}
# Enable/disable MCP globally
dab configure --runtime.mcp.enabled true
dab configure --runtime.mcp.path "/mcp"
# Disable specific tools globally (restrict all agents)
dab configure --runtime.mcp.dml-tools.delete-record false
dab configure --runtime.mcp.dml-tools.create-record false
# Add server description (shown to MCP clients)
dab configure --runtime.mcp.description "Production inventory database MCP endpoint"
Default: Entities participate in MCP automatically. Only configure to exclude or restrict.
{
"entities": {
"Products": {
"mcp": {
"dml-tools": true // default: true (all tools allowed per runtime settings)
}
},
"SensitiveData": {
"mcp": {
"dml-tools": false // exclude this entity from MCP completely
}
},
"AuditLogs": {
"mcp": {
"dml-tools": {
"create-record": true, // allow create
"read-records": true, // allow read
"update-record": false, // prevent updates
"delete-record": false // prevent deletes
}
}
}
}
}
SQL MCP Server exposes exactly six tools to AI agents:
Purpose: Returns all entities the current role can access, including fields, types, descriptions, and allowed operations.
Key Points:
--description flagsExample Response:
{
"entities": [
{
"name": "Products",
"description": "Product catalog with pricing and inventory",
"fields": [
{
"name": "ProductId",
"type": "int",
"isKey": true,
"description": "Unique product identifier"
},
{
"name": "UnitPrice",
"type": "decimal",
"description": "Retail price in USD"
}
],
"operations": ["read_records", "update_record"]
}
]
}
Purpose: Insert new rows into tables.
Requirements:
create permission for current rolePurpose: Query tables and views with filtering, sorting, pagination, and field selection.
Features:
Purpose: Modify existing rows.
Requirements:
Purpose: Remove existing rows.
Requirements:
Warning: Many production deployments disable this tool globally to prevent accidental data loss.
Purpose: Execute stored procedures.
Features:
Why descriptions matter: AI agents rely on context. Without descriptions, agents only see technical names like ProductID. With descriptions, they understand it's "Unique identifier for each product in the catalog."
# Add during creation
dab add Products \
--source dbo.Products \
--permissions "anonymous:*" \
--description "Product catalog with pricing, inventory, and supplier information"
# Update existing entity
dab update Products \
--description "Product catalog with pricing, inventory, and supplier information"
# Single field
dab update Products \
--fields.name UnitPrice \
--fields.description "Retail price per unit in USD"
# Multiple fields (call multiple times)
dab update Products \
--fields.name ProductID \
--fields.description "Unique identifier for each product" \
--fields.primary-key true
dab update Products \
--fields.name UnitsInStock \
--fields.description "Current inventory count available for purchase"
dab add GetOrdersByDateRange \
--source dbo.usp_GetOrdersByDateRange \
--source.type stored-procedure \
--permissions "authenticated:execute" \
--description "Retrieves all orders placed within a specified date range" \
--parameters.name "StartDate,EndDate,CustomerID" \
--parameters.description "Beginning of date range (inclusive),End of date range (inclusive),Optional customer ID filter (null returns all customers)" \
--parameters.required "true,true,false" \
--parameters.default ",,null"
Do:
Don't:
Inbound (Client → SQL MCP Server): How AI agents authenticate to your MCP endpoint Outbound (SQL MCP Server → Database): How DAB authenticates to your database
Option 1: SQL User/Password (Development)
dab init \
--database-type mssql \
--connection-string "@env('SQL_CONNECTION_STRING')"
Environment variable:
SQL_CONNECTION_STRING=Server=tcp:myserver.database.windows.net,1433;Database=mydb;User ID=myuser;Password=mypass;Encrypt=True;
Option 2: Managed Identity (Recommended for Azure)
Server=tcp:myserver.database.windows.net,1433;Database=mydb;Authentication=Active Directory Managed Identity;
For User-Assigned Managed Identity (UAMI):
Server=tcp:myserver.database.windows.net,1433;Database=mydb;Authentication=Active Directory Managed Identity;User Id=<uami-client-id>;
Option 1: Anonymous (Development Only)
# No auth config needed - defaults to anonymous
# Agents use only what 'anonymous' role permits
dab configure --runtime.host.authentication.provider AppService
Option 2: Microsoft Entra ID / JWT (Production)
dab configure \
--runtime.host.authentication.provider EntraId
dab configure \
--runtime.host.authentication.jwt.audience "api://<app-id>"
dab configure \
--runtime.host.authentication.jwt.issuer "https://login.microsoftonline.com/<tenant-id>/v2.0"
# Grant permissions for authenticated users
dab update Products --permissions "authenticated:read"
Option 3: API Gateway (Key-Based)
/mcp endpoint with Azure API Management or similar gatewayEvery DML tool operation enforces RBAC rules:
# Anonymous can only read specific fields
dab add Products --source dbo.Products --permissions "anonymous:read"
dab update Products --fields.exclude "Cost,Margin,SupplierID"
# Authenticated users can CRUD
dab update Products --permissions "authenticated:*"
# Admin can see everything
dab update Products --permissions "admin:*"
Steps:
dab start in terminal.vscode/mcp.json in workspaceMCP Config:
{
"servers": {
"sql-mcp-server": {
"type": "http",
"url": "http://localhost:5000/mcp"
}
}
}
Key Steps:
dab-config.jsonDockerfile:
FROM mcr.microsoft.com/azure-databases/data-api-builder:1.7.83-rc
COPY dab-config.json /App/dab-config.json
⚠️ ANTI-PATTERN: Never use Azure Files, storage accounts, or volume mounts for
dab-config.json. Always build a custom Docker image with the config embedded and push to ACR. Storage mounts add latency, failure modes, and unnecessary complexity.
Deploy:
az containerapp create \
--name sql-mcp-server \
--resource-group rg-sql-mcp \
--environment sql-mcp-env \
--image <acr>.azurecr.io/sql-mcp-server:1 \
--target-port 5000 \
--ingress external \
--secrets "mssql-connection-string=<connection-string>" \
--env-vars "MSSQL_CONNECTION_STRING=secretref:mssql-connection-string"
Integration Pattern:
appsettings.json or environmentConnection Steps:
Ask:
Guide through:
Answer:
dotnet tool update microsoft.dataapibuilder --prereleasedab start - /mcp endpoint is liveTroubleshoot:
dab add)--permissions)mcp.dml-tools: false)runtime.mcp.dml-tools)describe_entities first?Options:
dab configure --runtime.mcp.dml-tools.delete-record falsemcp.dml-tools.delete-record: false in entity configdelete action to agent's roleAnswer:
Guide:
--description in dab add or dab update--fields.name and --fields.description in dab update--parameters.name and --parameters.description for stored proceduresExample:
dab update Products \
--fields.name UnitPrice \
--fields.description "Retail price per unit in USD (includes tax)"
Recommend:
Key considerations:
delete-record tool if appropriatedab validate && dab start
Validation checks:
Health check:
curl http://localhost:5000/health
List tools:
# Use MCP Inspector or VS Code MCP extension
# Connect to http://localhost:5000/mcp
# Verify 6 tools appear: describe_entities, create_record, read_records, update_record, delete_record, execute_entity
VS Code Copilot Chat Examples:
"Which products have low inventory?"
"Show me all products under $50"
"What categories do we have?"
"How many units of Product X are in stock?"
OpenTelemetry Tracing:
Health Checks:
/health endpoint for liveness/readinessLogging:
dab configure --runtime.telemetry.application-insights.connection-string "@env('APPLICATIONINSIGHTS_CONNECTION_STRING')"
Steps:
dotnet tool update microsoft.dataapibuilder --prereleasedab startNo breaking changes - MCP is additive to existing REST/GraphQL endpoints.
Key differences:
Migration approach:
Checks:
dab --versionruntime.mcp.enabled: true/mcp, check runtime.mcp.pathChecks:
dab validatepermissions configmcp.dml-tools: falsedescribe_entities first?Checks:
echo $DATABASE_CONNECTION_STRING@env('VAR_NAME').env file in working directory? (local dev)Checks:
dbo.Products)--source.key-fields?Solutions:
dab update <entity> --cache.enabled true --cache.ttl 300Checks:
runtime.host.authentication)audience and issuer correct?dab init --database-type mssql --connection-string "@env('CONNECTION_STRING')" --host-mode Development
# Table
dab add Products --source dbo.Products --permissions "anonymous:read" --description "Product catalog"
# View
dab add ProductSummary --source dbo.vw_ProductSummary --source.type view --source.key-fields "ProductId" --permissions "anonymous:read"
# Stored Procedure
dab add GetProducts --source dbo.usp_GetProducts --source.type stored-procedure --permissions "anonymous:execute" --graphql.operation query
# Entity
dab update Products --description "Product catalog with pricing and inventory"
# Fields
dab update Products --fields.name UnitPrice --fields.description "Retail price in USD"
dab update Products --fields.name ProductID --fields.description "Unique identifier" --fields.primary-key true
# Stored Procedure Parameters
dab add GetOrdersByDate \
--source dbo.usp_GetOrdersByDate \
--source.type stored-procedure \
--permissions "authenticated:execute" \
--parameters.name "StartDate,EndDate" \
--parameters.description "Start date (inclusive),End date (inclusive)" \
--parameters.required "true,true"
# Enable/disable globally
dab configure --runtime.mcp.enabled true
dab configure --runtime.mcp.path "/mcp"
# Disable specific tools
dab configure --runtime.mcp.dml-tools.delete-record false
# Add server description
dab configure --runtime.mcp.description "Production inventory MCP endpoint"
# Entra ID
dab configure --runtime.host.authentication.provider EntraId
dab configure --runtime.host.authentication.jwt.audience "api://<app-id>"
dab configure --runtime.host.authentication.jwt.issuer "https://login.microsoftonline.com/<tenant-id>/v2.0"
# Update permissions for authenticated users
dab update Products --permissions "authenticated:*"
dab validate
dab start
dab start --verbose
dab start --LogLevel Debug
| Aspect | Regular DAB | SQL MCP Server |
|---|---|---|
| Primary Use | REST/GraphQL APIs | AI agent database access |
| Client Type | Web apps, mobile apps | AI agents, copilots |
| Protocol | HTTP REST, GraphQL | MCP over HTTP or stdio |
| Version | 1.0+ | 1.7+ (preview) |
| Endpoint | /api, /graphql |
/mcp |
| Query Method | OData filters, GraphQL queries | DML tool calls |
| Descriptions | Optional | Critical for AI understanding |
| Default State | REST + GraphQL enabled | REST + GraphQL + MCP enabled |
Good fit:
Not a good fit:
Migration candidates:
data-api-builder.md for comprehensive DAB CLI guidancedab-cli.skill.md for detailed command reference.gitignore with .env, **\bin, and **\obj entries before adding secretsdab validate && dab start@env('VAR_NAME') patternCurrent State (v1.7.x-rc):
--prerelease flag to install:latest Docker tagWhen GA releases:
:latest Docker tag will include MCPAlways check: dab --version to confirm 1.7+