SQL Server MCP
Um servidor de protocolo de contexto de modelo (MCP) somente leitura para Microsoft SQL Server, permitindo descoberta segura de metadados e consultas SELECT parametrizadas.
Documentação
Ferramenta MCP SQL Server
Um servidor Model Context Protocol (MCP) somente leitura por padrão para Microsoft SQL Server que oferece suporte a descoberta de metadados, consultas parametrizadas e análise de consultas, com configuração baseada em perfis. As ferramentas de consulta impõem somente SELECT (sem DML/DDL); uma ferramenta opcional run_command pode executar T-SQL de escrita arbitrário, mas apenas em perfis que aceitam explicitamente via AllowWrite (bloqueado por padrão).
Requisitos: runtime .NET 8.0 ou posterior (a ferramenta tem como alvo net8.0 e net10.0), SQL Server e uma string de conexão. A compilação a partir do código-fonte requer o SDK .NET 10.0.
Início rápido
Defina MCPMSSQL_CONNECTION_STRING e execute o servidor de uma das seguintes formas:
# Option 1: Run from NuGet package (e.g. with MCP Inspector)
export MCPMSSQL_CONNECTION_STRING="Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
npx -y @modelcontextprotocol/inspector dotnet dnx Alyio.McpMssql --prerelease
# Option 2: Install and run as a global tool
dotnet tool install --global Alyio.McpMssql --prerelease
export MCPMSSQL_CONNECTION_STRING="Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
npx -y @modelcontextprotocol/inspector mcp-mssql
# Option 3: Run from source (clone repo, then)
export MCPMSSQL_CONNECTION_STRING="Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
npx -y @modelcontextprotocol/inspector dotnet run --project src/Alyio.McpMssql
Use --prerelease para builds de pré-lançamento.
Configuração
Todas as configurações usam o prefixo MCPMSSQL. Variáveis de ambiente planas (por exemplo, MCPMSSQL_CONNECTION_STRING) são a forma direta de configurar o perfil padrão quando você tem uma única conexão. Para vários perfis, o arquivo appsettings.json no escopo do usuário é recomendado.
Conexão única: Configure por meio de variáveis de ambiente.
# Connection string (required).
export MCPMSSQL_CONNECTION_STRING="Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
# Optional description for the default profile (tooling/AI discovery).
export MCPMSSQL_DESCRIPTION="Primary connection"
# Optional max rows per interactive query (default `500`; hard ceiling `1000`).
export MCPMSSQL_QUERY_MAX_ROWS="500"
# Optional query timeout in seconds (default `30`).
export MCPMSSQL_QUERY_COMMAND_TIMEOUT_SECONDS="60"
# Optional max rows for snapshot queries (default `10000`; hard ceiling `50000`).
export MCPMSSQL_QUERY_SNAPSHOT_MAX_ROWS="10000"
# Optional snapshot query timeout in seconds (default `120`).
export MCPMSSQL_QUERY_SNAPSHOT_COMMAND_TIMEOUT_SECONDS="120"
# Optional analyze timeout in seconds (default `300`).
export MCPMSSQL_ANALYZE_COMMAND_TIMEOUT_SECONDS="300"
# Optional: enable write commands (DDL/DML) via run_command (default `false`).
# Soft guard only — prefer a db_datareader login for a hard read-only guarantee.
export MCPMSSQL_ALLOW_WRITE="false"
# Optional write command timeout in seconds (default `60`; hard ceiling `600`).
export MCPMSSQL_WRITE_COMMAND_TIMEOUT_SECONDS="60"
Várias conexões: Use o arquivo appsettings.json no escopo do usuário (recomendado). Variáveis de ambiente também funcionam por meio das convenções do host .NET (MCPMSSQL__PROFILES__<NAME>__CONNECTIONSTRING, etc.).
- Semelhante a Unix:
~/.config/mcp-mssql/appsettings.json - Windows:
%USERPROFILE%\.config\mcp-mssql\appsettings.json
Exemplo (appsettings.json):
{
"McpMssql": {
"Profiles": {
"default": {
"ConnectionString": "Server=...;User ID=...;Password=...;",
"Description": "Primary connection",
"Query": {
"MaxRows": 500,
"CommandTimeoutSeconds": 60,
"SnapshotMaxRows": 10000,
"SnapshotCommandTimeoutSeconds": 120
},
"Analyze": {
"CommandTimeoutSeconds": 300
}
},
"warehouse": {
"ConnectionString": "Server=warehouse.example.com;...",
"Description": "Warehouse read-only"
},
"migrations": {
"ConnectionString": "Server=...;User ID=...;Password=...;",
"Description": "Write-enabled profile for schema changes",
"AllowWrite": true,
"Write": {
"CommandTimeoutSeconds": 60
}
}
}
}
}
Desenvolvimento local: Armazene a string de conexão em user-secrets e execute com DOTNET_ENVIRONMENT=Development para que os segredos sejam carregados.
dotnet user-secrets set "MCPMSSQL_CONNECTION_STRING" "..." --project src/Alyio.McpMssql
npx -y @modelcontextprotocol/inspector -e DOTNET_ENVIRONMENT=Development dotnet run --project src/Alyio.McpMssql
Azure SQL / Microsoft Entra ID: Este servidor MCP usa Microsoft.Data.SqlClient, que oferece suporte à autenticação Microsoft Entra (Azure AD). Defina a propriedade Authentication na string de conexão para um modo compatível (por exemplo, Active Directory Default, Active Directory Managed Identity ou Active Directory Interactive) ao conectar ao Azure SQL. Consulte Connect to Azure SQL with Microsoft Entra authentication and SqlClient para todos os modos e detalhes.
Ferramentas e recursos
Todas as ferramentas aceitam um profile opcional; quando omitido, o perfil padrão é usado.
Ferramentas
| Ferramenta | Descrição | Parâmetros principais |
|---|---|---|
list_profiles | Lista os perfis de conexão configurados. Chame primeiro ao escolher um perfil não padrão. | — |
get_server_properties | Obtém propriedades do servidor e limites de execução (timeouts, limites de linhas, proteções). | profile |
list_objects | Lista metadados do catálogo. kind=catalog: bancos de dados; schema: esquemas; relation: tabelas/views; routine: procedures/funções. catalog omitido → catálogo ativo (ignorado para kind=catalog). A omissão de schema depende do tipo. | kind, profile, catalog, schema |
get_object | Obtém metadados de uma relação ou rotina. Use list_objects para resolver nomes. Retorna payloads de detalhes vazios se includes for nulo. | kind, name, profile, catalog, schema, includes |
run_query | Executa T-SQL SELECT somente leitura; apenas SELECT é permitido (sem DML/DDL). Retorna resultados como CSV no campo data (inline) ou um URI de recurso de snapshot quando snapshot=true. Limite inline: 500 linhas (teto máximo de 1000). Limite de snapshot: 10.000 linhas. Prefira analyze_query para ajuste de plano. | sql, profile, catalog, parameters, snapshot |
analyze_query | Analisa o plano de execução de um SELECT somente leitura. Retorna um resumo JSON compacto (custo, operadores, cardinalidade, avisos, índices, esperas, estatísticas). Obtenha o XML completo de plan_uri; não retorna linhas de resultado. | sql, profile, catalog, parameters, estimated |
run_command | Executa T-SQL de escrita (DDL/DML). Rejeitado a menos que o profile de destino defina AllowWrite=true (desativado por padrão). O chamador gerencia transações. Retorna rows_affected (−1 para DDL) e messages do servidor. Marcado como destrutivo; destinado ao uso supervisionado por humanos. | sql, profile, catalog, parameters |
kind—catalog,schema,relationouroutine. Paraget_object, apenasrelationouroutine.includes— Matriz de seções de detalhes:columns,indexes,constraints(somente relações),definition(somente rotinas).
Recursos
| Modelo de URI | Descrição |
|---|---|
mssql://profiles | Lista os perfis de conexão configurados. Mesmos dados de list_profiles. |
mssql://server-properties?{profile} | Obtém propriedades do servidor e limites de execução. Mesmos dados de get_server_properties. |
mssql://objects?{kind,profile,catalog,schema} | Lista metadados do catálogo. O comportamento de omissão de esquema corresponde a list_objects. |
mssql://objects/{kind}/{name}{?profile,catalog,schema,includes} | Obtém metadados de uma relação ou rotina. includes é obrigatório. |
mssql://plans/{id} | Recupera o plano de execução XML completo por ID de analyze_query; as entradas expiram após 7 dias. |
mssql://snapshots/{id} | Recupera o resultado completo da consulta como CSV por ID de run_query (snapshot=true); as entradas expiram após 1 dia. |
Os recursos espelham suas ferramentas correspondentes e retornam JSON (exceto mssql://plans/{id}, que retorna XML, e mssql://snapshots/{id}, que retorna CSV).
Segurança
As ferramentas de consulta (run_query, analyze_query) são somente leitura (apenas SELECT) e usam vinculação parametrizada de @paramName. Use variáveis de ambiente ou user-secrets para strings de conexão — nunca confirme segredos.
Escritas são opcionais. A ferramenta run_command executa T-SQL arbitrário. Ela é rejeitada a menos que o perfil de destino defina AllowWrite=true, que tem como padrão false, portanto, as implantações existentes permanecem somente leitura sem alteração. A ferramenta é sempre anunciada e rejeita no momento da chamada em perfis bloqueados.
AllowWrite é uma proteção suave, em nível de aplicativo, não um limite de segurança — ela restringe este servidor, não o banco de dados. Para uma garantia genuína de somente leitura, conecte-se com um login restrito a db_datareader e mantenha os perfis habilitados para escrita apontados para credenciais com escopo apenas para o que precisam. run_command é marcado como destructive por meio de anotações de ferramenta MCP para que os hosts possam bloqueá-lo atrás de confirmação, mas honre essas anotações a critério do host.
Exemplos de hosts MCP
Trechos para clientes MCP comuns. Substitua a string de conexão pela sua; garanta que dotnet esteja no seu PATH. O bloco env não é necessário se a string de conexão já estiver definida via appsettings.json ou variáveis de ambiente.
Cursor
{
"mcpServers": {
"mssql": {
"command": "dotnet",
"args": ["dnx", "Alyio.McpMssql", "--prerelease", "--yes"],
"env": {
"MCPMSSQL_CONNECTION_STRING": "Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
}
}
}
}
Gemini
{
"mcpServers": {
"mssql": {
"command": "dotnet",
"args": ["dnx", "Alyio.McpMssql", "--prerelease", "--yes"],
"env": {
"MCPMSSQL_CONNECTION_STRING": "Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
}
}
}
}
Codex
[mcp_servers.mssql]
command = "dotnet"
args = ["dnx", "Alyio.McpMssql", "--prerelease", "--yes"]
[mcp_servers.mssql.env]
MCPMSSQL_CONNECTION_STRING = "Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
Open Code
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"mssql": {
"type": "local",
"enabled": true,
"command": ["dotnet", "dnx", "Alyio.McpMssql", "--prerelease", "--yes"],
"environment": {
"MCPMSSQL_CONNECTION_STRING": "Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
}
}
}
}
Claude Code
{
"mcpServers": {
"mssql": {
"command": "dotnet",
"args": ["dnx", "Alyio.McpMssql", "--prerelease", "--yes"],
"env": {
"MCPMSSQL_CONNECTION_STRING": "Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
}
}
}
}
GitHub Copilot
{
"inputs": [],
"servers": {
"mssql": {
"type": "stdio",
"command": "dotnet",
"args": ["dnx", "Alyio.McpMssql", "--prerelease", "--yes"],
"env": {
"MCPMSSQL_CONNECTION_STRING": "Server=127.0.0.1;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=True;TrustServerCertificate=True;"
}
}
}
}
Testes de integração
Os testes usam um SQL Server real e o perfil default (MCPMSSQL_CONNECTION_STRING de variáveis de ambiente ou user-secrets). A suíte espera um banco de dados chamado McpMssqlTest: a string de conexão deve incluir Initial Catalog=McpMssqlTest. A infraestrutura de teste cria, popula e descarta esse banco de dados. Defina o segredo para o projeto de teste:
dotnet user-secrets set "MCPMSSQL_CONNECTION_STRING" \
"Server=localhost,1433;User ID=sa;Password=...;TrustServerCertificate=True;Encrypt=True;Initial Catalog=McpMssqlTest;" \
--project test/Alyio.McpMssql.Tests
Um framework por vez. O único banco de dados McpMssqlTest é compartilhado por todos os testes, e os fixtures o descartam e recriam na inicialização. Dentro de um processo de teste, isso é seguro — a coleção SqlServer desativa a paralelização. Entre processos, não é: o projeto de teste tem como alvo tanto net8.0 quanto net10.0, e dotnet test executa os dois módulos de framework em paralelo, então eles competem por esse único banco de dados. Não há bloqueio entre processos, portanto, execute um único framework por vez:
dotnet test --framework net8.0
dotnet test --framework net10.0
O CI faz o mesmo, iterando sobre TARGET_FRAMEWORKS sequencialmente.
Por que isto em vez do Data API Builder?
O Data API Builder (DAB) é uma API REST/GraphQL completa com CRUD e autenticação. Este projeto é um servidor MCP pequeno e somente leitura para agentes: stdio, SELECT parametrizado apenas, superfície mínima. Escolha este para fluxos de trabalho de agentes e baixa sobrecarga operacional; escolha DAB para CRUD, REST/GraphQL e políticas avançadas.
Contribuindo
Abra issues ou PRs; siga o estilo existente e adicione testes quando apropriado.
Licença
MIT. Consulte LICENSE.