Skip to main content
Glama
Andres2009

facturas-mcp

by Andres2009
README.md
# facturas-mcp

Servidor MCP de solo lectura para preguntarle a Claude Desktop sobre `DWH.facturas`.

## Como funciona

- Claude Desktop lanza este servidor localmente (proceso propio, se comunica por stdio).
- El servidor se conecta a SQL Server usando un login **de solo lectura** (`mcp_readonly`)
  que unicamente tiene `GRANT SELECT` sobre `DWH.facturas`. Ese permiso vive en la base
  de datos, no en este codigo -- es la barrera real de seguridad.
- Expone dos herramientas:
  - `listar_columnas_facturas`: para que Claude descubra las columnas antes de escribir SQL.
  - `consultar_facturas`: ejecuta un `SELECT` de solo lectura contra `DWH.facturas`.

## Paso 1 -- Crear el login restringido en SQL Server

Corre `setup-db-login.sql` UNA VEZ, con un usuario que tenga permisos de administracion
sobre la base de datos. Cambia la contrasena de ejemplo antes de ejecutarlo.

## Paso 2 -- Configurar las credenciales de este servidor

Crea un archivo `.env` en esta carpeta (no se sube a git) con:

```
MSSQL_SERVER=sintesiserp.com
MSSQL_DATABASE=Diverxamotos_4_2
MSSQL_USER=mcp_readonly
MSSQL_PASSWORD=la-contrasena-que-pusiste-en-el-paso-1
```

## Paso 3 -- Registrar el servidor en Claude Desktop

Abre `claude_desktop_config.json` (en Windows: `%APPDATA%\Claude\claude_desktop_config.json`)
y agrega esto dentro de `"mcpServers"`:

```json
{
  "mcpServers": {
    "facturas": {
      "command": "node",
      "args": ["C:\\Users\\Developer-07\\Documents\\DESARROLLO\\facturas-mcp\\dist\\index.js"],
      "env": {
        "MSSQL_SERVER": "sintesiserp.com",
        "MSSQL_DATABASE": "Diverxamotos_4_2",
        "MSSQL_USER": "mcp_readonly",
        "MSSQL_PASSWORD": "la-contrasena-que-pusiste-en-el-paso-1"
      }
    }
  }
}
```

Cierra Claude Desktop por completo y vuelve a abrirlo para que cargue el servidor nuevo.

## Paso 4 -- Probarlo

En Claude Desktop, pregunta algo como: *"¿Cuánto vendí hoy según DWH.facturas?"*

## Agregar otra tabla despues

1. En SQL Server: `GRANT SELECT ON DWH.otratabla TO mcp_readonly;`
2. En `src/index.ts`: agrega `"DWH.OTRATABLA"` al arreglo `ALLOWED_TABLES`, y opcionalmente
   una tool `listar_columnas_otratabla` igual a la que ya existe.
3. `npm run build` y reinicia Claude Desktop.

## Modo remoto (Render) -- para que varias personas lo usen desde Claude.ai

Por defecto el servidor corre en modo **stdio** (local, un proceso por usuario, lanzado
por Claude Desktop). Para que varias personas lo usen desde Claude.ai sin instalar nada,
se puede desplegar como servicio HTTP en Render. El mismo `dist/index.js` sirve para
los dos modos -- el switch es la variable de entorno `MCP_TRANSPORT`.

**Importante:** en modo HTTP la unica proteccion de la base de datos sigue siendo el
login de solo lectura, pero el *servidor MCP en si* queda expuesto en una URL publica.
Por eso el modo HTTP exige un token (`MCP_AUTH_TOKEN`) -- sin el, el proceso ni siquiera
arranca. Cualquiera con la URL **y** el token puede ejecutar `SELECT` contra
`DWH.facturas`, asi que trata ese token como una contrasena: no lo publiques, no lo
subas a git, y rotalo si se filtra.

### Paso 1 -- Generar un token fuerte

Por ejemplo, con PowerShell:

```powershell
-join ((48..57)+(65..90)+(97..122)|Get-Random -Count 40|%{[char]$_})
```

Guarda ese valor -- es tu `MCP_AUTH_TOKEN`.

### Paso 2 -- Crear el Web Service en Render

1. Sube este proyecto a un repositorio de GitHub (necesitas `node_modules` y `dist`
   fuera del repo -- ya estan en `.gitignore` -- Render corre `npm install` y `npm run build` el solo).
2. En Render: **New -> Web Service**, conecta el repo.
3. **Build Command:** `npm install && npm run build`
4. **Start Command:** `npm start`
5. **Environment variables** (pestaña Environment):
   ```
   MCP_TRANSPORT=http
   MCP_AUTH_TOKEN=<el token del paso 1>
   MSSQL_SERVER=sintesiserp.com
   MSSQL_DATABASE=Diverxamotos_4_2
   MSSQL_USER=mcp_readonly
   MSSQL_PASSWORD=<la contrasena del login de solo lectura>
   ```
   (Render define `PORT` automaticamente -- no hace falta agregarla.)
6. Deploy. Cuando termine, Render te da una URL tipo `https://facturas-mcp.onrender.com`.

### Paso 3 -- Probar que el servidor responde

```bash
curl https://facturas-mcp.onrender.com/health
# {"status":"ok"}

curl -X POST https://facturas-mcp.onrender.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer <tu MCP_AUTH_TOKEN>" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
```

Si responde con `serverInfo` y `capabilities`, el servidor esta vivo y aceptando el token.
Sin el header `Authorization` correcto debe responder `401`.

### Paso 4 -- Conectarlo desde Claude.ai / Claude Desktop

En Claude.ai (o Claude Desktop reciente): **Settings -> Connectors -> Add custom connector**,
y registra la URL `https://facturas-mcp.onrender.com/mcp` con el header de autenticacion
`Authorization: Bearer <tu MCP_AUTH_TOKEN>` (la UI exacta puede variar segun la version
de Claude -- busca la opcion de servidor MCP remoto / custom connector).

Nota: el plan free de Render "duerme" el servicio tras inactividad -- el primer request
tras el sueño puede tardar unos segundos en responder.

TDQS

A4.6/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct roles: one is for inspecting the table schema, the other for executing read-only SQL queries against the table. There is no overlap or ambiguity about which to call.

Naming Consistency5/5

Both tool names follow the same lowercase snake_case verb_object pattern in Spanish: listar_columnas_facturas and consultar_facturas. The naming is predictable and aligns with each tool's function.

Tool Count4/5

With only two tools, the server is minimal, but the scope is intentionally narrow: schema discovery plus SQL querying of a single invoices table. This is slightly below the typical 3-15 tool range but reasonable and well-scoped for its purpose.

Completeness5/5

For a read-only query server over DWH.facturas, the surface is complete: agents can discover the schema and then run arbitrary SELECT queries to answer business questions. No obvious additional operations are needed for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues