mcp-sql
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-sqlshow me the tables in the sales schema"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-sql
An extensible, read-only Model Context Protocol
server for SQL databases. It lets an MCP client (Claude, etc.) explore schemas and
run SELECT queries safely.
First engine: Microsoft SQL Server (via
pyodbc/ ODBC Driver 18).Designed to extend: new engines plug in behind a
DatabaseProviderinterface; auth methods plug in behind anAuthStrategy.Transports: local stdio and remote streamable HTTP from the same server.
Read-only by design: every query is validated to be a single
SELECT/WITH/EXPLAIN.
Install
Requires Python 3.11+. The MS SQL engine needs the Microsoft ODBC Driver 18:
# macOS
brew tap microsoft/mssql-release https://github.com/microsoft/homebrew-mssql-release
brew trust microsoft/mssql-release # newer Homebrew requires trusting 3rd-party taps
HOMEBREW_ACCEPT_EULA=Y brew install unixodbc msodbcsql18
# Debian/Ubuntu: see https://learn.microsoft.com/sql/connect/odbc/linux-mac/Then install the project (with the mssql extra for the SQL Server driver):
uv sync --extra mssql --extra dev
# or: pip install -e ".[mssql,dev]"Related MCP server: sqlite-mcp-server
Configure
Copy .env.example to .env and edit. Key settings (env prefix MCPSQL_):
Setting | Purpose |
| Engine. Currently |
| Connection target. |
|
|
| Row cap for |
| ODBC driver name (default |
Authentication matrix (MS SQL)
| What it does | Extra settings |
| SQL Server login (username/password). |
|
| Integrated / trusted connection (Windows or AD-joined host). | — |
| OAuth2 access token via Azure AD / Entra ID. |
|
azure_ad token acquisition modes (MCPSQL_AZURE_AUTH_MODE):
default—DefaultAzureCredential(env vars, managed identity, Azure CLI, …).service_principal— readsAZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET.managed_identity—ManagedIdentityCredential(for Azure-hosted workloads).
Security note: the read-only validator is a guard, not a boundary. For real protection, connect with a least-privilege principal (e.g. a login mapped to
db_datareader). Then even a validator bypass cannot write.
Quickstart with the bundled demo database
A docker-compose.yml spins up SQL Server 2022 and seeds a small AppDemo
database (sales.customers / orders / order_items + a view and FKs):
docker compose up -d # start + seed (first run pulls the image)
docker compose logs seed # look for "Seed complete".env.example's defaults already point at this database, so:
cp .env.example .env
uv run mcp-sql # or inspect it (see below)When you're done: docker compose down -v.
The seed also creates a least-privilege
mcp_readerlogin (passwordReader!Pass1). PointMCPSQL_USERNAME/MCPSQL_PASSWORDat it to run mcp-sql with read-only database permissions — the recommended setup.On Apple Silicon the SQL Server image runs under amd64 emulation; first start takes a minute or two.
Run
# Local stdio (default) — how MCP clients usually launch it
uv run mcp-sql
# Remote streamable HTTP
uv run mcp-sql --transport http --host 0.0.0.0 --port 8000Endpoint authentication is not done here. This server is designed to sit behind an MCP gateway that authenticates callers. Run it only on a network reachable through that gateway (private network / mTLS); for defense in depth bind to loopback and rely on FastMCP's DNS-rebinding (allowed-hosts) protection. The gateway should also strip/overwrite client-supplied connection headers it sets.
Remote: one server, many databases
For a remote deployment the server is not pinned to a single database. The
caller (or gateway) names the database in a request header; the server
resolves that name to a connection. The wire only ever carries the name — never
credentials. Backend chosen by MCPSQL_CONNECTION_BACKEND:
Backend | Resolves a name via | Use for |
| the single connection in the settings above | stdio / local / single DB |
|
| local/dev multi-DB (no Azure) |
| Azure Key Vault secret | production |
Request header (default X-MCP-Connection) selects the connection per request:
X-MCP-Connection: analytics → secret "mcpsql-conn-analytics" in Key VaultKey Vault path (production):
Store each database's ODBC connection string as a secret named
mcpsql-conn-<name>. Prefer connection strings that useazure_ad/ managed identity so the vault holds no SQL password.The server authenticates to Key Vault with
DefaultAzureCredential(managed identity in Azure) — setMCPSQL_KEYVAULT_URL.The connection name is validated against
[A-Za-z0-9-]{1,120}and the fixed prefix, so a header can never address an arbitrary vault secret. AddMCPSQL_CONNECTION_ALLOWLISTto restrict further.Resolved connections are cached for
MCPSQL_CONNECTION_CACHE_TTLseconds (rotation is picked up on expiry).
Resolved connections are pooled (one connection per operation, via pyodbc's driver-level pool), so a single process serves many databases and many concurrent callers safely.
Use with an MCP client (stdio)
{
"mcpServers": {
"sql": {
"command": "uv",
"args": ["run", "mcp-sql"],
"cwd": "/path/to/mcp-sql"
}
}
}Inspect manually
npx @modelcontextprotocol/inspector uv run mcp-sqlRunnable examples
See examples/ for working client scripts:
examples/stdio_client.py— local stdio (spawns the server).examples/http_client.py— remote streamable HTTP, selecting the database per request with theX-MCP-Connectionheader.
Tools
Tool | Description |
| Schemas in the database. |
| Tables and views. |
| Columns, types, PK, FKs, indexes. |
| Foreign-key relationships. |
| Run a validated read-only query. |
Extending to another database
Add a provider module implementing
DatabaseProvider(src/mcp_sql/providers/base.py).Register it in
src/mcp_sql/providers/registry.py(one line).Reuse the existing
AuthStrategytypes, or add new ones undersrc/mcp_sql/auth/.Add the driver as a new optional extra in
pyproject.toml.
The MCP tool layer and the read-only validator are engine-agnostic and need no changes.
Develop
uv run pytestThe test_safety.py and test_config_auth.py suites need no database.
This server cannot be deployed
Maintenance
Related MCP Connectors
- dataOAuthco.thinair
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Draxlr's remote MCP server connects AI assistants to your SQL databases and dashboards. Explore schemas, run read-only queries, manage saved queries and dashboards, and export results, all with row-level security so each user sees only their own data.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Read-only MCP server exposing a user ORANO library to their own AI agent.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceA read-only MCP server that enables AI agents to explore database schemas and execute safe queries on PostgreSQL and MySQL.-
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that enables LLMs to safely explore and query any SQLite database via natural language. It exposes tools for listing tables, describing schemas, and executing SELECT/WITH queries with built-in safety guards like write prevention and row limits.MIT
- FlicenseAqualityCmaintenanceA read-only MCP server for browsing and querying SQL Server databases, providing tools to list schemas, tables, describe columns, and execute safe SELECT queries with validated parameters.15-
- AlicenseNot gradedqualityCmaintenanceRead-only MCP server for SQL databases (SQLite/PostgreSQL) that enables listing tables, describing schemas, and executing SELECT queries with safety guardrails.MIT