Skip to main content

Generic SQL database (Postgres, MySQL/MariaDB, MSSQL, Oracle, SQLite) API + MCP Server + A2A Server for Agentic AI!

Project description

Sql Mcp

API | MCP Server | A2A Agent

PyPI - Version MCP Server PyPI - Downloads GitHub Repo stars GitHub forks GitHub contributors PyPI - License GitHub GitHub last commit (by committer) GitHub pull requests GitHub closed pull requests GitHub issues GitHub top language GitHub language count GitHub repo size PyPI - Wheel PyPI - Implementation

Generic SQL database API + MCP Server + A2A Agent for the agent-utilities ecosystem — one connector for PostgreSQL, MySQL/MariaDB, Microsoft SQL Server, Oracle, and SQLite over SQLAlchemy 2.x Core.

Version: 0.3.0

Documentation — Installation, deployment, and usage across the API, CLI, and MCP interfaces are maintained in docs/.

Table of Contents

Overview

sql-mcp exposes read-only queries, gated DML/DDL, schema reflection, and connection administration as typed, deterministic MCP tools, and ships an optional Pydantic-AI agent server. It is read-only by default: every query passes a statement-type allowlist, every result is bounded by a row cap and a timeout, and all values travel as bound parameters — never interpolated into SQL strings.

What it provides

  • SqlApi (sql_mcp.api.api_client_sql) — a SQLAlchemy 2.x Core facade with named multi-connection support, lazy engine creation, the read-only statement gate, row-cap/timeout enforcement, and bounded result envelopes ({columns, rows, row_count, truncated}).
  • Four MCP tools (sql-mcp console script): sql_query (execute/explain), sql_execute (execute/script — gated by SQL_ALLOW_WRITES), sql_schema (schemas/tables/views/columns/indexes/foreign_keys/ddl/sample), and sql_admin (ping/version/active_connections/connections/dialects). See docs/usage.md for the full action surface.
  • A dialect registry (sql_mcp.dialects) — per-engine driver, URL scheme, pip extra, EXPLAIN prefix, and admin SQL. Core ships SQLite only; the other drivers install via extras.
  • An A2A agent server (sql-agent console script) — a Pydantic-AI graph agent wired to the MCP server via MCP_URL.

MCP tools

Tool Actions Description
sql_query execute, explain Run a read-only SELECT/CTE with bound parameters, or return the dialect's query plan
sql_execute execute, script One DML/DDL statement (or an all-or-nothing statement list) in a transaction — requires SQL_ALLOW_WRITES=True
sql_schema schemas, tables, views, columns, indexes, foreign_keys, ddl, sample Reflect schemas, tables, columns, indexes, FKs, CREATE DDL, and preview rows
sql_admin ping, version, active_connections, connections, dialects Connection health, server version, server sessions, registry info, driver availability

Every tool takes action, params_json, and an optional connection naming one of the configured connections. The whole set is toggled with SQLTOOL.

Dialects & extras

Dialect SQLAlchemy scheme Driver Install
SQLite sqlite+pysqlite stdlib pip install sql-mcp (core)
PostgreSQL postgresql+psycopg psycopg 3 pip install sql-mcp[postgres]
MySQL / MariaDB mysql+pymysql PyMySQL pip install sql-mcp[mysql]
SQL Server mssql+pyodbc pyodbc pip install sql-mcp[mssql]
Oracle oracle+oracledb python-oracledb pip install sql-mcp[oracle]

pip install sql-mcp[all] pulls every driver plus the MCP and agent extras.

Configuration (environment)

Var Default Meaning
SQL_CONNECTIONS (empty) JSON map of named connections: DSN strings or {dialect, host, port, username, password, database, options} objects
SQL_URL (empty) Single DSN registered as connection default
SQL_DIALECT / SQL_HOST / SQL_PORT / SQL_USERNAME / SQL_PASSWORD / SQL_DATABASE / SQL_OPTIONS (empty) Discrete fields for a single default connection
SQL_ALLOW_WRITES False Enable sql_execute (DML/DDL). Read-only by default
SQL_MAX_ROWS 500 Per-call row cap; tool requests are clamped to it
SQL_TIMEOUT_SECONDS 30 Per-statement timeout
SQLTOOL True Register the SQL tool set

