Postgres MCP server — agent-first database workbench
Project description
Tabulus
A Postgres MCP server built for AI agents.
Tabulus is the database workbench for the AI-augmented developer. Connect Claude Code, Cursor, or any MCP-compatible client to your Postgres database and let the agent introspect the schema, sample data, and write safe queries — without copy-pasting schemas into chat windows.
Why
Every modern dev workflow now includes an AI agent. Every DB GUI was designed before that was true. Tabulus flips the model: the agent is a first-class user, not a sidebar feature.
What that means in practice:
- Schema introspection optimized for LLM context windows (compact JSON, foreign keys flattened, sample rows inline).
- Read-only by default —
INSERT/UPDATE/DELETE/DDLare rejected at the gateway. The agent can't drop your tables. EXPLAINexposed as a tool so the agent can reason about query plans before proposing optimizations.- Statement timeout + row cap enforced server-side. No agent can DOS your database by accident.
- Opt-in PII redactor (
TABULUS_REDACT=on) scrubs emails, API keys, JWTs, credit cards, phones, and IPs from tool output before the agent sees them.
Status
v0.0.1 — alpha. Postgres only. Stdio MCP transport only. No GUI yet.
Install
pip install tabulus
Run
export DATABASE_URL=postgres://user:pass@host:5432/dbname
tabulus
Then point your MCP client at the tabulus command.
Claude Code (project-level)
Create .mcp.json in your project root:
{
"mcpServers": {
"tabulus": {
"command": "tabulus",
"args": [],
"env": {
"DATABASE_URL": "postgres://user:pass@host:5432/dbname"
}
}
}
}
Restart Claude Code in that directory and approve the trust prompt.
Claude Code (user-level via CLI)
claude mcp add tabulus "$(which tabulus)" --env DATABASE_URL=postgres://user:pass@host:5432/dbname
Cursor
Add to ~/.cursor/mcp_servers.json:
{
"mcpServers": {
"tabulus": {
"command": "tabulus",
"env": { "DATABASE_URL": "postgres://user:pass@host:5432/dbname" }
}
}
}
Tools
| Tool | Description |
|---|---|
list_tables |
All tables with row count estimates + sizes |
describe_schema |
Columns, PK, FKs, indexes, sample rows for a table |
sample_rows |
Random sample from a table |
safe_select |
Run a read-only SELECT (write keywords rejected) |
explain |
Get query plan (EXPLAIN FORMAT JSON) |
Configuration
| Variable | Default | Purpose |
|---|---|---|
DATABASE_URL |
— (required) | Postgres connection URL |
TABULUS_MAX_ROWS |
100 |
Hard cap on rows returned by any tool |
TABULUS_SAMPLE_SIZE |
3 |
Sample rows included in describe_schema |
TABULUS_STATEMENT_TIMEOUT_MS |
5000 |
Server-side query timeout |
TABULUS_REDACT |
off |
Set on to scrub PII (emails, API keys, JWTs, credit cards, phones, IPs) from sample_rows, safe_select, and describe_schema output before the agent sees it. Recommended for production. |
TABULUS_ALLOW_WRITES |
false |
Set true to disable the write block (NOT recommended) |
Roadmap
- v0.1 — Postgres parity, polished install
- v0.2 — SQLite adapter
- v0.3 — MySQL / MariaDB adapter
- v0.x — Tauri desktop GUI shell on top of the same core
- v1.0 — Stable, cross-platform, multi-DB
License
MIT. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tabulus-0.0.2.tar.gz.
File metadata
- Download URL: tabulus-0.0.2.tar.gz
- Upload date:
- Size: 13.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d35437a8c231e785b15a136e675a3fd215c2fd443b647d4beb1886642af871a
|
|
| MD5 |
7db6024b4b71dc2b31ff4fd29cff4a30
|
|
| BLAKE2b-256 |
825dc5d78e0d40dc01b2876ca7ae03c3e1dca04747b6afb08a9ce44870ba257e
|
Provenance
The following attestation bundles were made for tabulus-0.0.2.tar.gz:
Publisher:
publish.yml on WalkingMountain/tabulus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tabulus-0.0.2.tar.gz -
Subject digest:
4d35437a8c231e785b15a136e675a3fd215c2fd443b647d4beb1886642af871a - Sigstore transparency entry: 2006636572
- Sigstore integration time:
-
Permalink:
WalkingMountain/tabulus@3e3e5e2c46837fcba14f299030a862e99c78d7cb -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/WalkingMountain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3e3e5e2c46837fcba14f299030a862e99c78d7cb -
Trigger Event:
push
-
Statement type:
File details
Details for the file tabulus-0.0.2-py3-none-any.whl.
File metadata
- Download URL: tabulus-0.0.2-py3-none-any.whl
- Upload date:
- Size: 3.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b88cef9a7347158a75052c98c40f995473e34990b4fa54c6c1926e9517120265
|
|
| MD5 |
51994bc3798f13f5eca3989bc41d80a9
|
|
| BLAKE2b-256 |
323276a9954e163a60e2caee07df54ddb30aa9b87055812923f6d34e116b1d29
|
Provenance
The following attestation bundles were made for tabulus-0.0.2-py3-none-any.whl:
Publisher:
publish.yml on WalkingMountain/tabulus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tabulus-0.0.2-py3-none-any.whl -
Subject digest:
b88cef9a7347158a75052c98c40f995473e34990b4fa54c6c1926e9517120265 - Sigstore transparency entry: 2006636749
- Sigstore integration time:
-
Permalink:
WalkingMountain/tabulus@3e3e5e2c46837fcba14f299030a862e99c78d7cb -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/WalkingMountain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3e3e5e2c46837fcba14f299030a862e99c78d7cb -
Trigger Event:
push
-
Statement type: