query-executor
Allows AI agents to execute SQL queries, inspect schemas, and analyze query performance on one or more PostgreSQL databases registered as named projects.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@query-executor describe the schema for the default project"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Query Executor MCP Server
A Model Context Protocol server that gives AI agents read (and optionally write) access to one or more PostgreSQL databases. Each database is registered as a named project — the agent picks the right one per call via project_id.
How it works
flowchart TD
A[AI Agent\nClaude / Cursor / etc.] -->|MCP stdio| B[Query Executor\nMCP Server]
B --> C{Resolve project_id}
C -->|default| D[(default DB)]
C -->|project-alpha| E[(project-alpha DB)]
C -->|project-beta| F[(project-beta DB)]
subgraph Tools
T1[describe_postgres_schema]
T2[execute_postgres]
T3[explain_postgres]
T4[pg_stat_statements]
end
B --> Tools
Tools --> CsequenceDiagram
participant Agent
participant Server as MCP Server
participant Config as databases.json
participant DB as PostgreSQL
Agent->>Server: tool call (project_id, sql)
Server->>Config: resolve project_id → DSN + mode
Config-->>Server: { dsn, mode }
alt mode = readonly
Server->>Server: assert first token is SELECT/WITH
end
Server->>DB: execute query
DB-->>Server: rows
Server-->>Agent: JSON { rows, row_count }Related MCP server: mcp-postgres
Features
Multi-project — connect to any number of PostgreSQL databases simultaneously; each call targets one via
project_idPer-project mode —
readonlyblocks all writes at the first SQL token;readwriteallows all SQLSafe fallback — omitting
project_idroutes to the configured default projectFour tools — schema inspection, query execution, EXPLAIN ANALYZE, and slow-query analysis
stdio transport — works with any MCP client (Claude Desktop, Cursor, Claude Code, etc.)
Docker-ready — single image, credentials baked in at build time from gitignored files
Project layout
query-executor/
├── Dockerfile
├── Makefile
├── pyproject.toml
├── uv.lock
├── main.py # connection check entrypoint
├── .env # gitignored — copy from .env.example
├── databases.json # gitignored — copy from databases.example.json
├── .env.example
├── databases.example.json
└── query_executor/
├── config.py # loads .env + databases.json; single source of truth
├── query_connector.py # raw asyncpg functions (no MCP imports)
├── tools.py # Pydantic input models + tool implementations
└── server.py # FastMCP bootstrap + entrypointQuick start
1. Install dependencies
uv sync2. Configure
cp .env.example .env
cp databases.example.json databases.jsonEdit databases.json with your real connection strings:
{
"default": {
"dsn": "postgresql://user:password@localhost:5432/mydb",
"mode": "readonly"
},
"staging": {
"dsn": "postgresql://user:password@staging-host:5432/stagingdb",
"mode": "readwrite"
}
}
| Behaviour |
| Only |
| All SQL is permitted. Use only on non-production databases. |
If a project does not specify mode, it defaults to readonly.
3. Check connections
make checkWelcome to Query Executor!
Default project : default
• default [readonly] (default)
• staging [readwrite]
Testing database connections...
[default] mode=readonly ... OK — PostgreSQL 15.4
[staging] mode=readwrite ... OK — PostgreSQL 15.4
All 2 connection(s) OK.4. Build the Docker image
make buildMCP client configuration
The server runs over stdio — the MCP client spawns the process and communicates via stdin/stdout.
Claude Desktop
Config file: ~/Library/Application Support/Claude/claude_desktop_config.json
With UV (local):
{
"mcpServers": {
"query-executor": {
"command": "uv",
"args": ["run", "python", "-m", "query_executor.server"],
"cwd": "/Users/niteshnandan/workspace/2026/query-executor"
}
}
}With Docker:
{
"mcpServers": {
"query-executor": {
"command": "docker",
"args": ["run", "-i", "--rm", "query-executor"]
}
}
}Cursor
Global config: ~/.cursor/mcp.json
Project config: .cursor/mcp.json
With UV (local):
{
"mcpServers": {
"query-executor": {
"command": "uv",
"args": ["run", "python", "-m", "query_executor.server"],
"cwd": "/Users/niteshnandan/workspace/2026/query-executor"
}
}
}With Docker:
{
"mcpServers": {
"query-executor": {
"command": "docker",
"args": ["run", "-i", "--rm", "query-executor"]
}
}
}Claude Code
Add to your project's .claude/mcp.json:
With UV (local):
{
"mcpServers": {
"query-executor": {
"type": "stdio",
"command": "uv",
"args": ["run", "python", "-m", "query_executor.server"],
"cwd": "/Users/niteshnandan/workspace/2026/query-executor"
}
}
}With Docker:
{
"mcpServers": {
"query-executor": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "query-executor"]
}
}
}Note: Replace
/Users/niteshnandan/workspace/2026/query-executorwith the actual path on your machine if sharing config with others.
Tools reference
describe_postgres_schema
Inspect tables, columns, foreign keys, and indexes for a given schema.
Call this first before writing any query — it gives you exact column names and types so you write correct SQL on the first attempt.
Parameter | Type | Default | Description |
| string |
| Schema to inspect |
| string | default project | Target database |
Returns { columns, foreign_keys, indexes }.
execute_postgres
Run a SQL query and get rows back as JSON.
Parameter | Type | Required | Description |
| string | yes | SQL to execute. In |
| string | no | Target database |
Returns { rows: [...], row_count: N }.
explain_postgres
Run EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) on a query and return the execution plan.
Parameter | Type | Required | Description |
| string | yes | SELECT query to analyse (do not include |
| string | no | Target database |
Returns { plan: [...] }. Key things to check in the plan:
Seq Scan on a large table → missing index on the
WHEREcolumnActual rows ≫ Plan rows → stale statistics; run
ANALYZE <table>High shared_blks_read → I/O-bound; working set does not fit in
shared_buffers
pg_stat_statements
Return the top N query patterns ranked by total cumulative execution time.
Parameter | Type | Default | Description |
| integer | 20 | Number of queries to return (max 100) |
| string | no | Target database |
Returns rows with total_exec_sec, mean_exec_sec, max_exec_sec, calls, shared_blks_hit, shared_blks_read.
Requires the pg_stat_statements extension. Enabled by default on AWS RDS, GCP Cloud SQL, and Supabase. On self-hosted Postgres: CREATE EXTENSION pg_stat_statements;
Recommended workflows
Explore an unknown database
describe_postgres_schema → execute_postgresDebug a slow query
describe_postgres_schema (check what indexes exist)
→ explain_postgres (verify the planner uses them)
→ execute_postgres (run once plan looks correct)Performance audit
pg_stat_statements (find the most expensive patterns)
→ explain_postgres (drill into the worst offender)
→ describe_postgres_schema (check if a missing index would help)Environment variables
Variable | Default | Description |
|
| Path to the databases registry file |
|
| Fallback project when |
|
| Python logging level |
|
| asyncpg connection timeout in seconds |
|
| Statement timeout for EXPLAIN ANALYZE in milliseconds |
|
| Default row limit for |
Available Tools
5 toolsdescribe_postgres_schemaA
Inspect a PostgreSQL schema and return its full structure as JSON.
Call this before writing any query, JOIN, or EXPLAIN — it gives you exact table/column names and indexes so you don't guess.
Returns a JSON object:
"columns": table_name, column_name, data_type, is_nullable, column_default
"foreign_keys": which columns reference which tables (use for JOINs)
"indexes": full CREATE INDEX definitions (check before running EXPLAIN)
Large schemas (100+ tables) return a lot of JSON — filter by table_name client-side rather than calling this multiple times.
Inputs: input (required). Returns: result
execute_postgresA
Execute a SQL query against a PostgreSQL database and return rows as JSON.
Returns: {"rows": [...], "row_count": N}
Mode behaviour (per project in databases.json):
readonly — only SELECT/WITH accepted; writes are blocked before reaching the DB.
readwrite — all SQL allowed; use only on non-production projects.
Call describe_postgres_schema first to confirm table/column names. If row_count equals your LIMIT, there are likely more rows.
Inputs: input (required). Returns: result
explain_postgresA
Run EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) on a query and return the plan.
The query executes to collect real timing; results are discarded — only the plan is returned. A statement timeout prevents runaway queries.
Returns: {"plan": []}
Use before running a slow or unfamiliar query on a large table. Check describe_postgres_schema first to see what indexes exist. Write queries are blocked.
Inputs: input (required). Returns: result
list_projectsA
List all configured database projects and their access modes.
Call this first when you don't know which project_id to use. Returns every project registered in databases.json, including which one is the default (used when project_id is omitted).
Returns a JSON object: { "default_project": "<project_id>", "projects": [ {"project_id": "", "mode": "readonly|readwrite", "is_default": true|false}, ... ] }
Inputs: no named parameters. Returns: result
pg_stat_statementsA
Return the top N most expensive queries from pg_stat_statements.
Best starting point for a performance audit — shows which query patterns cost the most cumulative time across the application.
Returns: {"rows": [{query, calls, total_exec_sec, mean_exec_sec, max_exec_sec, total_rows, shared_blks_hit, shared_blks_read}], "row_count": N}
Query text uses $1/$2 placeholders (pg_stat_statements normalises literals). Requires the pg_stat_statements extension (enabled by default on RDS, Cloud SQL, Supabase; otherwise: CREATE EXTENSION pg_stat_statements).
Inputs: input (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: schema inspection, query execution, explain planning, project listing, and performance analysis. No overlap exists.
Tools follow a mostly consistent verb_noun pattern (describe_, execute_, explain_, list_), except pg_stat_statements which is a fixed PostgreSQL function name. Overall, naming is clear and predictable.
Five tools is ideal for a query executor, covering key operations without unnecessary overhead. Each tool serves a specific need.
The tool set covers essential operations: schema inspection, query execution with read-only/write modes, explain analysis, project management, and performance monitoring. No obvious gaps for the domain.
Maintenance
Related MCP Connectors
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Supabase-compatible Postgres for agents: projects, branches, SQL, auth, storage, email.
Deterministic safety, correctness & cost gate that vets Postgres SQL before your AI agent runs it.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to safely explore, analyze, and maintain PostgreSQL databases with read-only mode by default, SQL injection prevention, query performance analysis, and optional write operations.87 npmApache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with PostgreSQL databases through schema intelligence, query execution, and DBA tooling including index analysis and health monitoring. Features configurable access levels and audit logging for secure database operations.432 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with PostgreSQL databases through natural language queries, schema inspection, and safe SQL execution.6 npm1ISC
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to safely interact with PostgreSQL databases, perform queries, inspect schemas, and analyze query performance.2ISC