MCP Alchemy

Explore schemas and run SQL on any SQLAlchemy-supported relational database

By Rune Kaagaard (individual) Python Local · stdio Databases

62 popularity score ★ 422 ↓ 13k/mo

Connect your client

Local (PyPI)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs DB_URL. Replace each <NAME> with your value.

Claude CodeTerminal
claude mcp add alchemy -e DB_URL=<DB_URL> -- uvx --from mcp-alchemy==2026.10.6.103105 --refresh-package mcp-alchemy mcp-alchemy
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "alchemy": {
      "command": "uvx",
      "args": [
        "--from",
        "mcp-alchemy==2026.10.6.103105",
        "--refresh-package",
        "mcp-alchemy",
        "mcp-alchemy"
      ],
      "env": {
        "DB_URL": "<DB_URL>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "alchemy": {
      "command": "uvx",
      "args": [
        "--from",
        "mcp-alchemy==2026.10.6.103105",
        "--refresh-package",
        "mcp-alchemy",
        "mcp-alchemy"
      ],
      "env": {
        "DB_URL": "<DB_URL>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "alchemy": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from",
        "mcp-alchemy==2026.10.6.103105",
        "--refresh-package",
        "mcp-alchemy",
        "mcp-alchemy"
      ],
      "env": {
        "DB_URL": "<DB_URL>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.alchemy]
command = "uvx"
args = ["--from", "mcp-alchemy==2026.10.6.103105", "--refresh-package", "mcp-alchemy", "mcp-alchemy"]

[mcp_servers.alchemy.env]
DB_URL = "<DB_URL>"
Gemini CLITerminal
gemini mcp add --scope user -e DB_URL=<DB_URL> alchemy uvx -- --from mcp-alchemy==2026.10.6.103105 --refresh-package mcp-alchemy mcp-alchemy
Local (container)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs DB_URL. Replace each <NAME> with your value.

Claude CodeTerminal
claude mcp add alchemy -e DB_URL=<DB_URL> -- docker run -i --rm -e DB_URL ghcr.io/runekaagaard/mcp-alchemy:latest
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "alchemy": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "DB_URL",
        "ghcr.io/runekaagaard/mcp-alchemy:latest"
      ],
      "env": {
        "DB_URL": "<DB_URL>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "alchemy": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "DB_URL",
        "ghcr.io/runekaagaard/mcp-alchemy:latest"
      ],
      "env": {
        "DB_URL": "<DB_URL>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "alchemy": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "DB_URL",
        "ghcr.io/runekaagaard/mcp-alchemy:latest"
      ],
      "env": {
        "DB_URL": "<DB_URL>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.alchemy]
command = "docker"
args = ["run", "-i", "--rm", "-e", "DB_URL", "ghcr.io/runekaagaard/mcp-alchemy:latest"]

[mcp_servers.alchemy.env]
DB_URL = "<DB_URL>"
Gemini CLITerminal
gemini mcp add --scope user -e DB_URL=<DB_URL> alchemy docker -- run -i --rm -e DB_URL ghcr.io/runekaagaard/mcp-alchemy:latest

Settings 4

DB_URL Required: SQLAlchemy database URL, e.g. postgresql://user:password@localhost/dbname.
EXECUTE_QUERY_MAX_CHARS Optional: Character cap on query output; default 4000.
CLAUDE_LOCAL_FILES_PATH Optional: Folder where full result sets are written as JSON files.
DB_ENGINE_OPTIONS Optional: JSON of extra SQLAlchemy engine options, overriding the pool and AUTOCOMMIT defaults.

In a container, a setting goes in with -e NAME=value after docker run.

What it does

MCP Alchemy connects an assistant to one relational database through SQLAlchemy. You give it a single connection URL in DB_URL, and it works with whatever dialect SQLAlchemy can load: SQLite out of the box, and PostgreSQL, MySQL/MariaDB, MS SQL Server, Oracle, CrateDB, Vertica and others once you add their driver package.

It has four tools. Two list table names (all of them, or those containing a substring), one prints columns, types, primary keys and foreign-key relationships for chosen tables, and one runs any SQL statement with optional bound parameters. Query results come back as one block per row, with NULLs and ISO dates spelled out, cut off at 4000 characters by default (EXECUTE_QUERY_MAX_CHARS). If you set CLAUDE_LOCAL_FILES_PATH, the full result set is also written as a JSON file in that folder for use with the author's separate claude-local-files project.

Some things the README does not spell out, taken from server.py at the released tag: the server connects to the database while it starts, so a wrong URL or unreachable host stops it from launching. Every tool description includes the dialect, server version, database name, host and user name. The connection is opened in AUTOCOMMIT mode, so any write a query makes is committed at once.

It speaks stdio by default. With --transport streamable-http (or the older sse) it serves HTTP on 127.0.0.1:7000 unless --host and --port are given.

What it needs

RuntimePythonorDocker

uv (for uvx) and Python, or Docker. A database you can reach, and its SQLAlchemy driver added with uvx --with (for example psycopg2-binary, pymysql, pymssql, oracledb, vertica-python). SQLite needs no extra driver. The Docker image ships PostgreSQL, MySQL/MariaDB, MS SQL Server and Oracle drivers.

Limits

It has no read-only mode: execute_query runs whatever SQL it is given, and the connection uses AUTOCOMMIT by default (server.py). Output is cut off at EXECUTE_QUERY_MAX_CHARS (default 4000) and whole rows past that point are dropped. The table tools list tables in the connection's default schema only, and filter_table_names matches case-sensitively. One server instance serves one DB_URL. The README notes that uvx can show a version error for up to 600 seconds after a new release, and that restarting the client fixes it.

Who it suits

Suits developers and analysts who want an assistant to explore a database's structure and run queries, especially across several database engines with one tool. It runs on your machine and is not tied to one vendor. Because any statement goes through and is committed at once, point it at a read-only database user or a copy rather than production data you cannot lose. If you need a server that limits itself to reading, or one built for a single vendor's own features, look elsewhere.

Tools 4

all_table_names
Lists every table name in the database, comma-separated
filter_table_names
Lists table names that contain a given substring
schema_definitions
Shows columns, types, keys and foreign-key links for chosen tables
execute_query
Runs a SQL statement with optional bound parameters and returns rows or the affected count

Similar servers