sqlmate-mcp
by adamrpostjr
README.md
<div align="center">
# ποΈ sqlmate-mcp
### Give Claude a database. Give yourself a GUI.
**Zero-config SQL database [MCP](https://modelcontextprotocol.io) server with a live browser GUI β for Claude Code, Zed, and any MCP client.**
Point it at your project, and Claude can explore your **MySQL Β· MariaDB Β· SQLite Β· MSSQL Β· PostgreSQL** databases while _you_ browse, edit, and query them in a beautiful browser dashboard that updates in real time.
<br>
[](https://nodejs.org)
[](https://modelcontextprotocol.io)
[](LICENSE)
[](https://www.npmjs.com/package/sqlmate-mcp)
<br>
```bash
npm install -g sqlmate-mcp
claude mcp add --transport stdio sqlmate-mcp sqlmate-mcp
```
_That's the whole setup. It reads your existing `.env` β no config files to write._
<br>
<img src="docs/screenshots/overview.png" alt="sqlmate-mcp browser GUI β paginated data grid with a live feed of Claude's tool calls" width="100%">
</div>
---
## β¨ Why sqlmate-mcp?
Most database MCP servers give the AI tools and leave **you** in the dark. sqlmate-mcp does both halves:
- π€ **For Claude** β 9 focused tools to inspect schemas, run queries, and make guarded writes.
- π **For you** β a browser GUI (run once as a background daemon, not per session) so you can watch what the agent touches, edit data by hand, and run your own SQL side by side.
No API keys. No cloud. No `node-gyp`. It reads the config you already have.
---
## π Features
| | |
|---|---|
| β‘ **Zero config** | Reads `DB_*` vars or `DATABASE_URL` straight from your project's `.env` |
| π **5 databases** | MySQL, MariaDB, SQLite, MSSQL, and PostgreSQL from one server |
| π§ **Schema intelligence** | `get_schema` returns every table's columns, PKs, foreign keys, and indexes in a single call |
| π **Query plans** | `explain_query` returns the execution plan without running your statement β opt into `analyze` for real timing |
| π‘οΈ **Write safety** | DELETE/UPDATE without `WHERE`, `DROP`, and `TRUNCATE` require explicit confirmation |
| π₯οΈ **Browser GUI** | Paginated grid, inline cell editing, row delete, schema view, and a SQL editor with EXPLAIN + timing |
| πΈοΈ **ERD visualizer** | Interactive entity-relationship diagram per connection, with foreign-key edges and click-to-open tables |
| ποΈ **Unified dashboard** | Open several projects at once and see them all in one GUI, grouped by project |
| π‘ **Live agent feed** | Watch every MCP tool call stream into the browser in real time |
| πͺΆ **No native builds** | SQLite uses Node's built-in `node:sqlite` β nothing to compile |
---
## π¦ Setup
### 1. Install
```bash
npm install -g sqlmate-mcp
```
### 2. Register with your editor
<details open>
<summary><b>Claude Code</b></summary>
```bash
claude mcp add --transport stdio sqlmate-mcp sqlmate-mcp
```
</details>
<details>
<summary><b>Zed</b></summary>
Open your Zed `settings.json` (<kbd>Cmd/Ctrl</kbd> + <kbd>,</kbd>) and add:
```json
{
"context_servers": {
"sqlmate-mcp": {
"command": "sqlmate-mcp",
"args": [],
"env": {}
}
}
}
```
To pin a specific project's database, set `SQLMATE_PROJECT_ROOT` in the `env` block:
```json
{
"context_servers": {
"sqlmate-mcp": {
"command": "sqlmate-mcp",
"args": [],
"env": { "SQLMATE_PROJECT_ROOT": "/absolute/path/to/your/project" }
}
}
}
```
The sqlmate-mcp tools then appear in the Zed Agent Panel.
</details>
### 3. That's it
sqlmate-mcp reads connections from the **root of whichever project you open** (the directory you launch your editor from). Each project uses its own `.env` or `.sqlmaterc` β no global config. See [Connection Setup](#-connection-setup).
---
## π§ Connection Setup
sqlmate-mcp reads connections from your **project root** at startup (defaults to `cwd`, override with `SQLMATE_PROJECT_ROOT`).
### Option 1 β `.env`
Laravel-style variables:
```env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secret
```
Or a connection URL:
```env
DATABASE_URL=mysql://root:secret@127.0.0.1:3306/myapp
DATABASE_URL=sqlite:///relative/path/app.db
DATABASE_URL=sqlserver://sa:pass@localhost:1433/master
DATABASE_URL=postgres://postgres:secret@127.0.0.1:5432/myapp
```
Supported schemes: `mysql`, `mariadb`, `sqlite`, `sqlserver` / `mssql`, `pgsql` / `postgres` / `postgresql`.
### Option 2 β `.sqlmaterc`
A JSON array of connection objects in your project root:
```json
[
{ "name": "Local MySQL", "type": "mysql", "host": "127.0.0.1", "port": 3306, "username": "root", "password": "", "database": "myapp" },
{ "name": "App SQLite", "type": "sqlite", "path": "./database/app.db" },
{ "name": "Local Postgres", "type": "postgres", "host": "127.0.0.1", "port": 5432, "username": "postgres", "password": "", "database": "myapp" }
]
```
A copy-paste starting point lives in [`docs/sqlmaterc-example.json`](docs/sqlmaterc-example.json).
---
## π οΈ MCP Tools
| Tool | Description |
|------|-------------|
| `list_connections` | List all detected connections (id, name, type, source) |
| `add_connection` | Add a connection for the session via URL, config file, or params |
| `list_tables(connectionId)` | List table names for a connection |
| `describe_table(connectionId, table)` | Column names, types, nullability, and primary key info |
| `get_schema(connectionId, [table])` | Full schema graph β columns, PKs, foreign keys, and indexes |
| `run_query(connectionId, sql)` | Run a read-only query (SELECT, EXPLAIN, SHOW, PRAGMA) |
| `explain_query(connectionId, sql, [analyze])` | Return the execution plan; `analyze` runs read-only statements for real timing |
| `run_write(connectionId, sql)` | Run an INSERT, UPDATE, DELETE, or DDL statement |
| `dump_database(connectionId, [tables], [mode], [output], [gzip])` | Write a restorable `.sql` backup (schema + data) to disk β pure JS, no `mysqldump`/`pg_dump` needed |
> `run_write` runs a risk assessment first. Operations affecting all rows (no `WHERE`), `DROP`, `TRUNCATE`, or `ALTERβ¦DROP COLUMN` pause and ask Claude to confirm with `confirm: true` before proceeding.
> `dump_database` is meant to be called before risky writes or migrations. The dump goes to `.sqlmate/dumps/<connection>-<timestamp>.sql` in your project (a `.sqlmate/.gitignore` keeps it out of git) and only the file path and row counts are returned to Claude. Example: *"Back up the `orders` and `customers` tables, gzipped, before running this migration"* β `dump_database({ connectionId: "app", tables: ["orders", "customers"], gzip: true })`. MySQL, Postgres and SQLite dump from a consistent snapshot; MSSQL is best-effort. Views, routines and triggers are not included (SQLite triggers are).
---
## π₯οΈ Browser GUI
Available at **`http://localhost:4737`** once the [GUI daemon](#run-the-gui-as-a-standalone-daemon) is running.
- π Browse any table with a paginated data grid
- βοΈ Click a cell to edit it inline; delete rows with the trash icon
- π Toggle between data view and column schema view
- π¬ Run arbitrary SQL in the built-in editor, with **Explain** for the plan and per-query timing
- πΈοΈ Visualize a database as an interactive **ERD** β PK/FK badges, relationship edges, click-to-open
- π Reconnect a database without restarting the server
- π‘ Watch a live feed of every MCP tool call Claude makes
<table>
<tr>
<td width="50%"><img src="docs/screenshots/sql-editor.png" alt="Built-in SQL editor with query results, timing, and an Explain button"><br><sub><b>SQL editor</b> β run queries with EXPLAIN and per-query timing</sub></td>
<td width="50%"><img src="docs/screenshots/schema.png" alt="Column schema view showing types, nullability, and primary keys"><br><sub><b>Schema view</b> β columns, types, nullability, and keys</sub></td>
</tr>
</table>
<img src="docs/screenshots/erd.png" alt="Interactive entity-relationship diagram with foreign-key edges and a minimap" width="100%">
<sub><b>ERD visualizer</b> β an interactive diagram of every table and its relationships</sub>
---
## ποΈ Multiple Projects, One Dashboard
Open your editor in more than one project at a time and each runs its own sqlmate-mcp process β but you only ever see **one** browser GUI, showing **all** projects at once.
- The sidebar groups connections by project (each labeled with its host/database); open tables, run SQL, and view ERDs across projects side by side. The live feed spans every project, labeled by project.
- Every MCP process is **attach-only**: it never binds the GUI port itself and never opens a browser tab. It just registers its connections with whatever GUI is already running and streams its tool activity into the live feed.
This means the GUI's lifetime is decoupled from any single editor session β see below.
### Run the GUI as a standalone daemon
Instead of a browser tab popping up (and a new host getting elected) every time an editor session starts, run the GUI once as its own long-lived process and let every sqlmate-mcp process just attach to it:
```bash
sqlmate-mcp gui # start the GUI daemon, opens the browser once
sqlmate-mcp gui --install-autostart # (Windows) start it automatically at login
sqlmate-mcp gui --uninstall-autostart # remove the login item
```
- If no daemon is running, an MCP process just logs a hint to stderr and keeps working without a GUI β it retries attaching in the background every 30s, so starting the daemon later (or after it restarts) picks the session back up without restarting your editor.
- Running `sqlmate-mcp gui` again while one is already running just opens the browser to the existing instance instead of erroring.
- `--install-autostart` drops a hidden startup shortcut (`%APPDATA%\...\Startup\sqlmate-gui.vbs`) that launches `sqlmate-mcp gui` at login with no visible console window. If the project lives on a drive that isn't attached yet at login (a mapped or slow-to-mount drive), it waits β checking every 3s, up to 5 minutes by default β instead of failing silently. Override with `--max-wait=<seconds>`, e.g. `sqlmate-mcp gui --install-autostart --max-wait=60`.
Fully optional β without it, sqlmate-mcp behaves as a normal attach-only client and simply runs with no GUI until you start one.
---
## βοΈ Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `SQLMATE_PROJECT_ROOT` | `cwd` | Directory to search for `.env` and `.sqlmaterc` |
| `SQLMATE_PORT` | `4737` | Port for the browser GUI |
| `SQLMATE_NO_OPEN` | β | Set to `1` to skip auto-opening the browser |
---
## π§βπ» Development
```bash
git clone https://github.com/adamrpostjr/sqlmate-mcp.git
cd sqlmate-mcp
npm install
npm run build # builds the Svelte GUI into /public
node src/index.js # start the backend (serves the GUI at :4737)
cd frontend && npm run dev # frontend hot-reload (proxies /api to :4737)
```
The frontend is **Svelte 5 + Vite + Tailwind**. Production build output goes to `/public`, served statically by Express. Backend is pure Node.js ES modules β no TypeScript, no build step.
---
## π Requirements
- **Node.js β₯ 22.5** (for the native `node:sqlite` module)
---
<div align="center">
## π License
[MIT](LICENSE) Β· Built by [Adam Post](https://github.com/adamrpostjr)
**If sqlmate-mcp saves you a trip to a database client, consider giving it a β**
</div>
TDQS
A4/5.0
Scored across 6 tools
Disambiguation5/5
Each tool addresses a distinct operation: connection setup, schema inspection, connection listing, table listing, read-only queries, and write queries. No functional overlap exists.
Naming Consistency5/5
All tool names follow a consistent 'verb_noun' pattern using snake_case (e.g., describe_table, run_query), making the API predictable and easy to navigate.
Tool Count5/5
With 6 tools, the surface is well-scoped for a database management tool, covering essential tasks without being overly minimal or bloated.
Completeness4/5
The set covers core CRUD and schema inspection, but lacks connection management operations (e.g., remove, update) and support for other database objects like views or stored procedures, which are minor gaps.
Maintenance
ActivityMaintained
ResponsivenessNo issues