Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Steward

FreeNot checked

MCP server giving AI agents unified access to PostgreSQL, MySQL, and SQLite.

GitHubEmbed

About

MCP server giving AI agents unified access to PostgreSQL, MySQL, and SQLite.

README

Read-only-by-default database access for AI agents, over MCP.

A self-contained MCP server that lets Claude Code (and any other MCP-compatible agent) talk to PostgreSQL, MySQL, and SQLite. Single static binary, stdio transport, read-only by default.

Features

Feature Description
Three engines PostgreSQL, MySQL/MariaDB, SQLite — all through sqlx with rustls (no native deps)
Two-layer safety sqlx after_connect session toggle + sqlparser AST guard with LIMIT injection
Typed rows Results returned as a closed Value enum (Int/Float/Text/Bool/Bytes/Json) — not stringified
Secrets OS keychain via the keyring crate (service dev.skydiver.db-mcp)
Interactive CLI Wizard-driven profile add validates the connection before persisting anything

Quick Start

# Build
make

# Add a profile (interactive wizard)
./dist/db-mcp profile add

# List profiles
./dist/db-mcp profile list

# Run the MCP server over stdio
./dist/db-mcp serve

Wire it into Claude Code

The fastest path is the CLI:

# Project-scoped (writes .mcp.json at the repo root, shared with the team)
claude mcp add db /absolute/path/to/db-mcp serve --scope project

# Local to the current project for just your user (.claude/settings.local.json)
claude mcp add db /absolute/path/to/db-mcp serve --scope local

# Or globally for every project
claude mcp add db /absolute/path/to/db-mcp serve --scope user

Or hand-roll a project-scoped .mcp.json at the repo root:

{
  "mcpServers": {
    "db": {
      "command": "/absolute/path/to/db-mcp",
      "args": ["serve"]
    }
  }
}

Then approve it in .claude/settings.local.json:

{
  "enabledMcpjsonServers": ["db"]
}

Skip the permission prompts

Allow every db-mcp tool without confirmation by adding a wildcard to .claude/settings.local.json:

{
  "permissions": {
    "allow": ["mcp__db__*"]
  }
}

MCP Tools

Tool Purpose
list_profiles Enumerate configured profiles (no secrets returned)
connect Open or reuse a pool for a profile (idempotent)
disconnect Close a pool
list_schemas Schemas (Postgres/MySQL) or ["main"] for SQLite
list_tables Tables in a schema with cheap row-count estimates
describe_table Columns: name, data type, nullability, primary key
execute_query Parse, validate, inject LIMIT, run; returns typed rows
explain_query EXPLAIN the given query

Safety

Read-only is enforced in two layers:

  1. Session level — sqlx after_connect sets default_transaction_read_only (Postgres), SESSION TRANSACTION READ ONLY (MySQL), or PRAGMA query_only (SQLite).
  2. App levelsqlparser parses every query, rejects writes/DDL/multi-statement, and injects a LIMIT when none is present.

Writes require both read_only = false on the profile and --allow-writes when starting the server.

Development

Prerequisites

rustup install stable    # Rust 1.85+ (2024 edition)

Commands

Command Description
make Release build into dist/db-mcp
make dev cargo run
make test Unit tests + SQLite integration tests
make integration-test Postgres + MySQL container tests (requires Docker running)
make clean Remove cargo artifacts and dist/

Project Structure

db-mcp/
├── src/
│   ├── cli.rs           # clap CLI + interactive profile wizard
│   ├── config.rs        # profiles.toml schema + IO
│   ├── secrets.rs       # OS keychain via `keyring`
│   ├── manager.rs       # ConnectionManager: profile → Arc<ActiveConnection>
│   ├── mcp/             # rmcp stdio server + tool router
│   └── db/
│       ├── postgres.rs  # sqlx adapter (rustls, SSL modes)
│       ├── mysql.rs     # sqlx adapter
│       ├── sqlite.rs    # sqlx adapter (mode=ro, PRAGMA query_only)
│       └── readonly.rs  # sqlparser AST guard + LIMIT injection
├── tests/               # SQLite + Postgres + MySQL integration tests
├── Makefile             # Build targets
└── dist/                # Build output (gitignored)

Configuration

Profiles live at ~/.config/db-mcp/profiles.toml (path resolved via directories). Passwords are stored in the OS keychain, never in the file.

Testing

make test                 # 25 unit tests + 6 SQLite integration tests
make integration-test     # adds Postgres + MySQL via testcontainers (Docker required)

License

MIT — see LICENSE.

from github.com/skydiver/steward-mcp

Installing Steward

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/skydiver/steward-mcp

FAQ

Is Steward MCP free?

Yes, Steward MCP is free — one-click install via Unyly at no cost.

Does Steward need an API key?

No, Steward runs without API keys or environment variables.

Is Steward hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Steward in Claude Desktop, Claude Code or Cursor?

Open Steward on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Steward with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All data MCPs