Guide
SQL Server MCP server for Claude Code and Codex
Connecting Claude Code, Codex or Cursor to SQL Server through MCP: Microsoft's SQL MCP Server in Data API builder, read-only setups, and a schema-only option.
Guide
Connecting Claude Code, Codex or Cursor to SQL Server through MCP: Microsoft's SQL MCP Server in Data API builder, read-only setups, and a schema-only option.
Interest in connecting AI coding agents to SQL Server has kept growing through 2026 while the PostgreSQL equivalent levelled off, and most of the new searches lead to the same place: Microsoft's SQL MCP Server, part of Data API builder. It is a serious piece of engineering, and it solves a different problem from the one many developers have when they first look for "SQL Server MCP".
There are two distinct jobs. One is letting an agent work with the data: read orders, update a record, run a stored procedure inside an application. The other is letting an agent understand the schema so the code and SQL it writes match the real tables. They call for different servers.
SQL MCP Server ships with Data API builder 1.7 and later, with 2.0 as the current recommended release. It is open source, self-hosted, and configured through dab-config.json, where each table, view or stored procedure to expose is declared as an entity with role-based permissions.
The design choices are explicit in Microsoft's documentation. It does not translate natural language into arbitrary SQL. Agents call a fixed set of tools, describe_entities, read_records, create_record, update_record, delete_record, execute_entity and aggregate_records, and Data API builder generates the T-SQL deterministically. It is built around DML, working with data rather than schema, so it does not create or alter tables.
Making it read-only means giving the agent's role only the read action on each entity and turning off the write tools in the runtime configuration. The protection comes from Data API builder's permission system rather than from the database login, so it is worth also connecting with a login that has only SELECT grants.
It fits well when an application or an internal copilot needs controlled access to specific business entities. It is less suited to the coding agent case, for two reasons: every object the agent should know about has to be declared in the configuration first, and what the agent sees is the curated entity layer, with aliases and filtered fields, rather than the physical schema the code is written against.
The MCP directories list many community servers for SQL Server that take a connection string and expose a query tool. Some restrict themselves to SELECT by inspecting the statement text. That is a convenience, not a security boundary: a function or procedure with side effects passes a text filter. If one of these is used against anything shared, the login should be read-only in the database itself, and the server should point at a replica rather than the primary.
For an agent that writes migrations, Entity Framework models, Dapper queries or reports, the question it keeps getting wrong is not "what is in this row" but "what is this column called, what type is it, and how does this table join to that one". A schema-only MCP server answers exactly that, without any path to the data.
The Taavik MCP server works this way. It does not connect to SQL Server and has no tool that runs SQL. Its tools read the catalog that the on-premises agent collected during its scans: list_connections, list_tables and describe_table, which returns columns with types and nullability, primary and foreign keys, indexes, the tables that reference the one described and relationships declared by hand where no foreign key exists. It covers SQL Server and Azure SQL Database alongside PostgreSQL, MySQL and Redshift, so a polyglot estate is one connector. Sign-in is an OAuth browser flow with the workspace account, so the config file holds no connection string and no key, and every tool call is recorded.
On the Pro plan, describe_table can also return the known values of short status-like columns, so the agent writes WHERE status = 'Shipped' with the right spelling. Rows are never returned.
Claude Code:
claude mcp add --transport http taavik https://api.taavik.com/mcp
Codex CLI, which registers itself with the server and opens the browser to sign in:
codex mcp add taavik --url https://api.taavik.com/mcp
codex mcp login taavik
or in ~/.codex/config.toml:
[mcp_servers.taavik]
url = "https://api.taavik.com/mcp"
Cursor and other clients take the same URL in their MCP settings.
The two approaches combine cleanly. A schema-only server gives the coding agent an accurate picture of every database, and a Data API builder instance with read-only roles on a handful of entities answers the data questions that genuinely need rows. Keeping them separate keeps the blast radius of each one obvious. The read-only MCP guide covers the general checklist, and the free plan includes the schema tools for one connection.