mcp-sqlserv

mcp-sqlserv

Enables AI agents to safely read SQL Server databases via MCP with structured queries, default-deny table permissions, OAuth authentication, and full audit logging.

Category
Visit Server

README

<div align="center">

mcp-sqlserv

MCP Server untuk akses read-only database SQL Server — anti SQL-injection by construction, dikelola lewat Web Admin UI.

License: MIT Node TypeScript Docker MCP Tests

Zero raw SQL · Default deny · Bind parameter 100% · Audit penuh

</div>


Tentang

mcp-sqlserv memungkinkan AI agent (Claude, Cursor, Claude Code, client MCP apa pun) membaca database SQL Server secara aman dan terkontrol:

  • Semua query dibangun terstruktur oleh server — AI tidak pernah menulis SQL mentah.
  • Identifier (tabel/kolom) divalidasi terhadap metadata asli database (sys.tables, sys.columns).
  • Nilai selalu bind parameterSQL injection mustahil by construction.
  • Izin per-tabel bersifat default deny: tanpa izin eksplisit, tabel tidak bisa disentuh.
  • Setiap request tercatat di audit log, lengkap dengan key, tool, filter, jumlah baris, dan durasi.

Fitur

Fitur Keterangan
MCP Streamable HTTP Endpoint /mcp, kompatibel dengan semua MCP client via HTTP
Multi-project URL per project /mcp/<projectId>, storage & izin terpisah
API Key Buat / revoke key per konsumen AI
OAuth 2.1 Authorization Code + PKCE, DCR (RFC 7591), refresh rotation, revoke
Koneksi SQL Server Host/port/user/pass (terenkripsi AES-256-GCM), TLS opsional
Izin granular Per tabel: baca data dan/atau lihat metadata. Default = DENY
Audit log Semua request AI tercatat: key, tool, tabel, filter, baris, durasi, status
Rate limit 60 req/menit per API key (dapat dikonfigurasi)
Read-only total Tool hanya menghasilkan SELECT; tidak ada jalur tulis sama sekali
Agent Test Chat langsung dengan model Gemini dari Web UI untuk uji end-to-end

Arsitektur

┌──────────────┐   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

Server jalan di http://localhost:4000 — Web UI admin di /, MCP endpoint di /mcp.

Environment Variables

Variable Default Keterangan
PORT 4000 Port server
DATA_DIR ./data Folder SQLite (di-mount ke volume di compose)
ADMIN_USER admin User web UI admin
ADMIN_PASSWORD wajib Password web UI admin (min 8 karakter)
SESSION_SECRET auto Secret JWT/enkripsi (auto-generate & persist jika kosong)
QUERY_TIMEOUT_MS 30000 Timeout query SQL
RATE_LIMIT_PER_MIN 60 Rate limit per API key
OAUTH_ENABLED 1 Nonaktifkan OAuth dengan 0
OAUTH_CODE_TTL_S 600 Umur authorization code (detik)
OAUTH_ACCESS_TTL_S 3600 Umur access token (detik)
OAUTH_REFRESH_TTL_S 2592000 Umur refresh token (detik, 30 hari)

Alur Pakai

  1. Login Web UI → menu Koneksi DB → isi host/port/user/pass/database + Test Connection.

    Untuk container Docker, SQL Server di host bisa dipakai via host.docker.internal.

  2. Menu API Keys → buat key (tampil sekali, simpan!).
  3. Menu Izin Tabel → centang tabel yang boleh dibaca AI → Simpan Izin. Default deny.
  4. Hubungkan AI agent ke https://<domain>/mcp + header Authorization: Bearer <api-key>.

Menghubungkan MCP Client Generik

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

