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 "Install 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-executordescribe 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 }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 |
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nitesh-Nandan/query-executor'
If you have feedback or need assistance with the MCP directory API, please join our Discord server