Skip to main content
Glama
Fattan-malva

mcp-sqlserv

by Fattan-malva

mcp-sqlserv

MCP-Server für schreibgeschützten Zugriff auf SQL-Server-Datenbanken — SQL-Injection konstruktionsbedingt ausgeschlossen, verwaltet über eine Web-Admin-UI.

License: MIT Node TypeScript Docker MCP Tests

Kein rohes SQL · Default Deny · 100 % Bindparameter · Vollständiges Audit


Überblick

mcp-sqlserv ermöglicht KI-Agenten (Claude, Cursor, Claude Code, beliebige MCP-Clients), SQL-Server-Datenbanken sicher und kontrolliert zu lesen:

  • Alle Abfragen werden vom Server strukturiert aufgebaut – die KI schreibt niemals rohes SQL.

  • Bezeichner (Tabellen/Spalten) werden gegen die tatsächlichen Datenbank-Metadaten validiert (sys.tables, sys.columns).

  • Werte sind immer Bindparameter → SQL-Injection ist konstruktionsbedingt unmöglich.

  • Berechtigungen sind pro Tabelle Default Deny: Ohne explizite Berechtigung kann eine Tabelle nicht angefasst werden.

  • Jede Anfrage wird im Audit-Log erfasst, inklusive Schlüssel, Tool, Filter, Zeilenzahl und Dauer.

Related MCP server: SQL Server MCP

Funktionen

Merkmal

Beschreibung

MCP Streamable HTTP

Endpoint /mcp, kompatibel mit allen MCP-Clients über HTTP

Multi-Projekt

URL pro Projekt /mcp/<projectId>, Speicher & Berechtigungen getrennt

API-Key

Schlüssel pro KI-Anwendung erstellen / widerrufen

OAuth 2.1

Authorization Code + PKCE, DCR (RFC 7591), Refresh Rotation, Revoke

SQL-Server-Verbindung

Host/Port/Benutzer/Passwort (verschlüsselt mit AES-256-GCM), TLS optional

Granulare Berechtigung

Pro Tabelle: Daten lesen und/oder Metadaten ansehen. Standard = DENY

Audit-Log

Alle KI-Anfragen werden protokolliert: Key, Tool, Tabelle, Filter, Zeilen, Dauer, Status

Rate-Limit

60 Anfragen pro Minute und API-Key (konfigurierbar)

Vollständiger-Read-Only

Tools erzeugen ausschließlich SELECT; es gibt keinerlei Schreibpfad

Agent-Test

Chatten Sie direkt mit einem Gemini-Modell aus der Web-UI für End-to-End-Tests

Architektur

┌──────────────┐   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 │    │
                                                      └──────────────┴──────────┴────┘

Quick Start

# 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/healthz

Der Server läuft unter http://localhost:4000 – Web-Admin-UI unter /, MCP-Endpoint mit /mcp.

Umgebungsvariablen

Variable

Soll

Beschreibung

PORT

4000

Server-Port

DATA_DIR

./data

SQLite-Ordner (bei Compose als Volume eingehängt)

ADMIN_USER

admin

Benutzer für die Web-Admin-UI

ADMIN_PASSWORD

Plicht

Passwort für die Web-Admin-UI (mindestens 8 Zeichen)

SESSION_SECRET

automatisch

JWT-/Verschlüsselungs-Secret (auto-generiert & persistent, falls leer)

QUERY_TIMEOUT_MS

30000

Ablaufzeit für SQL-Abfragen

RATE_LIMIT_PER_MIN

60

Zulässige Anfragen pro API-Key und Minute

OAUTH_ENABLED

1

Deaktivieren mit 0

OAUTH_CODE_TTL_S

600

TTL des Autorisierungscodes (Sekunden)

OAUTH_ACCESS_TTL_S

3600

TTL des Access-Tokens (Sekunden)

OAUTH_REFRESH_TTL_S

2592000

TTL des Refresh-Tokens (Sekunden, 30 Tage)

Verwendung

  1. In der Web-UI anmelden → Menü DB-Verbindung → Host/Port/Benutzer/Passwort/Datenbank eintragen + Testverbindung.

    Für Docker-Container ist der SQL Server des Hosts über host.docker.internal erreichbar.

  2. Menü mit API-Keys → Schlüssel erstellen (wird einmal angezeigt, unbedingt speichern!).

  3. Menü Tabellenberechtigungen → Tabellen auswählen, welche die KI lesen darf → Berechtigungen speichern. Standard ist: verweigert.

  4. KI-Agent mit https://<domain>/mcp verbinden + Header Authorization: Bearer <api-key>.

Generischen MCP-Client verbinden

{
  "mcpServers": {
    "sql-server": {
      "url": "https://<domain>/mcp",
      "headers": { "Authorization": "Bearer sk-xxxx" }
    }
  }
}

Schneller Test mit 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"}}}'

