
MCP Gateway
io.github.PanosSalt由 GitHub 帳號 PanosSalt 發布v1.0.4更新於 Oct 24, 2026
Multi-tenant MCP platform with OAuth 2.1, Entra SSO, RBAC and audit logging.
概覽
多租戶 MCP 閘道,向助理提供受角色控管的資料庫查詢與沙箱檔案系統工具,並支援 OAuth 2.1、Entra SSO、RBAC 與稽核記錄。
- 可以做什麼
- 資料庫:列出可存取的連線、讀取結構描述,並執行僅限 SELECT 的 SQL(30 秒逾時),以 JSON 回傳結果,可選擇由 Claude 產生自然語言摘要。檔案系統:在設定的目錄內讀取、列出目錄、檢視目錄樹、以萬用字元搜尋與查看檔案資訊(分析師以上);寫入、建立目錄與移動檔案(僅管理員)。查詢目前 UTC 時間。平台管理:透過 API 與管理介面管理租戶、使用者與角色、資料庫連線、依工具的角色覆寫、API 金鑰、稽核記錄與查詢歷史。
- 適用情境
- 適合團隊希望用一個共用、具身分驗證的 MCP 端點,讓助理以唯讀方式查詢多個資料庫並取得受限的檔案系統存取,同時具備租戶隔離與角色權限控管。也適合需要 SSO、稽核紀錄以及集中控管各角色可用工具的組織。
- 執行需求
- 以自架服務執行(Docker 與 Docker Compose,或 Python 加 PostgreSQL),透過 SSE 存取;清單中列為遠端端點。需要 SECRET_KEY、ENCRYPTION_KEY、POSTGRES_PASSWORD 與 DATABASE_URL;自然語言查詢端點需要 ANTHROPIC_API_KEY;檔案系統工具需設定 FILESYSTEM_ALLOWED_DIRS;SSO 為選用,需 Entra ID 應用程式註冊。用戶端透過 OAuth 2.1 瀏覽器流程或 URL 中的 API 金鑰驗證。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 MCP Gateway,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Web executable,透過 SSE。 遠端服務在工作區中設定後即可從網頁執行環境執行。
交給代理程式安裝
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.PanosSalt%2FMCP-Gateway/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。其他 MCP 客戶端
把它新增到你客戶端的 mcpServers 設定中。
{
"mcpServers": {
"gateway": {
"type": "sse",
"url": "https://your-gateway.example.com/t/your-org/mcp/sse"
}
}
}README
MCP Gateway
[Tests] [License: MIT] [Python 3.12]
The production platform for MCP tools.
Claude Desktop can connect to your internal tools — databases, filesystems, APIs, anything — through a single authenticated endpoint. You control who can use which tools, every action is logged, and no raw credentials ever leave your server.
Built-in tools: SQL query (Postgres, MySQL, SQLite, MSSQL), filesystem access. Custom tools: plug in anything that implements the MCP tool interface.
See it in action — short demo of Claude Desktop querying a database through MCP Gateway.
Table of Contents
- Overview
- Features
- Architecture
- Quick Start
- Configuration
- Authentication
- API Reference
- MCP Integration
- Role-Based Access Control
- Entra ID / SSO
- Development
- Troubleshooting
- Security
- Additional Documentation
Overview
MCP Gateway sits between AI assistants and your databases. It:
- Authenticates users via password login, Microsoft Entra ID (Azure AD), or API keys
- Enforces role-based access control (viewer / analyst / admin)
- Exposes databases as MCP tools that AI assistants can discover and call
- Translates natural language questions into SQL via Claude, executes queries, and summarizes results
- Logs all activity to a structured audit trail
What you get out of the box
For your organisation
- One URL for Claude Desktop — users authenticate once, access everything they're allowed
- Microsoft Entra ID SSO — roles assigned automatically from Azure AD groups
- Full audit trail — every tool call, every query, every login, who did what and when
For your tools
- Drop any MCP tool into the gateway and it inherits auth, RBAC, and logging automatically
- Per-tool role overrides — restrict SQL execution to analysts, filesystem writes to admins
- Bundled: SQL tools (4 databases), filesystem tools (read, write, search, tree)
For your security team
- No credentials on employee machines
- Tenant isolation — org A cannot see org B's tools or data
- API keys for CI/CD, OAuth 2.1 + PKCE for human users
Supported Databases
Filesystem Tools
- Sandboxed file read/write/search exposed as MCP tools
- Enabled via
FILESYSTEM_ALLOWED_DIRSenvironment variable - Read operations (analyst+):
fs_read_file,fs_list_directory,fs_directory_tree,fs_search_files,fs_get_file_info - Write operations (admin):
fs_write_file,fs_create_directory,fs_move_file
Admin UI
- Web interface served at
/admin/ - Manage connections, users, SSO config, API keys, and tool roles
- View audit logs, generated SQL, and query results
Architecture
Technology Stack
Dev tooling (requirements-dev.txt): pytest, pytest-asyncio, ruff, mypy.
The pinned versions above are generated from requirements.txt — update both together.
Project Structure
Database Schema
Quick Start
Prerequisites
- Docker and Docker Compose
- An Anthropic API key (for the
/query/endpoint; not needed for raw MCP tool access)
1. Clone and configure
Edit .env:
Generate secure random values:
2. Start the stack
Services started:
apion port 8000 (FastAPI + admin UI)dbon port 5432 (PostgreSQL, internal only)
3. Register your first tenant
The slug becomes part of your MCP URL: http://localhost:8000/t/my-org/mcp/sse
4. Open the admin UI
Navigate to http://localhost:8000/admin/ and sign in with your admin credentials.
5. Add a database connection
In the admin UI → Connections → Create connection, or via API:
6. Connect Claude Desktop
Add to your Claude Desktop MCP config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
Restart Claude Desktop. It will open a browser window for OAuth login. After authenticating, Claude can use your database tools.
Configuration
All configuration is via environment variables. See .env.example for a template.
Required
POSTGRES_PASSWORD is also required, but by docker-compose, not by the application — it seeds the db service and is interpolated into DATABASE_URL. Compose fails fast if it, SECRET_KEY or ENCRYPTION_KEY are unset.
Optional
Entra ID
Authentication
Local login
Response:
Include the token in subsequent requests:
Access tokens expire after 15 minutes by default. Use the OAuth token endpoint with a refresh token to get a new pair.
API keys
Generate a key (requires authentication):
The raw_key in the response is shown once only — store it immediately:
Use via query parameter:
OAuth 2.1 (MCP browser clients)
The gateway implements RFC 8414 OAuth discovery. MCP clients follow this flow automatically:
- Client connects to
/t/{slug}/mcp/sse— receives 401 +WWW-Authenticateheader pointing to the OAuth discovery URL - Client fetches
/.well-known/oauth-authorization-server/t/{slug} - Client registers dynamically via
POST /t/{slug}/oauth/register - Client opens browser → user logs in at
/t/{slug}/oauth/authorize - Client exchanges code + PKCE verifier for tokens via
POST /t/{slug}/oauth/token - Client reconnects with Bearer token
No manual configuration needed — just point mcp-remote at your tenant's SSE URL.
API key auth (MCP non-interactive clients)
For CI/CD, scripts, or when you want to skip the browser login, pass an API key in the URL:
The SSE endpoint validates the key and establishes the session directly — no OAuth flow, no browser window. See API Keys for details.
API Reference
All management endpoints are available at both their canonical paths (e.g. /tenants/) and the versioned prefix /api/v1/ (e.g. /api/v1/tenants/). The unversioned paths are kept for backward compatibility with the current frontend; new integrations should use /api/v1/. Protocol-defined routes (OAuth /t/{slug}/…, MCP /t/{slug}/…, /.well-known/) and infrastructure routes (/health, /admin) are intentionally unversioned.
The
curlexamples below use the unversioned paths so they match the running admin UI. Prefix them with/api/v1for new integrations.
Authentication
Tenants & Users
Entra ID / SSO
Register tenant:
Create user:
Roles: viewer (default), analyst, admin. Passwords must be at least 12 characters.
Connections
Add connection:
min_role controls who can query this connection. Users below this role cannot see or use it.
Natural Language Query
Query:
Response:
The query pipeline:
- Fetches schema from the database
- Sends schema + question to Claude → generates SQL
- Validates SQL is a
SELECTstatement (blocks all writes) - Executes SQL (30-second timeout)
- Sends question + results to Claude → generates summary
Tools
List tools:
Response:
Override tool role:
API Keys
Audit Logs
Query parameters: skip (offset, default 0), limit (max 200, default 50), event_prefix (comma-separated, e.g. query, login, fs).
Health Check
Returns 503 if the database is unreachable. Suitable for Kubernetes liveness and readiness probes.
MCP Integration
Connecting Claude Desktop
Install mcp-remote:
Add to claude_desktop_config.json:
On first connection, a browser window opens for OAuth login. After authenticating, mcp-remote caches the tokens and reconnects automatically. Tokens refresh silently in the background.
Available MCP Tools
For each active database connection the user can access, the gateway exposes two tools:
get_schema_{connection-name}_{id}
Returns the full database schema (tables, columns, types, constraints, indexes). Claude calls this first to understand the data structure before generating SQL.
execute_sql_{connection-name}_{id}
Executes a SELECT statement and returns rows as JSON. Any non-SELECT statement is rejected (INSERT, UPDATE, DELETE, DROP, etc.). Execution timeout: 30 seconds.
list_connections
Returns all database connections the user can access with their names and types.
get_current_time
Returns the current UTC time in ISO 8601 format. Available to all roles.
Filesystem tools (only when FILESYSTEM_ALLOWED_DIRS is configured):
SSE Endpoints
OAuth Discovery Endpoints
Build your own tools
Any Python function becomes an authenticated, audited MCP tool:
Restart the gateway. The tool appears in Claude Desktop automatically, with auth and audit logging included.
Role-Based Access Control
Three roles in ascending order of permission: viewer → analyst → admin
Default permissions
Per-connection roles
Each connection has a min_role. Users below this role cannot see or use that connection, or the MCP tools it generates.
Example: A sensitive production database with min_role: admin is invisible to analysts and viewers entirely — it won't appear in /connections/ or /tools/, and its MCP tools won't be listed.
Per-tool overrides
Admins can override the effective minimum role for any MCP tool independently of the connection's min_role:
Entra ID / SSO
Setup in Azure AD
- Register an application in Azure Active Directory (App registrations → New registration)
- Add redirect URIs:
http://<gateway-url>/auth/entra/callback(admin UI SSO)http://<gateway-url>/t/<slug>/oauth/entra-callback(MCP OAuth flow)
- Under API permissions, add:
- Delegated (Microsoft Graph):
openid,profile,email,User.Read,GroupMember.Read.All - Application (Microsoft Graph):
GroupMember.Read.All(required for role sync during token refresh) - Grant admin consent for both the delegated and the application
GroupMember.Read.All
- Delegated (Microsoft Graph):
- Create a Client secret (Certificates & secrets → New client secret)
- Note your Azure tenant ID, app client ID, and the client secret value
Configure in MCP Gateway
Via admin UI: SSO Config tab, or via API:
Group IDs are optional — configure only what you need. Users in multiple mapped groups get the highest role.
Login flow
Direct users to: http://<gateway>/auth/entra/login?tenant_slug=<slug>
The gateway redirects to Microsoft. After authentication it:
- Fetches the user's profile from Microsoft Graph (
/me) - Fetches transitive group memberships (
/me/transitiveMemberOf) - Maps groups to roles (highest wins: admin > analyst > viewer)
- Creates the user if they don't exist (just-in-time provisioning)
- Returns a JWT
Development
Local setup (without Docker)
Frontend development
The Vite dev server proxies all API paths to http://localhost:8000, so the frontend and API can run independently during development.
Sample databases
Starts pre-seeded sample databases:
sample_postgreson port 5433 →postgresql://sampleuser:samplepass@localhost:5433/sampledbsample_mysqlon port 3307 →mysql+pymysql://sampleuser:samplepass@localhost:3307/sampledb
Add these as connections in the admin UI to explore the natural language query feature.
Running tests
Database migrations
Building for production
Troubleshooting
"SECRET_KEY must be set" / "ENCRYPTION_KEY must be set"
docker-compose uses ${VAR:?error message} syntax — it fails fast if these are not set. Generate them:
Add to your .env file before running docker compose up.
API returns 503 on health check
The database is not reachable. Check:
Claude Desktop doesn't open a browser for login
Ensure mcp-remote is installed: npm install -g mcp-remote. Check that BASE_URL in .env matches the URL you put in claude_desktop_config.json. A mismatch causes the OAuth callback to fail silently.
Query returns "INVALID_QUERY"
The LLM could not generate a valid SELECT for your question, or it generated a non-SELECT statement (which is blocked). Try:
- Be more specific in your question
- Ensure your database has descriptive column and table names
- Check that
ANTHROPIC_API_KEYis set and valid
Entra login returns 400 "Entra ID not configured for this tenant"
The tenant doesn't have an Entra ID configuration. Add one via Admin UI → SSO Config or POST /auth/entra/config.
Entra callback returns 403 "Not a member of any authorized group"
The Azure AD user is not in any of the three groups configured for the tenant. Either:
- Add the user to one of the mapped groups in Azure AD
- Update the group IDs in the gateway config to match the user's actual groups (
POST /auth/entra/config)
Refresh token rejected as "Invalid or expired"
Refresh tokens are single-use — each use issues a new pair and revokes the old one. If two requests attempt to use the same refresh token simultaneously, the second fails. Re-authenticate to get a fresh pair.
Rate limit 429 responses
Wait 60 seconds for the limit window to reset.
Limits are keyed on the client IP. Two deployment caveats:
- Without
REDIS_URLthe limiter stores counters in process memory, so each uvicorn worker enforces its own copy. WithWEB_CONCURRENCY=4the effective limit is roughly four times the value above. SetREDIS_URLfor shared enforcement. - Behind a reverse proxy, set
TRUST_PROXY_HEADERS=trueso the key comes fromX-Forwarded-For. Without it every request appears to originate from the proxy and all clients share a single bucket. Do not enable it unless a trusted proxy actually sets the header — clients can otherwise spoof it.
Security
Credentials at rest
HTTP security headers
All responses include:
X-Content-Type-Options: nosniffX-Frame-Options: DENYStrict-Transport-Security: max-age=31536000Cache-Control: no-storeon auth endpoints
OAuth protections
- PKCE S256 — prevents authorization code interception attacks
- Single-use authorization codes — codes expire after 5 minutes and are deleted on first use
- Rotating refresh tokens — each refresh revokes the previous token (prevents replay)
- Loopback-only redirect URIs — only
localhost,127.0.0.1, and::1are accepted as redirect targets (per RFC 8252)
SQL safety
The execute_sql MCP tool rejects all non-SELECT statements via sqlglot AST parsing before any query reaches the database. INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, TRUNCATE, and EXEC are all blocked regardless of how they are formatted.
Tenant isolation
All database queries are scoped to current_user.tenant_id. Foreign key constraints enforce isolation at the schema level — there is no code path that allows data from one tenant to appear in another tenant's responses.
Rotating secrets
Rotating SECRET_KEY: All existing JWTs immediately become invalid. Users must re-authenticate. Refresh tokens (hashed separately) are also invalidated. API keys are also invalidated — they are HMAC-keyed with SECRET_KEY, so existing keys must be revoked and re-issued after rotation.
Rotating ENCRYPTION_KEY: Requires re-encrypting all stored connection strings and Entra client secrets with the new key before the old key is removed. Plan this as a maintenance window — the gateway cannot serve connections during the rotation.
Audit log
All significant events are written to the audit_logs table:
Query the audit log:
Additional Documentation
What's Coming — SaltMine AI
MCP Gateway is the open source foundation. A managed platform called SaltMine AI is currently in development, built on top of this project, following the same security principles and aimed at business teams who want to query their data without any infrastructure to manage.
Planned features include:
- Multi-datasource queries across databases, data lakes, and APIs in a single question
- Business-user chat interface with visualisations — no SQL knowledge required
- Data privacy controls with field-level masking and query-level audit trails
- Zero Vendor Lock-in on AI
- Understands Your Business Language
If you're interested in learning more, have a use case you'd like to discuss, or just want to follow the progress:
來源:README.md,提交 257be6a
工具
0版本歷史
4- v1.0.4最新Sep 27, 2026
- v1.0.3Sep 19, 2026
- v1.0.2Sep 18, 2026
- v1.0.0Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通必需25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式必需10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分