
Universal DB (read-only)
io.github.alghanimv0.1.0更新於 Oct 9, 2026
Read-only, guarded SQL access for AI agents: PostgreSQL, MySQL, ClickHouse, Oracle, SQL Server, Db2
概覽
讓 AI 助理以受保護的唯讀方式存取 PostgreSQL、MySQL、ClickHouse、Oracle、SQL Server、Db2 與 SQLite 資料庫。
- 功能
- 提供 29 個 db_* 工具,用來列出連線、目錄、結構描述、資料表、欄位、檢視表、索引與關聯,並驗證、執行與解讀唯讀查詢。也能對資料表做剖析、搜尋值與中繼資料、推斷關聯、檢閱結構描述並產生 Markdown 資料字典。聯邦工具可跨連線執行單一語句,或在兩個連線間做有界雜湊聯結。每個語句都會先被解析,且必須是單一讀取;寫入會被拒絕。
- 適用情境
- 當助理需要探索、記錄或查詢既有關聯式資料庫,且完全不能有寫入風險時使用。適合跨多種引擎的結構描述探索、資料剖析與唯讀報表,包括隔離網路環境。
- 執行需求
- 本機 Python 3.12 執行環境(虛擬環境;不接受 pip install --user 或僅靠 PYTHONPATH 的方式)或容器映像。需要宣告連線的 YAML 設定,憑證透過 username_file、password_file 等檔案提供,並以絕對路徑 UDBMCP_CONFIG 指定設定位置。需要資料庫驅動程式與到各資料庫的網路存取;容器映像不含 SQL Server 驅動程式。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Universal DB (read-only),將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
universal-db-mcp
[CI] [OpenSSF Scorecard] [license: Apache-2.0] [python: 3.12] [MCP: 29 tools] [databases: 8] [access: read-only] [works with: Claude · Cursor · VS Code]
Quick start · Tools · Security model · Offline install · Docs · Landing page · Report a vulnerability
Give AI agents read-only access to your databases, safely. universal-db-mcp is an MCP server that lets Claude Code, Cursor, VS Code or any MCP client discover, document, profile, search and query the databases you declare, and nothing else. Every statement is parsed before it runs and must be a single read; it runs on a read-only session, columns that look sensitive are masked, and every call is audited. Writes are refused, not discouraged. The server never calls an LLM, sends no telemetry and installs nothing at runtime, so it also runs on networks with no internet access at all.
Status: hardened through a production security review and three follow-up
code reviews (2026-09/10). IMPLEMENTATION_STATUS.md is the honest ledger of
what is implemented, what is verified and how, and what is still open; claims
here are limited to what its gates and test-evidence/ demonstrate.
What it does
Engines (each version below passes the version matrix,
scripts/version_matrix/, results in test-evidence/version-matrix/):
29 tools (docs/tools.md is the contract):
- Connections:
db_list_connections,db_test_connection,db_get_capabilities. - Catalog:
db_list_catalogs,db_list_databases,db_list_schemas,db_list_tables,db_get_table,db_list_columns,db_list_views,db_list_synonyms,db_list_routines,db_list_indexes,db_get_relationships,db_get_statistics,db_search_metadata,db_get_catalog. - Reading data:
db_validate_query,db_query,db_sample_table,db_explain(plans, never executions),db_get_query_history. - Discovery, review and documentation:
db_profile_table,db_search_values(find a value across tables and connections without writing SQL),db_infer_relationships,db_review_schema(prioritized optimization findings),db_document_schema(Markdown data dictionary). - Federated reads:
db_federated_query(one statement, or one per connection, merged) anddb_federated_join(a bounded hash join across two connections).
How it keeps the databases safe
Defence in depth; details and limitations in docs/security.md and
docs/session-safety.md.
- The database login is the primary control. Give every connection a
SELECT-only login limited to the schemas you list in
allowed_schemas. The one exception is Db2'sdb_explain, which writes its plan rows into the explain tables a DBA provisions, reads them back and deletes them: that login also needs INSERT, SELECT and DELETE on those tables, and only there (Oracle's plans go to the session-privatePLAN_TABLE, which needs no grant). Column-level grants or views are the real protection for sensitive columns. - Read-only sessions. On by default and enforced by the server itself on
PostgreSQL, MySQL/MariaDB, ClickHouse and SQLite; Db2 runs at
URand SQL Server atREAD UNCOMMITTED, so reads take no share locks. There is no write mode:security.read_only: false,allow_write_operations: trueand a connection'sread_only: falseare rejected when the config loads. Every session is also pinned to the settings that decide how its server lexes a statement (MySQLsql_mode, PostgreSQLstandard_conforming_strings, SQL ServerQUOTED_IDENTIFIER, ...), so the server reads exactly what the guard parsed. - The SQL guard parses every statement in the connection's dialect and
accepts one read statement only; anything it cannot parse is refused.
Under a non-empty
allowed_schemas, every table must be schema-qualified (SELECT * FROM ocean.buoys, notSELECT * FROM buoys), because the engine would otherwise choose the schema. On Oracle, Db2 and PostgreSQL, CTE names and unquoted table names must be ASCII. Views that show other sessions' SQL, column statistics or stored credentials are refused whateverallowed_system_schemasopens; Oracle'sSYS.DUALand Db2'sSYSIBM.SYSDUMMY1toSYSDUMMY4are always readable. Bound parameters reach the driver exactly as validated. - Masking that refuses what it cannot prove. Columns matching the
sensitive patterns (built in, plus
security.mask_columns) are masked by where each output value comes from. A statement over a table with masked columns is accepted only in shapes the analysis fully proves (columns, expressions, aggregates, window functions, joins, CTEs, subqueries, unions,*over listed tables); anything else is refused before it runs, with the construct named. Predicates are not masked: aWHEREon a masked column can still narrow results. - Bounded, sanitized, audited. Row, byte, cell and time ceilings; a
per-query memory cap on ClickHouse (2 GiB by default,
options.max_memory_usage); size caps checked before any parsing; driver error text sanitized. Every call is audited, by default to the platform's state directory (/var/log/universal-db-mcp/audit.jsonlfor the service's config,%ProgramData%\UniversalDB MCP\logs\audit.jsonlon Windows,~/.universal-db-mcp/audit.jsonlfor a per-user config). - stdio is not a security boundary. A stdio registration runs the server
as your user inside the agent, so an agent that can run shell commands or
read files can read the credentials in
~/.universal-db-mcp/secrets/and connect directly, outside the guard. Use SELECT-only logins, or run the server in HTTP mode (bearer token, behind your reverse proxy) under a separate service account.
Quick start
From source
Register the server with your agents with .venv/bin/udbmcp configure-agents
(Claude Code, Claude Desktop, Cursor, VS Code, Cline and others;
docs/claude-code-integration.md). It writes the launch command with
python -I (isolated mode), so the package and its dependencies must be
installed in a virtual environment, as above; pip install --user or
PYTHONPATH-only setups are refused. It registers the system config
(/etc/universal-db-mcp/config.yaml, on Windows
%ProgramData%\UniversalDB MCP\config.yaml) when your user can read it,
otherwise the per-user ~/.universal-db-mcp/config.yaml; export an absolute
UDBMCP_CONFIG first to choose another. The .deb ships the system config
readable by every user, so on a .deb host make it root:udbmcp 0640 first
(docs/claude-code-integration.md).
udbmcp add-connection adds a connection interactively and stores its
secrets with private permissions; udbmcp doctor checks a config, its
secrets and (with --connectivity) every database.
With the container image
It is listed in the official MCP Registry
as io.github.alghanim/universal-db-mcp, so clients that browse the registry
can install it. Mount your config and its secrets read-only and run it over
stdio or HTTP as docs/offline-deployment.md (Container mode) describes. The image has no SQL
Server driver; the same section shows how to add Microsoft's.
A minimal connection
config.example.yaml documents every setting, per engine.
Install offline (air-gapped sites)
See docs/offline-deployment.md, and docs/site-upgrade-runbook.md for a
site that installs from a release stick (scripts/package/release_usb.sh
builds one). Short version:
Nothing from a bundle or stick runs before its Ed25519 signature is checked
against the installed release key. The installers refuse a bundle whose
signed release_seq is older than the installed release unless you ask for
the downgrade: --allow-downgrade for the scripts, UDBMCP_ALLOW_DOWNGRADE=1
for the .deb, a one-shot flag file the .pkg names, and
UDBMCP_ALLOW_DOWNGRADE=1 for one of this release's MSIs after uninstalling
the newer one (Windows Installer refuses any older MSI over a newer install).
In container mode, scripts/load_images_offline.sh keeps a root-owned release
record (/var/lib/universal-db-mcp/release.json) and refuses an older bundle
the same way.
Verification
- Tests: over 12,000 unit tests, run by GitHub Actions CI on
ubuntu-24.04 and locally on macOS; ruff and
mypy --strictclean.IMPLEMENTATION_STATUS.md(section 3f) records the latest counts. - Real databases: the version matrix above, and
scripts/live_evidence.pyagainst the mock databases ofscripts/fixtures/start_mock_dbs.sh(docs/mock-environment.md). - Packages: the
.deband.pkgrelease gates and the offline upgrade gate (docs/acceptance-tests.md). - Supply chain: pinned, hash-checked locks for every platform, checked with pip-audit.
- Fuzzing: the SQL guard is fuzzed with Atheris (
tests/fuzz/) after each push tomainand weekly: any input it neither accepts nor refuses cleanly fails the run.
Not yet verified anywhere: the MSI on a real Windows host and a real macOS
Installer run of the .pkg.
Development
Tests that use the local mock databases run only with
UDBMCP_LIVE_FIXTURES=1, so a package gate never waits on a paused or absent
database; the real-dpkg container sequences run only with
UDBMCP_DOCKER_TESTS=1. The bundle-builder tests need pip in the venv: after
uv sync, run
uv pip install --python .venv/bin/python --require-hashes -r .github/ci-pip-requirements.txt.
CI. .github/workflows/ci.yml is a GitHub Actions workflow (ubuntu-24.04,
CPython 3.12): the unit suite (including the MSI custom-action tests under
pwsh), ruff, mypy --strict, prepare_offline_bundle.py --check-locks, and
pip-audit over every lock. Actions are pinned to commit SHAs. It runs on
every pull request and every push to main, in two jobs at once: the slowest
installer and packaging test files run in installer-tests, and checks
runs the rest and every other check. .github/workflows/audit.yml runs the
same pip-audit every week, so a new advisory fails a run between commits too.
Dependabot proposes grouped updates monthly.
tests/unit/test_hardening_2026_09_27_ci_hygiene.py guards the CI setup
itself (pinned actions, pytest options, the two jobs together running every
test once, no skips or hooks hidden in conftests or helpers, no compiled or
symlinked files in the tree); it is a tripwire, not a sandbox, so changes to
conftests, test helpers and CI files still need a reviewer. After a
Dependabot bump of requirements/runtime.in, refresh and review the locks
(docs/offline-build.md).
Documentation map
Reporting a vulnerability
Please report security issues privately through GitHub private vulnerability
reporting, never in a public issue. SECURITY.md says what to include and
how fixes reach air-gapped sites. The project is maintained by the
universal-db-mcp maintainers and publishes no e-mail address: the one in the
.deb's Maintainer field, which Debian requires, is a placeholder under the
reserved .invalid domain and reaches no one.
License
Apache-2.0. See LICENSE and NOTICE. Both ship in the wheel and in the
offline bundle's licenses/ directory; the .deb states the license in its
DEP-5 /usr/share/doc/universal-db-mcp/copyright file, with NOTICE beside
it. Third-party components keep their own licenses: the bundle lists them in
sbom/cyclonedx.json, and each wheel in its wheelhouse/ carries its license
files.
The Db2 connector's ibm_db wheel contains IBM Data Server Driver for ODBC
and CLI redistributables, which IBM licenses for distribution as part of an
application. They ship unmodified, with IBM's license and notice files,
which govern them (see NOTICE). Db2 and IBM are trademarks of International
Business Machines Corporation, used here only to name the database and its
driver. Microsoft's ODBC Driver for SQL Server and Oracle's Instant Client are
not redistributed: sites install them from the vendor.
來源:README.md,提交 ae0989b
工具
0版本歷史
1- v0.1.0最新Oct 9, 2026