With nothing configured the server registers a zero-infra in-memory SQLite connection named memory, so it works out of the box. Tools take an optional connection parameter naming one of the configured connections; it defaults to the sole/first one. Passwords are parsed into sqlalchemy.URL objects and only ever rendered redacted. Copy .env.example to .env and populate only what you use.

Installation

pip install sql-mcp            # core (SQLite, MCP server, API)
pip install sql-mcp[all]       # every driver + MCP + agent extras
pip install -e .               # from source

Or pull the container image:

docker pull knucklessg1/sql-mcp:latest

Usage

sql-mcp                        # stdio MCP server (default transport)
sql-mcp --transport streamable-http --host 0.0.0.0 --port 8000

Point it at a database:

export SQL_URL="postgresql+psycopg://svc:****@db.example.com:5432/app"
sql-mcp

Or several:

export SQL_CONNECTIONS='{
  "warehouse": "postgresql+psycopg://svc:****@dw.example.com:5432/dw",
  "erp": {"dialect": "mysql", "host": "erp.example.com", "username": "svc",
           "password": "****", "database": "erp"}
}'
sql-mcp

Run the agent server against a live MCP server:

sql-agent --mcp-url http://localhost:8000/mcp --host 0.0.0.0 --port 8080

MCP config

{
  "mcpServers": {
    "sql-mcp": {
      "command": "uv",
      "args": ["run", "sql-mcp"],
      "env": {
        "SQL_URL": "postgresql+psycopg://svc:****@db.example.com:5432/app",
        "SQL_ALLOW_WRITES": "False"
      }
    }
  }
}

Additional Deployment Options

sql-mcp can also run as a local container (Docker / Podman / uv) or be consumed from a remote deployment. The Deployment guide has full, copy-paste mcp_config.json for all four transports — stdio, streamable-http, local container / uv, and remote URL:

  • Local container / uv — launch the server from mcp_config.json via uvx, docker run, or podman run, or point at a local streamable-http container by url.
  • Remote URL — connect to a server deployed behind Caddy at http://sql-mcp.arpa/mcp using the "url" key.

Docker deployment

docker compose -f docker/mcp.compose.yml up -d      # MCP server only
docker compose -f docker/agent.compose.yml up -d    # MCP + A2A agent
curl -s http://localhost:8000/health                 # {"status":"OK"}

Both services read configuration from ../.env (copy .env.example); see docs/deployment.md.

Safety model

  • Read-only by defaultsql_execute refuses to run unless the server was started with SQL_ALLOW_WRITES=True; agents cannot flip the flag per call.
  • Statement allowlistsql_query accepts only SELECT/WITH/EXPLAIN/ SHOW/DESCRIBE/PRAGMA/VALUES; CTEs are inspected at paren depth zero so WITH ... INSERT cannot smuggle a write, SELECT INTO is rejected, and multi-statement payloads are refused.
  • Bounded results — per-call row caps clamp to SQL_MAX_ROWS; statements run under SQL_TIMEOUT_SECONDS on a worker thread.
  • Parameterized only — values bind via :name parameters; identifiers are quoted by SQLAlchemy reflection, never hand-interpolated.

Tests

python -m pytest          # full suite against in-memory SQLite (no live DBs)
pre-commit run --all-files

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

sql_mcp-0.3.0.tar.gz (33.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sql_mcp-0.3.0-py3-none-any.whl (26.1 kB view details)

Uploaded Python 3

File details

Details for the file sql_mcp-0.3.0.tar.gz.

File metadata

  • Download URL: sql_mcp-0.3.0.tar.gz
  • Upload date:
  • Size: 33.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for sql_mcp-0.3.0.tar.gz
Algorithm Hash digest
SHA256 89734c70bf0336f1ca037dcf2213a45ebe001fbc20ccf9f0fcd0b974609b1b36
MD5 22ce15faaeb31617d840347d52e6d2f1
BLAKE2b-256 8dde3a221ffd642993e26e60bc836db14a10d67803294b1a3a3f13602e1e527b

See more details on using hashes here.

File details

Details for the file sql_mcp-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: sql_mcp-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 26.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for sql_mcp-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 267be448549137563cebe523c78a685281c8a9bc2459bc8da889ee7f6a1179e8
MD5 927ad020b48918d6a0a9863bd79e321a
BLAKE2b-256 1bea7dd8845e36fa16981f1645e7ef55fc7fbe8ab6227b97cc52635b4a0b706f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page