MCP server · 41 tools · eight engines · AGPL-3.0

MCP server for SQL databases

One SQL MCP server for eight database engines

Postgres, Oracle, SQL Server, MySQL, H2, DuckDB, SQLite and dp-lake behind one MCP endpoint — read-only by default, one scoped key per agent, every call written to an audit log. Self-hosted, AGPL-3.0.

Don't point an agent at production with write credentials

The fast way to give a coding agent database access is to paste a connection string into a config file. It works on the first afternoon and creates four problems you keep.

  • The credential can write. Most database logins that can read a table can also drop it. An agent that misreads a schema does not need bad intent to do damage.
  • Database passwords sprawl across laptops. Every developer's MCP config is another copy, in plain text, outside any inventory.
  • Revoking one person means rotating a shared password — and then finding every config that held it.
  • There is no audit trail. The database sees one login. It cannot tell you which agent, on whose behalf, ran what.

This server is the other shape: the credentials live in the deployment, the agent gets a key, and the key is the thing you scope, revoke and audit.

What "governed" means here

Read-only by default, scoped keys, every call audited

Read-only is enforced, not advisory

A datasource flagged read-only refuses the three write-shaped uses in the pipeline contract — a DML node's source, a DDL node's source, and any node writing its output back to a datasource. The check runs at save time and again at execution time against the live row, so flipping the flag takes effect on the next run, not on the next cache expiry.

And the credential still does the real work

The flag is contract, not containment: the documented pattern is a SELECT-only database user for any datasource whose data must not change. The flag gives the agent a fast, machine-readable refusal; the credential gives the guarantee. The demo's own datasources have both.

One scoped key per agent

Keys are shown once, stored Argon2id-hashed, pinned to one workspace, and carry hierarchical scopes — read, execute, author (admin is for people, never issued to a key). A key's scopes can never exceed its creator's at issue time.

Revocation is a checkbox, not a rotation

Revoke one agent's key and that agent stops working within about a minute — the validation cache's TTL. No shared password to rotate, and nobody else is interrupted.

Every tool call is audited

The dispatcher writes mcp.tool.called for every call and mcp.tool.write for every mutating one, into the same audit log that carries logins, key issuance and datasource decryptions.

API keys only on /mcp

The endpoint accepts DP-API-Key or Authorization: Bearer dpk_… and rejects browser session cookies outright. A browser-embedded MCP client authenticates like any other agent — there is no cookie path to borrow.

Credentials never sit on a laptop

Datasource passwords are AES-256-GCM encrypted in the metadata database with the datasource name bound as additional authenticated data, and the app refuses to start without a valid key.

Cross-database joins land nothing

A pipeline that reads across engines stages each result set into an in-memory database created for that one execution, joins there, and destroys it when the execution ends. How the staging join works.

Pick your engine

Connect Claude Code to Postgres, Oracle, SQL Server, MySQL, H2, DuckDB, SQLite and dp-lake

One server speaks all eight. Each page carries that engine's dialect constant, its JDBC driver and license, whether the driver ships in the published image, and the client config to paste.

Postgres MCP server

POSTGRES · org.postgresql:postgresql

Driver ships in the published image

MySQL MCP server

MYSQL · com.mysql:mysql-connector-j

Driver user-supplied — GPL-2.0 with FOSS exception

Oracle MCP server

ORACLE · com.oracle.database.jdbc:ojdbc11

Driver user-supplied — OTN

SQLite MCP server

SQLITE · org.xerial:sqlite-jdbc

Driver ships in the published image

DuckDB MCP server

DUCKDB · org.duckdb:duckdb_jdbc

Driver ships in the published image

H2 MCP server

H2 · com.h2database:h2

Driver ships in the published image

The surface

The 41 MCP tools an agent gets

Discovery, authoring, execution and result reading — the full lifecycle. 25 of them read; 16 can write, and those are the ones the audit log flags with mcp.tool.write.

Pipelines — author, run, inspect

7 tools — every name, its scope and whether it writes is listed on the tools page.

Templates — the SQL an agent writes

7 tools — every name, its scope and whether it writes is listed on the tools page.

Datasources — what the agent may see

8 tools — every name, its scope and whether it writes is listed on the tools page.

dp-lake — tables over your bucket

3 tools — every name, its scope and whether it writes is listed on the tools page.

The SQL probe

1 tools — every name, its scope and whether it writes is listed on the tools page.

Executions — results and cancellation

4 tools — every name, its scope and whether it writes is listed on the tools page.

Published endpoints

4 tools — every name, its scope and whether it writes is listed on the tools page.

Calculators

2 tools — every name, its scope and whether it writes is listed on the tools page.

docs

2 tools — every name, its scope and whether it writes is listed on the tools page.

semantics

3 tools — every name, its scope and whether it writes is listed on the tools page.

All of them over one endpoint: POST {host}/mcp, Streamable HTTP, stateless by default.

Read the MCP server specification →

Where to go next

Asked before

The MCP server, in questions

Which databases can one MCP server reach?

Postgres, Oracle, SQL Server, MySQL, H2, DuckDB, SQLite and dp-lake — one MCP endpoint over all eight, each with its own dialect adapter, and any of them marked read-only where writes must never happen. The dialect catalog with drivers and licenses is docs/datasources.md §4.

Does the agent ever see a database password?

No. Datasource credentials are encrypted at rest in the metadata database and never returned — not through a tool, not through the UI, not in a pipeline's JSON. The agent holds a key to the server; the server holds the credentials. Credential storage is docs/datasources.md §7.

What stops a write against a read-only source?

The datasource's read-only flag refuses the write-shaped uses — a DML node's source, a DDL node's source, writing a node's output back — at save time and again at execution against the live row, and the documented pattern pairs it with a SELECT-only database user. The flag's semantics are docs/datasources.md §5.7.

How do I revoke one agent?

Revoke its key — one checkbox, and the agent stops working within about a minute, the validation cache's TTL. No shared password to rotate, and nobody else's key is touched. Revocation and the validation cache are docs/auth.md §11.4.

Is every tool call audited?

Yes: the dispatcher writes mcp.tool.called for every call and mcp.tool.write for every mutating one, into the same audit log that carries logins and key issuance — with the key and the tool, never the SQL text or the row data. The audit log is docs/auth.md §10.

Point your agent at the demo first

One command brings up the server, the demo sources and the pipelines that join them. The afternoon you spend on the demo is the cheapest way to find out what governed agent access feels like.