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.
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.
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 parameter → SQL 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
- 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. - Menu API Keys → buat key (tampil sekali, simpan!).
- Menu Izin Tabel → centang tabel yang boleh dibaca AI → Simpan Izin. Default deny.
- Hubungkan AI agent ke
https://<domain>/mcp+ headerAuthorization: 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)
- Buka Customize → Connectors → Add custom connector.
- Remote MCP server URL:
https://<domain>/mcp. - 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).
- Klik Add → Connect → browser membuka halaman login operator → Izinkan Akses.
- 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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。