SQL Server MCP

Un servidor de Model Context Protocol (MCP) de solo lectura para Microsoft SQL Server, que permite el descubrimiento seguro de metadatos y consultas SELECT parametrizadas.

Documentación

Herramienta MCP SQL Server

Build Status NuGet Version License: MIT

Un servidor Model Context Protocol (MCP) de solo lectura por defecto para Microsoft SQL Server que admite descubrimiento de metadatos, consultas parametrizadas y análisis de consultas, con configuración basada en perfiles. Las herramientas de consulta aplican solo SELECT (sin DML/DDL); una herramienta opcional run_command puede ejecutar T-SQL de escritura arbitrario, pero solo en perfiles que se suscriban explícitamente mediante AllowWrite (bloqueada por defecto).

Requisitos: runtime .NET 8.0 o posterior (la herramienta apunta a net8.0 y net10.0), SQL Server y una cadena de conexión. Para compilar desde el código fuente se requiere el SDK .NET 10.0.

Inicio rápido

Establezca MCPMSSQL_CONNECTION_STRING y ejecute el servidor de una de estas maneras:

# 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 compilaciones preliminares.

Configuración

Todos los ajustes usan el prefijo MCPMSSQL. Las variables de entorno planas (p. ej., MCPMSSQL_CONNECTION_STRING) son la forma directa de configurar el perfil predeterminado cuando tiene una sola conexión. Para múltiples perfiles, se recomienda el archivo appsettings.json con ámbito de usuario.

Conexión única: Configure mediante variables de entorno.

# 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"

Conexiones múltiples: Use el archivo appsettings.json con ámbito de usuario (recomendado). Las variables de entorno también funcionan mediante las convenciones de host de .NET (MCPMSSQL__PROFILES__<NAME>__CONNECTIONSTRING, etc.).

  • Unix-like: ~/.config/mcp-mssql/appsettings.json
  • Windows: %USERPROFILE%\.config\mcp-mssql\appsettings.json

Ejemplo (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
        }
      }
    }
  }
}

Desarrollo local: Almacene la cadena de conexión en secretos de usuario y luego ejecute con DOTNET_ENVIRONMENT=Development para que los secretos se carguen.

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 admite autenticación de Microsoft Entra (Azure AD). Establezca la propiedad Authentication en la cadena de conexión a un modo admitido (p. ej., Active Directory Default, Active Directory Managed Identity o Active Directory Interactive) al conectarse a Azure SQL. Consulte Connect to Azure SQL with Microsoft Entra authentication and SqlClient para todos los modos y detalles.

Herramientas y recursos

Todas las herramientas aceptan un profile opcional; cuando se omite, se usa el perfil predeterminado.

Herramientas

HerramientaDescripciónParámetros clave
list_profilesLista los perfiles de conexión configurados. Llame primero al elegir un perfil no predeterminado.
get_server_propertiesObtiene propiedades del servidor y límites de ejecución (tiempos de espera, límites de filas, salvaguardas).profile
list_objectsLista metadatos del catálogo. kind=catalog: bases de datos; schema: esquemas; relation: tablas/vistas; routine: procedimientos/funciones. catalog omitido → catálogo activo (ignorado para kind=catalog). La omisión de schema depende del tipo.kind, profile, catalog, schema
get_objectObtiene metadatos de una relación o rutina. Use list_objects para resolver nombres. Devuelve cargas de detalle vacías si includes es nulo.kind, name, profile, catalog, schema, includes
run_queryEjecuta T-SQL SELECT de solo lectura; solo se permite SELECT (sin DML/DDL). Devuelve resultados como CSV en el campo data (en línea) o un URI de recurso de instantánea cuando snapshot=true. Límite en línea: 500 filas (máximo absoluto 1000). Límite de instantánea: 10 000 filas. Prefiera analyze_query para ajuste de planes.sql, profile, catalog, parameters, snapshot
analyze_queryAnaliza el plan de ejecución de un SELECT de solo lectura. Devuelve un resumen JSON compacto (costo, operadores, cardinalidad, advertencias, índices, esperas, estadísticas). Obtenga el XML completo desde plan_uri; no devuelve filas de resultados.sql, profile, catalog, parameters, estimated
run_commandEjecuta T-SQL de escritura (DDL/DML). Se rechaza a menos que el profile de destino establezca AllowWrite=true (desactivado por defecto). El llamador gestiona las transacciones. Devuelve rows_affected (−1 para DDL) y messages del servidor. Marcada como destructiva; destinada a uso supervisado por humanos.sql, profile, catalog, parameters
  • kindcatalog, schema, relation o routine. Para get_object, solo relation o routine.
  • includes — Matriz de secciones de detalle: columns, indexes, constraints (solo relaciones), definition (solo rutinas).

