Every few months, someone publishes a demo of an AI agent querying a database using natural language. The agent translates "show me last month's revenue by region" into a SQL query, executes it, and returns a nicely formatted table. It looks impressive in a three-minute video. It also falls apart the moment you point it at a production database with 200 tables, column names that made sense to someone in 2014, and data that absolutely cannot be exposed to the wrong role.
The fundamental problem with NL2SQL -- having a language model generate raw SQL from natural language -- is that language models are not deterministic. The same prompt can produce different queries on different runs. Complex joins, subqueries, and aggregations are exactly the cases where subtle errors creep in, and they are exactly the cases where those errors matter most. You end up building a validation layer around the generated SQL, which raises the question of why you are generating it in the first place.
Microsoft's SQL MCP Server, announced on 8 April 2026 as part of Data API builder 2.0, takes a deliberately different approach. Instead of letting agents write SQL, it exposes a fixed set of seven DML tools through the Model Context Protocol. Agents interact with a controlled entity abstraction layer, and the underlying query builder produces deterministic T-SQL every time. Same input, same output, no surprises.
What SQL MCP Server actually is
SQL MCP Server is not a standalone product. It is a feature of Data API builder (DAB), Microsoft's open-source, zero-code engine for exposing database operations through REST, GraphQL, and now MCP endpoints. Starting with DAB version 1.7, MCP support is included by default -- if you already have a working DAB configuration, upgrading gives you a functional MCP server with no additional setup.
The server runs as a containerised MCR image or locally through the DAB CLI. It supports four database backends:
- Microsoft SQL Server
- PostgreSQL
- Azure Cosmos DB
- MySQL
All four are accessible through the same configuration model and the same set of MCP tools. You can even run hybrid queries that span on-premises SQL Server and cloud-hosted Cosmos DB through DAB's multi-data-source support.
The seven DML tools
Rather than exposing a "run any query" tool, SQL MCP Server provides exactly seven operations:
| Tool | Purpose |
|---|---|
describe_entities |
Discovers available entities and their allowed operations |
create_record |
Inserts a new row |
read_records |
Queries tables or views |
update_record |
Modifies an existing row |
delete_record |
Removes a row |
execute_entity |
Runs a stored procedure |
aggregate_records |
Performs aggregation queries |
This constraint is intentional. Every tool you expose to an agent consumes tokens during tool discovery and selection. A sprawling tool surface forces the model to spend its context window figuring out which tool to call rather than reasoning about the task. Seven well-defined operations cover the vast majority of data access patterns without overwhelming the agent's decision-making.
Each tool respects the role-based access control rules defined in your configuration. An agent running under a reader role will never see the create_record or delete_record tools if those operations are not permitted for that role.
NL2DAB: deterministic by design
The core architectural decision behind SQL MCP Server is what Microsoft calls NL2DAB -- Natural Language to Data API builder. Rather than having the language model generate SQL directly, the agent expresses intent through the structured MCP tools. The DAB query builder then translates that intent into well-formed T-SQL.
This is not a semantic distinction. Consider what happens when an agent needs to read customer records with a filter:
- The agent calls
read_recordswith entity nameCustomersand a filter expression - DAB validates the request against the entity configuration and RBAC rules
- The query builder generates the exact same T-SQL every time for the same input
- Results flow back through the entity abstraction layer, which may alias columns or exclude fields based on role
At no point does the language model see the actual table schema, column names, or database structure. It works with the entity names, field aliases, and descriptions you define in your configuration. This is not just a security benefit -- it also produces better results, because the model reasons about semantically meaningful names like CustomerName rather than cryptic column names like cust_nm_01.
// IMPORTANT
SQL MCP Server intentionally does not support DDL operations. Agents cannot create tables, alter schemas, or modify indexes. This is a deliberate design choice for production environments where AI agents interact with mission-critical systems.
Configuration: three commands to a working server
Getting started requires a DAB configuration file. The CLI makes this straightforward:
dab init \
--database-type mssql \
--connection-string "@env('SQL_CONNECTION_STRING')" \
--config dab-config.json \
--host-mode development
dab add Customers \
--source dbo.Customers \
--source.type table \
--permissions "reader:read" \
--description "Customer records including contact details and account status"
dab add Orders \
--source dbo.Orders \
--source.type table \
--permissions "reader:read,writer:*" \
--description "Sales orders with line items and fulfilment status"
dab start
That is it. Three commands -- init, add, start -- and you have a working MCP server exposing two entities with role-based permissions.
The connection string uses the @env() syntax to pull from environment variables. You can also reference Azure Key Vault secrets using @akv(), which keeps credentials out of configuration files entirely.
Runtime MCP configuration
The MCP runtime settings live in the dab-config.json file. In most cases, the defaults are sufficient:
{
"runtime": {
"mcp": {
"enabled": true,
"path": "/mcp",
"dml-tools": {
"describe-entities": true,
"create-record": true,
"read-records": true,
"update-record": true,
"delete-record": true,
"execute-entity": true,
"aggregate-records": true
}
}
}
}
You can disable individual tools at the runtime level. This is useful when you want to enforce operational boundaries that go beyond what RBAC alone provides. For instance, turning off delete-record globally ensures no agent can ever delete data, regardless of their role permissions:
{
"runtime": {
"mcp": {
"enabled": true,
"dml-tools": {
"delete-record": false
}
}
}
}
Entity-level control
Individual entities can opt out of MCP entirely or restrict which tools are available:
{
"entities": {
"Products": {
"source": {
"type": "table",
"object": "dbo.Products"
},
"mcp": {
"dml-tools": true
}
},
"AuditLog": {
"source": {
"type": "table",
"object": "dbo.AuditLog"
},
"mcp": {
"dml-tools": false
}
}
}
}
The AuditLog entity remains accessible through REST and GraphQL but is invisible to MCP agents. This lets you maintain a single configuration file while giving agents a more focused view of your data.
Stored procedures as custom tools
The built-in DML tools cover standard CRUD operations, but many enterprises encapsulate business logic in stored procedures. SQL MCP Server lets you expose these as named MCP tools:
{
"entities": {
"GetMonthlyRevenue": {
"source": {
"type": "stored-procedure",
"object": "dbo.sp_GetMonthlyRevenue"
},
"permissions": {
"analyst": {
"actions": ["execute"]
}
},
"mcp": {
"custom-tool": true
}
}
}
}
When custom-tool is set to true, the stored procedure is registered as a named tool through tools/list and tools/call. The agent discovers it by name rather than having to use the generic execute_entity tool. This creates a bespoke tool surface tailored to your specific business processes.
// TIP
You can disable all built-in DML tools and expose only stored procedures. This gives you complete control over what agents can do -- each tool maps to a specific, tested business operation rather than generic CRUD.
The entity abstraction layer
The entity abstraction layer is what makes SQL MCP Server practical for production use. It sits between the agent and the database, providing several capabilities:
Schema hiding -- Agents never see real table or column names. You define aliases that make semantic sense without revealing internal naming conventions.
Field-level RBAC -- Each role can see a different set of fields. A public role might see CustomerName and City while an admin role also sees Email and PhoneNumber. This is enforced automatically across all MCP tools.
Semantic descriptions -- Entity, field, and parameter descriptions help the language model make better decisions about which entities to query and which fields to include. A field described as "unique identifier for each product in the catalogue" produces better agent behaviour than a field named ProductID with no context.
Cross-data-source relationships -- You can define relationships between entities in different databases, enabling agents to traverse data across SQL Server and Cosmos DB through a unified interface.
Caching and performance
SQL MCP Server automatically caches results from read_records using a two-level strategy:
- Level 1: In-memory application-level cache
- Level 2: External cache using Redis or Azure Managed Redis
Caching is configured per entity, which means frequently queried reference data can be cached aggressively while transactional tables remain uncached. This reduces database load, prevents request stampedes from multiple agents hitting the same query, and supports warm-start scenarios in horizontally scaled deployments.
The aggregate_records tool also supports a configurable query-timeout property (1-600 seconds, defaulting to 30) for long-running analytical queries.
Observability
Every MCP tool invocation is fully instrumented with OpenTelemetry spans. This gives you unified tracing across REST, GraphQL, and MCP endpoints from a single deployment. The telemetry integrates with Azure Log Analytics, Application Insights, and any OpenTelemetry-compatible collector.
Health checks provide per-endpoint verification across all three protocols. You can define performance expectations, set thresholds, and verify that your MCP endpoint is responding within acceptable latency bounds.
Running locally
For local development, the DAB CLI supports a stdio transport that works with MCP Inspector and local agent frameworks:
dab start --mcp-stdio
You can also specify a role to test different permission levels:
dab start --mcp-stdio role:analyst
For HTTP-based testing, launch MCP Inspector in proxy mode:
dab start
# In another terminal:
npx -y @modelcontextprotocol/inspector http://localhost:5000/mcp
This lets you test tool discovery, execute operations, and verify role-based filtering before deploying to a shared environment.
Common pitfalls
Relying on auto-configuration in production -- DAB 2.0 includes an auto-configuration mode that inspects the database schema at startup and builds the configuration dynamically. This is useful for prototyping, but it exposes your entire schema to agents. In production, always use explicit configuration files with carefully chosen entity definitions and permissions.
Forgetting to add descriptions -- Without semantic descriptions, agents have to infer entity and field purposes from names alone. A table aliased as Items with fields F1, F2, F3 will produce poor agent behaviour. Invest the time in writing clear descriptions -- they directly affect the quality of agent interactions.
Exposing write operations without thinking about consequences -- Just because an agent can call update_record does not mean it should. Consider whether your use case genuinely requires write access, and if it does, prefer stored procedures with custom-tool over generic DML tools. A stored procedure can enforce business rules, validate inputs, and log changes in ways that a raw update cannot.
Ignoring the multimodal nature of DAB -- SQL MCP Server shares its configuration with REST and GraphQL endpoints. Changes you make to support MCP agents affect all three protocols. If you add a new entity for an agent, it is also available through REST unless you explicitly restrict it.
Using NL2SQL alongside SQL MCP Server -- If you are also running a separate NL2SQL solution, you now have two paths to the same data with different security models. Pick one approach and commit to it.
Summary
- SQL MCP Server is a feature of Data API builder 2.0, not a standalone product. Upgrading to DAB 1.7+ gives you MCP support automatically.
- It exposes seven deterministic DML tools through the Model Context Protocol, avoiding the reliability and security issues of NL2SQL.
- The entity abstraction layer hides real schema details, enforces field-level RBAC, and supports semantic descriptions that improve agent behaviour.
- Stored procedures can be exposed as named custom tools, enabling bespoke agent interfaces tailored to specific business processes.
- It supports SQL Server, PostgreSQL, Cosmos DB, and MySQL through a single configuration model.
- Two-level caching, OpenTelemetry tracing, and health checks make it production-ready out of the box.
- Configuration requires three CLI commands to get started, and the defaults handle most scenarios without additional tuning.