Claude Custom Connector (claude.ai / Desktop)

  1. Öffne Customize → Connectors → Add custom connector.

  2. Remote MCP server URL: url: Kürzel Alternativ: https://<domain>/mcp.

  3. Unter Advanced settings → OAuth Client ID + Secret aus dem Menü OAuth Clients eintragen (Redirect-URI: https://claude.ai/api/mcp/auth_callback).

    Kann leer bleiben – Claude registriert selbst per Dynamic Client Registration (RFC 7591).

  4. Klicke D – Hafe → Add → Connect – der Browser öffnet die Betreiber-Anmeldeseite → Zugriff erlauben.

  5. Claude speichert das Refresh-Token und ruft die MCP-Tools mit einem Bearer-Token ab.

Claude Code ist (CLI):

claude mcp add mcp-sqlserv https://<domain>/mcp --transport http \
  ... # bila client pre-registered: --client-id <id> --client-secret --callback-port

OAuth-Endpunkte

Endpoint

Standard

GET /.well-known/oauth-protected-resource

RFC 9728

GET /.well-known/oauth-authorization-server

RFC 8414

POST /oauth/register

RFC 7591 (DCR, public + confidential)

GET /oauth/authorize (Login des Betreibers + Zustimmung)

RFC 6749 + PKCE S256

POST /oauth/token (Code-Austausch + Refresh-Rotation)

RFC 6749 / 7636

POST /oauth/revoke

RFC 7009

Die OAuth-Identität entspricht der Betreiber-Sitzung. Keine Access-Tokens sind an den internen API-Key oauth:<client_id> gebunden – alle Berechtigungen, Ratelimit und das Audit gelten darüber hinaus auch für Claude-Verbindungenstrated. Clients werden alle zugehörigen sofort aktualisiert.

MCP-Tools

Werkzeug

Funktion

list_tables

Listet die erlaubten Tabellen + ungefähre Zeilenanzahl

get_table_schema

Spalten, Typen, Nullability, Identity, Primärschlüssel, Indizes

read_records

Zeilen mit Struktur-Filter, Sortierung, Seitenzahl lesen

count_records

Zeilen mit optionalem Filter zählen

get_record_by_pk

Daten aus per 1 Zeile über den Primärschlüssel holen

server_info

Server- / Datenbank- Informationen

Tabellennamen müssen ohne Schema-Präfix angegeben werden (users, nicht dbo.users). Spaltenanzahl werden gegen sys.columns überprüft; die Werte sind zu 100 % Bind-Parameter.

Unterstützte strukturierte Filter: eq, neq, lt, lte, gt, gte, like, startsWith, ndc, endsWith, in, interval, isNull, isNotNull.

Sicherheit

  • Kein rohes SQL von KI– nur strukturierter Query-Builder

  • Identifier-Allowlist – Regex plus Validierung gegen echte DB-Metadata

  • Default Deny – Tabellen ohne Berechtigung können nicht zugreifen

  • Moderate Grenzen – max. 1000 ZeilenAufruf, 20 Filter, 50 IN-Werte, Timeout 30 s

  • API Key + Grenzrate – pro Key + Audit-Log aller Aufrufe

  • Nur-Lesen – Empfehlung: SQL-Server-Benutzer nur mit GRANT SELECT

  • Diesel-Passwort ist mit AES-256-GCM verschlüsselt in in SQLite gespeichert

Deployment

Einsatz mit Docker Compose im Netzwerk app-network zusammen mit nginx als Reverse-Proxy (Wildcard-SSL, nicht gepufferte SSE, CORS für Web-MCP-Clients).

Migration zwischen VPS

Karabiner und Docker funktionieren automatisch auf jede VPS; Spiele jedoch Folgendes sind nicht in Git (im .gitignore) und müssen manuell umgezogen werden:

Übertragen

Inhalt

Vorgehensweise

.env

Admin-Zugangsdaten & Secrets

Dateicopied einen VPS alt übernehmen, oder erstelle neue aus .env.example

data/

SQLite (API-Keys, Berechtigungen, Audit-Log, DB-Verbindungen)

rsync / Ordnerordner von VPS älter übernehmen

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

Ohne Migration von data/ läuft ein Server weiter – nur zuvor müssen DB-Verbindung, API-Keys und Tabellenberechtigungen und die WebUI neu eingerichtet werden.

Projektstruktur

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

Admin REST API

Methode

Pfad

Beschreibung

POST

/api/auth/login

Admin-Login (httpOnly-Cookie)

GET

/api/status

Status von DB, Keys, Berechtigungen

GET/PUT

/api/config

DB-Konfiguration lesen / speichern

POST

/api/config/test

Verbindung testen

GET/POST

/api/keys

API-Keys auflisten / neu erzeugen

PUT/DELETE

/api/keys/:id

Umbenennen / widerrufen

GET/LESS

/api/permissions

Tabellenberechtigungen anzeigen / speichern

GET

/api/audit

Zugriffsprotokoll (Audit-Log)

GET

/api/connect

MCP-URL-Info + Beispiel-Konfiguration

GET

/healthz

Health-Check (ohne Login)

Tests

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, revoke

test/oauth.mjs startet bei eigener Server auf Datenbankport 4100 Pfad Port (Datenverzeichnis oauth-test-data/) — es gibt keine zusätzliche Konfiguration.

Mitwirken

Mitwirkende sind willkommen! Bitte eröffne eine Issue oder eine Pull-Request. Für größere Änderungen zuerst in einer Issue besprechen, damit es den dem Prinzip “security is the product” folgt — jede Fläche (MCP, UI, Agent Test) soll denselben Standards linearhalten: read-only, default-deny, parameterized.

Lizenz

Dieses Projekt ist unter der MIT License lizenziert.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    9
    63 npm
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    An MCP server that connects AI assistants to Microsoft SQL Server databases, enabling schema exploration and read-only queries safely.
    49
    12 npm
    4
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides 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 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A read-only MCP server for Microsoft SQL Server that enables AI agents to safely explore and query SQL Server databases.
    804 npm
    MIT