Recursos

Plantilla de URIDescripción
mssql://profilesLista los perfiles de conexión configurados. Mismos datos que list_profiles.
mssql://server-properties?{profile}Obtiene propiedades del servidor y límites de ejecución. Mismos datos que get_server_properties.
mssql://objects?{kind,profile,catalog,schema}Lista metadatos del catálogo. El comportamiento de omisión de esquema coincide con list_objects.
mssql://objects/{kind}/{name}{?profile,catalog,schema,includes}Obtiene metadatos de una relación o rutina. includes es obligatorio.
mssql://plans/{id}Recupera el plan de ejecución XML completo por ID desde analyze_query; las entradas caducan después de 7 días.
mssql://snapshots/{id}Recupera el resultado completo de la consulta como CSV por ID desde run_query (snapshot=true); las entradas caducan después de 1 día.

Los recursos reflejan sus herramientas correspondientes y devuelven JSON (excepto mssql://plans/{id} que devuelve XML y mssql://snapshots/{id} que devuelve CSV).

Seguridad

Las herramientas de consulta (run_query, analyze_query) son de solo lectura (solo SELECT) y usan enlace @paramName parametrizado. Use variables de entorno o secretos de usuario para las cadenas de conexión; nunca confirme secretos.

Las escrituras son opcionales. La herramienta run_command ejecuta T-SQL arbitrario. Se rechaza a menos que el perfil de destino establezca AllowWrite=true, que por defecto es false, por lo que las implementaciones existentes permanecen de solo lectura sin cambios. La herramienta siempre se anuncia y se rechaza en el momento de la llamada en perfiles bloqueados.

AllowWrite es una salvaguarda suave a nivel de aplicación, no un límite de seguridad: restringe este servidor, no la base de datos. Para una garantía genuina de solo lectura, conéctese con un inicio de sesión restringido a db_datareader y mantenga los perfiles habilitados para escritura apuntando a credenciales limitadas solo a lo que necesitan. run_command está marcado como destructive mediante anotaciones de herramientas MCP para que los hosts puedan protegerlo detrás de confirmación, pero el honor de esas anotaciones queda a discreción del host.

Ejemplos de hosts MCP

Fragmentos para clientes MCP comunes. Reemplace la cadena de conexión con la suya; asegúrese de que dotnet esté en su PATH. El bloque env no es necesario si la cadena de conexión ya está establecida mediante appsettings.json o variables de entorno.

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;"
      }
    }
  }
}

Pruebas de integración

Las pruebas usan un SQL Server real y el perfil default (MCPMSSQL_CONNECTION_STRING de variables de entorno o secretos de usuario). El conjunto espera una base de datos llamada McpMssqlTest: la cadena de conexión debe incluir Initial Catalog=McpMssqlTest. La infraestructura de pruebas crea, siembra y elimina esta base de datos. Establezca el secreto para el proyecto de pruebas:

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

Un framework a la vez. La única base de datos McpMssqlTest es compartida por cada prueba, y los fixtures la eliminan y recrean en la inicialización. Dentro de un proceso de prueba esto es seguro: la colección SqlServer desactiva la paralelización. Entre procesos no lo es: el proyecto de pruebas apunta tanto a net8.0 como a net10.0, y dotnet test ejecuta los dos módulos de framework en paralelo, por lo que compiten por esa única base de datos. No hay bloqueo entre procesos, así que ejecute un solo framework a la vez:

dotnet test --framework net8.0
dotnet test --framework net10.0

CI hace lo mismo, iterando sobre TARGET_FRAMEWORKS secuencialmente.

¿Por qué esto en lugar de Data API Builder?

Data API Builder (DAB) es una API REST/GraphQL completa con CRUD y autenticación. Este proyecto es un servidor MCP pequeño y de solo lectura para agentes: stdio, SELECT parametrizado únicamente, superficie mínima. Elija esto para flujos de trabajo de agentes y baja sobrecarga operativa; elija DAB para CRUD, REST/GraphQL y políticas enriquecidas.

Contribuciones

Abra problemas o PRs; siga el estilo existente y agregue pruebas donde corresponda.

Licencia

MIT. Consulte LICENSE.