mcp-sqlserv
mcp-sqlserv
Servidor MCP para el acceso de solo lectura a bases de datos SQL Server — sin inyección de SQL por construcción, gestionado desde la Web Admin UI.
Zero raw SQL · Default deny · Bind parameter 100% · Auditoría completa
Acerca de
mcp-sqlserv permite que los agentes de IA (Claude, Cursor, Claude Code, cualquier cliente MCP) lean de forma segura y controlada bases de datos SQL Server:
Todas las consultas se construyen de manera estructurada por el servidor: la IA nunca escribe SQL en bruto.
Los identificadores (tablas/columnas) se validan contra los metadatos reales de la base de datos (
sys.tables,sys.columns).Los valores son siempre bind parameters → la inyección de SQL es imposible por construcción.
Los permisos por tabla son de denegación por defecto: sin un permiso explícito, la tabla no se puede tocar.
Cada solicitud queda registrada en el registro de auditoría, con clave, herramienta, filtro, número de filas y duración.
Related MCP server: SQL Server MCP
Características
Característica | Descripción |
MCP Streamable HTTP | Endpoint |
Multi-proyecto | URL por proyecto |
API Key | Crea / revoca claves por consumidor de IA |
OAuth 2.1 | Authorization Code + PKCE, DCR (RFC 7591), rotación de refresh, revocación |
Conexión SQL Server | Host/puerto/usuario/contraseña (cifrado con AES-256-GCM), TLS opcional |
Permisos granulares | Por tabla: lectura de datos y/o consulta de metadatos. Predeterminado = DENY |
Registro de auditoría | Todos los requests de la IA quedan: clave, herramienta, tabla, filtro, filas, duración, estado |
Rate limit | Límite de peticiones de 60/min por API key (configurable) |
Solo lectura total | La herramienta solo produce |
Prueba del agente | Chat directo con el modelo Gemini desde el Web UI para pruebas de punta a punta |
Arquitectura
┌──────────────┐ HTTPS ┌─────────────┐ ┌──────────────────────────────┐
│ AI Agent ├───────────►│ nginx ├─────────►│ mcp-sqlserv (Docker) │
│ (MCP client)│ Bearer │ reverse │ app-net │ Express + MCP + OAuth │
└──────────────┘ token │ proxy+SSL │ work │ │ │ │
└─────────────┘ │ ▼ ▼ │
┌──────────────┐ HTTPS │ SQLite mssql pool │
│ Web Admin UI ├─────────────────────────────────────►│ (data/, keys, │ │
│ (browser) │ REST /api/* │ audit, izin) ▼ │
└──────────────┘ │ ┌──────────┐ │
│ │ SQL Srvr │ │
└──────────────┴──────────┴────┘Inicio rápido
# 1. Clone & siapkan environment
git clone https://github.com/<username>/mcp-sqlserv.git
cd mcp-sqlserv
cp .env.example .env # isi ADMIN_USER / ADMIN_PASSWORD (min 8 karakter)
# 2. Build & jalankan
docker compose up -d --build
# 3. Verifikasi
curl http://localhost:4000/healthzEl servidor se ejecuta en http://localhost:4000: la interfaz de administración está en / y el endpoint MCP en /mcp.
Variables de entorno
Variable | Default | Descripción |
|
| Puerto del servidor |
|
| Carpeta SQLite (montada en volumen en compose) |
|
| Usuario del web UI de administración |
| obligatorio | Contraseña del web UI de administración (mín. 8 caracteres) |
| auto | Secreto JWT/cifrado (si está vacío, auto-generar y persistir) |
|
| Timeout de la consulta SQL |
|
| Límite de peticiones por API Key |
|
| Desactivar OAuth con |
|
| Tiempo de vida del authorization code (segundos) |
|
| Tiempo de vida del access token (segundos) |
|
| Tiempo de vida del refresh token (segundos, 30 días) |
Nota: La fila de OAUTH_REFRESH_TTL_S modificamos el valor. Debería ser 2592000 sin (segundos). Reviso.
Rehago la fila:
| OAUTH_REFRESH_TTL_S | 2592000 | Tiempo de vida del refresh token (segundos, 30 días) |
Flujo de uso
Inicia sesión en el Web UI → menú Conexión DB → completa host/puerto/usuario/contraseña/base de datos + Test Connection.
En contenedores Docker, se puede usar el SQL Server del host mediante
host.docker.internal.Menú API Keys → genera una clave (se muestra una sola vez, consérvala).
Menú Permisos de tablas → marca las tablas que la IA puede leer → Guardar permisos. Denegación por defecto.
Conecta tu agente de IA en
https://<dominio>/mcp+ cabeceraAuthorization: Bearer <api-key>.
Conectar el cliente MCP a generic
{
"mcpServers": {
"sql-server": {
"url": "https://<domain>/mcp",
"headers": { "Authorization": "Bearer sk-xxxx" }
}
}
}Prueba rápida con curl:
curl -X POST https://<domain>/mcp \
-H "Authorization: Bearer sk-xxxx" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'Conector personalizado de Claude (claude.ai / Desktop)
Abre Customize → Connectors → Add custom connector.
Remote MCP server URL:
https://<dominio>/mcp.En Advanced settings → introduce OAuth Client ID + Secret desde el menú OAuth Clients (URL de redirect:
https://claude.ai/api/mcp/auth_callback).Puede dejarse vacío: Claude se registra automáticamente mediante Dynamic Client Registration (RFC 2591).
Haz clic en Add → Connect: el navegador abre la página de login del operador → Permitir acceso.
Claude guarda el refresh token y llama a la herramienta MCP con un bearer token.
Claude Code (CLI):
claude mcp add mcp-sqlserv https://<domain>/mcp --transport http \
... # bila client pre-registered: --client-id <id> --client-secret --callback-portEndpoints OAuth
Endpoint | Estándar |
| RFC 9728 |
| RFC 8414 |
| RFC 7591 |
| RFC 6749 + PKCE S256 |
| RFC 6749 / 7636 |
| RFC 7009 |
La identidad OAuth es la sesión del operador. El access token mapea a una API key interna oauth:<client_id>: todos los permisos de tabla, límites de petición y auditoría se aplican también a la conexión de Claude. Revocar un cliente anula inmediatamente todos los tokens de ese cliente.
Herramientas MCP
Herramienta | Función |
| Lista las tablas permitidas + estimación del número de filas |
| Columnas, tipos, nullable, identity, primary key, índices |
| Leer filas con filtro estructurado, ordenación y paginación |
| Contar filas con un filtro opcional |
| Obtener una fila a partir de la primary key |
| Información del servidor / base de datos |
Los nombres de las tablas deben ir sin prefijo de esquema (users, no dbo.users). Las columnas son validadas contra sys.columns; the valores están 100% parametrizados.
Los filtros estructurados soportados: eq, neq, lt, lte, gt, gte, like, startsWith, endsWith, in, between, isNull, isNotNull.
Seguridad
Cero SQL en bruto desde la IA — solo builder de consultas estructurado
Identifier allowlist — regex y verificación de los metadatos reales de la base de datos
Default deny — no se puede acceder a una tabla sin permiso
Límite estricto — máximo 1000 filas por consulta, 20 filtros, 50 valores en
IN, timeout de 30API key + rate limit por clave + log de auditoría en todas las request
Solo lectura: se recomienda que el dato de SQL Server for el que se usa sea
GRANT SELECTLa contraseña de la base de datos se guarda con cifrado AES-256-GCM en SQLite
Despliegue
Despliegue con Docker Compose en la red app-network junto a nginx como reverse proxy (SSL wildcard, SSE sin buffer, CORS para clientes MCP).
Migración entre VPS
El código y Docker funcionarán en cualquier VPS, pero las siguientes dos no se suben a Git (están en .gitignore) y deben migrarse manualmente:
Qué se transfiere | Contenido | Cómo | |||
| Credenciales admin y secretos | Copia el archivo del VPS antigo o lambda nuevo desde | |||
| SQLite (API keys, permisos, auditoría, conexión de base de datos) |
|
| SQLite (API keys, permisos, auditoría, conexiones DB) |
|
# Di VPS baru
git clone https://github.com/<username>/mcp-sqlserv.git && cd mcp-sqlserv
# Migrasi state dari VPS lama (opsional)
rsync -av vps-lama:/path/mcp-sqlserv/.env .env
rsync -av vps-lama:/path/mcp-sqlserv/data ./data
# Network eksternal harus ada dulu (dipakai docker-compose.yaml)
docker network create app-network # abaikan jika sudah ada
docker compose up -d --buildSin migración de
data/, el servidor sigue funcionando — solo se debes configurar de nuevo la conexión de BD, los API keys y los permisos de tabla desde la Web UI.
Estructura del proyecto
mcp-sqlserv/
├── src/
│ ├── index.ts # Bootstrap Express + routing
│ ├── config.ts # Env config
│ ├── db/storage.ts # SQLite: api_keys, db_config, permissions, audit_log
│ ├── sqlserver/ # Connection pool, metadata (sys.tables), query builder
│ ├── mcp/ # MCP server (per-session) + tools
│ ├── oauth/ # OAuth 2.1: router, PKCE, discovery
│ ├── api/ # REST admin (auth, config, keys, permissions, audit)
│ └── ui/ # SPA vanilla JS (public/)
├── public/ # Web UI admin (tanpa build step)
├── test/ # Test suite keamanan + OAuth + smoke
├── Dockerfile # Multi-stage build (node:20-alpine)
├── docker-compose.yaml # Attach ke app-network, host.docker.internal
└── LICENSE # MITAPI REST Admin
Método | Conquista | Descripción |
POST |
| Login de administrador (cookie httpOnly) |
GET |
| Estado de la base de datos, claves y permisos |
GET/DELETE |
| Leer / guardar configuración de la base de datos |
POST |
| Probar la conexión |
GET/POST |
| Listar / crear API key |
PUT/DELETE |
| Renombrar / revocar |
GET/POST |
| Listar / guardar permisos de tablero |
GET |
| Registro de auditoría |
GET |
| Info URL MCP + ejemplo de configuración |
GET |
| Healthcheck (sin autenticación) |
Testing
npm run test:smoke # smoke test dasar
npm run test:security # 29 test: injection, permission, limit, pagination, auth
npm run test:oauth # 46 test: discovery, DCR, PKCE, consent, token, refresh, revoketest/oauth.mjs inicia su propio servidor en el puerto 4100 (directorio de datos oauth-test-data/) — no necesita configuración adicional.
Contribuciones
¡Las contribuciones son bienvenidas! Por favor, revive un issue o un pull request. Para cambios importantes, plantéalo primero en un issue para alinear con el principio del producto: la seguridad es el producto — cada superficie (MCP, interface, Agent Test) debe mantener el mismo estándar: solo escritura, denegación por defecto y ejecución parametrizada.
Licencia
Este proyecto está bajo la MIT License.
Related MCP Connectors
Guard AI agents' PostgreSQL/MySQL access via MCP: SQL audit, auth, masking, write approval
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to securely connect to and query Microsoft SQL Server databases with read-only access, schema discovery, and relationship mapping. Features advanced security protections, health monitoring, and bulk operations for production environments.963 npmMIT
- AlicenseBqualityDmaintenanceAn MCP server that connects AI assistants to Microsoft SQL Server databases, enabling schema exploration and read-only queries safely.4912 npm4MIT
- AlicenseNot gradedqualityCmaintenanceProvides read-only Microsoft SQL Server database access to AI agents with row-level security, enabling SELECT queries, table metadata, and schema introspection through MCP.15 npmMIT
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server for Microsoft SQL Server that enables AI agents to safely explore and query SQL Server databases.804 npmMIT