Test cepat dengan 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. Buka Customize → Connectors → Add custom connector.
  2. Remote MCP server URL: https://<domain>/mcp.
  3. Advanced settings → isi OAuth Client ID + Secret dari menu OAuth Clients (redirect URI: https://claude.ai/api/mcp/auth_callback).

    Boleh dikosongkan — Claude otomatis mendaftar via Dynamic Client Registration (RFC 7591).

  4. Klik Add → Connect → browser membuka halaman login operator → Izinkan Akses.
  5. Claude menyimpan refresh token dan memanggil tool MCP dengan 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-port

Endpoint OAuth

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 operator + consent) RFC 6749 + PKCE S256
POST /oauth/token (code exchange + refresh rotation) RFC 6749 / 7636
POST /oauth/revoke RFC 7009

Identitas OAuth = sesi operator. Access token memetakan ke API key internal oauth:<client_id> — seluruh izin tabel, rate limit, dan audit berlaku juga untuk koneksi Claude. Revoke client langsung mematikan semua token client tersebut.

Tools MCP

Tool Fungsi
list_tables Daftar tabel yang diizinkan + perkiraan jumlah baris
get_table_schema Kolom, tipe, nullable, identity, primary key, indeks
read_records Baca baris dengan filter terstruktur, order, pagination
count_records Hitung baris dengan filter opsional
get_record_by_pk Ambil 1 baris via primary key
server_info Info server / database

Nama tabel wajib tanpa prefix schema (users, bukan dbo.users). Kolom divalidasi terhadap sys.columns; nilai 100% bind parameter.

Filter terstruktur yang didukung: eq, neq, lt, lte, gt, gte, like, startsWith, endsWith, in, between, isNull, isNotNull.

Keamanan

  • Zero raw SQL dari AI — hanya builder query terstruktur
  • Identifier allowlist — regex + verifikasi metadata DB asli
  • Default deny — tabel tanpa izin tidak bisa diakses
  • Limit keras — maks 1000 baris/query, 20 filter, 50 nilai IN, timeout 30s
  • API key + rate limit per key + audit log semua request
  • Read-only — saran: user SQL Server cukup dengan GRANT SELECT
  • Password DB tersimpan terenkripsi AES-256-GCM di SQLite

Deployment

Deploy dengan Docker Compose di jaringan app-network bersama nginx sebagai reverse proxy (SSL wildcard, SSE non-buffered, CORS untuk MCP client web).

Migrasi antar VPS

Kode dan Docker akan jalan otomatis di VPS mana pun, tetapi dua hal berikut tidak ikut ke Git (ada di .gitignore) dan harus dimigrasikan manual:

Yang dipindahkan Isinya Cara
.env Kredensial admin & secret Salin file dari VPS lama, atau buat baru dari .env.example
data/ SQLite (API keys, izin, audit, koneksi DB) rsync / salin folder dari VPS lama
# 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

Tanpa migrasi data/, server tetap jalan — Anda hanya perlu setup ulang koneksi DB, API key, dan izin tabel dari Web UI.

Struktur Proyek

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

API REST Admin

Method Path Keterangan
POST /api/auth/login Login admin (cookie httpOnly)
GET /api/status Status DB, key, permission
GET/PUT /api/config Baca / simpan konfigurasi DB
POST /api/config/test Test koneksi
GET/POST /api/keys List / buat API key
PUT/DELETE /api/keys/:id Rename / revoke
GET/PUT /api/permissions List / simpan izin tabel
GET /api/audit Audit log
GET /api/connect Info URL MCP + contoh config
GET /healthz Health check (tanpa auth)

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

test/oauth.mjs me-spawn server sendiri di port 4100 (data dir oauth-test-data/) — tidak butuh konfigurasi tambahan.

Kontribusi

Kontribusi dipersilakan! Silakan buka issue atau pull request. Untuk perubahan besar, diskusikan dulu melalui issue agar sesuai dengan prinsip produk: security is the product — setiap permukaan (MCP, UI, Agent Test) harus mempertahankan standar yang sama: read-only, default-deny, parameterized.

Lisensi

Proyek ini dilisensikan di bawah MIT License.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured