Skip to main content
Glama
nayzo

mcp-postgresdb-readonly

by nayzo

mcp-postgresdb-readonly

Serveur MCP pour accès PostgreSQL en lecture seule. Expose des outils d'exploration et de requêtage à tout client compatible MCP (Claude Code, Cursor, OpenCode, etc.).

Les opérations d'écriture sont bloquées au niveau applicatif, indépendamment des droits de l'utilisateur de la base de données.

Deux modes de fonctionnement :

  • stdio : utilisé localement, l'agent IA lance le process directement.

  • HTTP : hébergé sur un serveur, les agents s'y connectent via une URL.

Supporte jusqu'à trois environnements : staging, test, prod. Seuls ceux avec un HOST configuré sont chargés.


Outils MCP

Outil

Description

query

Exécute une requête SELECT (écritures rejetées)

list-tables

Liste les tables d'un schéma (ou de tous les schémas si aucun schéma par défaut n'est configuré)

describe-table

Affiche colonnes, types, nullabilité, valeurs par défaut (tous les schémas si aucun par défaut)

list-schemas

Liste tous les schémas définis par l'utilisateur

list-environments

Liste les environnements configurés (sans credentials)


Related MCP server: Postgres MCP Server

Mode stdio (usage local)

Dans ce mode, chaque développeur installe le serveur sur sa propre machine. Le client IA (Claude Code, Cursor…) démarre automatiquement le serveur au moment où il en a besoin, et s'y connecte directement — pas de réseau, pas d'URL, pas de token.

Chaque développeur a ses propres credentials DB dans son .env local.

Prérequis : Node.js 18+ installé sur la machine.

1. Installer et builder

npm install
npm run build

2. Configurer

cp .env.dist .env

Renseigner dans .env au minimum un environnement :

POSTGRES_PROD_HOST=your-cluster.rds.amazonaws.com
POSTGRES_PROD_DATABASE=mydb
POSTGRES_PROD_USER=reader
POSTGRES_PROD_PASSWORD=secret

.env est git-ignoré et ne doit jamais être commité.

3. Déclarer le serveur dans le client IA

Le client IA a besoin du chemin absolu vers le fichier compilé. Récupérer ce chemin :

pwd
# exemple : /Users/alice/dev/mcp-postgresdb-readonly
# le fichier à déclarer : /Users/alice/dev/mcp-postgresdb-readonly/dist/index.js

Claude Code : ~/.claude/settings.json :

{
  "mcpServers": {
    "postgresdb-readonly": {
      "command": "node",
      "args": ["/chemin/absolu/vers/mcp-postgresdb-readonly/dist/index.js"]
    }
  }
}

Cursor : .cursor/mcp.json (projet) ou ~/.cursor/mcp.json (global) :

{
  "mcpServers": {
    "postgresdb-readonly": {
      "command": "node",
      "args": ["/chemin/absolu/vers/mcp-postgresdb-readonly/dist/index.js"]
    }
  }
}

Une fois configuré, redémarrer le client IA. Le serveur démarre automatiquement en arrière-plan à chaque session.


Mode HTTP (serveur hébergé)

Le serveur tourne sur une machine distante et expose un endpoint HTTPS. Les agents locaux s'y connectent via URL + Bearer token. Personne n'a besoin d'installer Node ou les credentials DB en local.

Architecture

Agents locaux (Claude, Cursor, OpenCode)
        │  HTTPS + Bearer token
        ▼
    nginx (SSL termination)
        │  HTTP loopback
        ▼
  Docker container  ←─── accès DB (prod/staging/test)
  (node dist/index.js, PORT=3000)

1. Prérequis serveur

  • Un nom de domaine pointant vers le serveur (ex: mcp.example.com)

  • Docker + Docker Compose

  • Nginx

  • Certbot (Let's Encrypt)

  • make (optionnel, pour les commandes de gestion)

Installation sur Ubuntu/Debian :

# Docker
curl -fsSL https://get.docker.com | sh

# Nginx + Certbot
apt install -y nginx certbot python3-certbot-nginx make

# Démarrer et activer nginx
systemctl start nginx && systemctl enable nginx

2. Cloner le repo sur le serveur

git clone <repo-url> /opt/mcp-postgresdb-readonly
cd /opt/mcp-postgresdb-readonly

3. Configurer .env

cp .env.dist .env

Renseigner les credentials de base de données et impérativement générer un token d'auth :

# Générer un token sécurisé
openssl rand -hex 32

Exemple de .env :

# Token d'auth (obligatoire en mode HTTP)
MCP_AUTH_TOKEN=votre-token-généré-ici

# Connexion prod
POSTGRES_PROD_HOST=your-cluster.rds.amazonaws.com
POSTGRES_PROD_PORT=5432
POSTGRES_PROD_DATABASE=mydb
POSTGRES_PROD_USER=reader
POSTGRES_PROD_PASSWORD=secret
# POSTGRES_PROD_SCHEMA=myschema  # optional: restrict to a single schema; omit to access all schemas
POSTGRES_PROD_SSL=true

# Protections (optionnel, valeurs par défaut)
RATE_LIMIT_PER_MINUTE=60
QUERY_TIMEOUT_MS=30000
MAX_ROWS=1000

PORT ne doit pas être dans .env pour le mode Docker, il est imposé à 3000 par docker-compose.yml.

4. Lancer le container

docker compose up -d --build

Vérifier que le container est en bonne santé :

docker compose ps
docker compose logs -f
curl http://localhost:3000/health

La réponse attendue :

{"status":"ok","version":"2.0.0","environments":["prod"],"transport":"streamable-http"}

5. Obtenir un certificat SSL

La config nginx fournie référence les certificats Let's Encrypt. Il faut les obtenir avant d'activer cette config.

Laisser nginx tourner avec sa config par défaut (port 80), puis :

certbot certonly --nginx -d votre-domaine.com

certonly récupère uniquement le certificat sans modifier nginx.

6. Configurer nginx

Les certs existent maintenant, nginx -t passera :

DOMAIN=votre-domaine.com make nginx-setup

Ou manuellement :

cp .docker/nginx.conf /etc/nginx/sites-available/mcp-postgresdb
sed -i 's/mcp.example.com/votre-domaine.com/g' /etc/nginx/sites-available/mcp-postgresdb
ln -sf /etc/nginx/sites-available/mcp-postgresdb /etc/nginx/sites-enabled/mcp-postgresdb
nginx -t && systemctl reload nginx

7. Tester le endpoint

Vérifier que le token est bien exigé :

curl -s -o /dev/null -w "%{http_code}" -X POST https://votre-domaine.com/mcp
# doit retourner 401

Lister les outils disponibles (valide le token + la connexion MCP) :

curl -s -X POST https://votre-domaine.com/mcp \
  -H "Authorization: Bearer votre-token-généré-ici" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

8. Mettre à jour

make deploy

Ou manuellement :

git pull
docker compose up -d --build

Configurer les agents en mode HTTP

Une fois le serveur en ligne, partager le token aux PMs et développeurs. Chacun ajoute la config suivante dans son agent.

Claude Code

~/.claude/settings.json :

{
  "mcpServers": {
    "postgresdb-readonly": {
      "type": "http",
      "url": "https://votre-domaine.com/mcp",
      "headers": {
        "Authorization": "Bearer votre-token"
      }
    }
  }
}

Cursor

.cursor/mcp.json (projet) ou ~/.cursor/mcp.json (global) :

{
  "mcpServers": {
    "postgresdb-readonly": {
      "url": "https://votre-domaine.com/mcp",
      "headers": {
        "Authorization": "Bearer votre-token"
      }
    }
  }
}

OpenCode

~/.config/opencode/config.json :

{
  "mcp": {
    "postgresdb-readonly": {
      "type": "remote",
      "url": "https://votre-domaine.com/mcp",
      "headers": {
        "Authorization": "Bearer votre-token"
      }
    }
  }
}

Makefile

Le Makefile regroupe les commandes courantes pour la gestion du serveur.

Commande

Description

make deploy

git pull + rebuild + redémarrage du container

make restart

Redémarre le container sans rebuild

make stop

Arrête le container

make logs

Affiche les logs en temps réel

make ps

État du container

make health

Vérifie que le serveur répond sur localhost:3000

make token

Génère un nouveau Bearer token

DOMAIN=... make nginx-setup

Installe et active la config nginx

DOMAIN=... make ssl

Obtient un certificat SSL via Certbot


Troubleshooting

Le container ne démarre pas

make logs
# ou
docker compose logs

Port 3000 déjà utilisé

ss -tlnp | grep 3000

La config nginx est invalide

nginx -t

Renouvellement SSL

Certbot configure un timer systemd automatique. Pour forcer le renouvellement :

certbot renew --dry-run

Vérifier que le container est en bonne santé

make ps
make health

Variables d'environnement

Connexions base de données

Chaque environnement utilise le préfixe POSTGRES_{ENV}_{ENV} vaut STAGING, TEST ou PROD. Si POSTGRES_{ENV}_HOST est absent, l'environnement est ignoré.

Variable

Obligatoire

Défaut

Description

POSTGRES_{ENV}_HOST

oui

-

Hostname PostgreSQL

POSTGRES_{ENV}_PORT

non

5432

Port TCP

POSTGRES_{ENV}_DATABASE

oui

-

Nom de la base

POSTGRES_{ENV}_USER

oui

-

Utilisateur

POSTGRES_{ENV}_PASSWORD

oui

-

Mot de passe

POSTGRES_{ENV}_SCHEMA

non

aucun (tous les schémas)

Restreint list-tables et describe-table à un schéma précis. Si absent, tous les schémas utilisateur sont accessibles.

POSTGRES_{ENV}_SSL

non

true

false pour désactiver SSL (local/dev uniquement)

Serveur HTTP

Variable

Obligatoire

Défaut

Description

PORT

non

-

Si défini, démarre en mode HTTP sur ce port. Absent = mode stdio.

MCP_AUTH_TOKEN

recommandé

-

Bearer token requis dans l'en-tête Authorization. Absent = serveur non protégé.

Protections

Variable

Défaut

Description

RATE_LIMIT_PER_MINUTE

60

Nombre max de requêtes par minute (fenêtre glissante globale)

QUERY_TIMEOUT_MS

30000

Timeout PostgreSQL côté serveur (ms). La requête est annulée si dépassé.

MAX_ROWS

1000

Si aucun LIMIT dans la requête, un LIMIT {MAX_ROWS} est injecté automatiquement.


Protections

Trois mécanismes protègent la base contre les requêtes abusives (boucles IA, hallucinations) :

  • Rate limiter : fenêtre glissante d'une minute. Au-delà de RATE_LIMIT_PER_MINUTE, les requêtes sont rejetées.

  • Statement timeout : durée max d'exécution côté PostgreSQL. La requête est annulée automatiquement si dépassée.

  • Auto LIMIT : si aucun LIMIT n'est présent, LIMIT {MAX_ROWS} est injecté. Évite les scans complets accidentels.

  • Blocage écriture : les mots-clés INSERT, UPDATE, DELETE, DROP, TRUNCATE, ALTER, CREATE, REPLACE, GRANT, REVOKE, MERGE, UPSERT, VACUUM, REINDEX, COPY, DO, CALL sont rejetés avant que la requête n'atteigne la base. Les commentaires SQL en tête de requête (--, /* */) sont strippés avant détection. EXPLAIN ANALYZE <write> est également bloqué (PostgreSQL exécute réellement la requête avec ANALYZE).


Logs

Chaque requête est loggée sur stderr :

[HH:MM:SS] ENV  outil | clé=valeur | ...

Exemples :

[11:52:26] PROD  query          | duration=257ms | rows=3    | sql=SELECT id, mail FROM users.user LIMIT 3
[11:52:26] STAGING  list-tables    | schema=all     | duration=300ms | tables=212
[11:52:26] STAGING  list-tables    | schema=public  | duration=300ms | tables=94
[11:52:26] TEST     describe-table | schema=all     | table=orders   | duration=247ms | columns=32
[11:52:26] PROD     query          | duration=12ms  | rows=1000 | limit=auto:1000 | sql=SELECT * FROM public.orders
[11:52:26] STAGING  query          | status=BLOCKED (write) | sql=INSERT INTO ...
[11:52:26] PROD  query          | status=RATE LIMITED | limit=60/min

PROD s'affiche en rouge, STAGING en jaune, TEST en cyan (si stderr est un TTY).


Sécurité

  • Utiliser un utilisateur PostgreSQL dédié en lecture seule. Ne jamais utiliser owner ou un superutilisateur.

  • En mode HTTP, toujours configurer MCP_AUTH_TOKEN. Générer un token par openssl rand -hex 32.

  • .env est dans .gitignore et ne doit jamais être commité.

  • En production, nginx est le seul point d'entrée public. Le container écoute uniquement sur 127.0.0.1:3000.

Available Tools

5 tools
describe-tableB

Get the structure of a table (columns, types, nullability, defaults)

ParametersJSON Schema
NameRequiredDescriptionDefault
envYesEnvironment (staging, test, prod)
tableYesTable name
schemaNoSchema name (defaults to the environment's configured schema)

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses the return contents, but never states that this is a non-mutating read, what happens for an unknown table or schema, or any permission/environment constraints — leaving key behavior to inference.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that names the operation and its output with zero filler; every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only metadata tool with a fully documented schema and no output schema, the description covers what the tool does and returns. It could be stronger by noting the read-only nature and environment scoping, but it is largely sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with env, table, and schema all documented (including the schema default behavior), so the schema does the heavy lifting. The description adds no parameter-level detail beyond what the schema already provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get') and resource ('structure of a table') and enumerates the returned content (columns, types, nullability, defaults), so the agent knows exactly what the tool yields. It does not explicitly differentiate itself from siblings like list-tables or list-schemas, relying on the name for that distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus list-tables, list-schemas, or query. The usage context is only implied by the name, and no prerequisites or exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list-environmentsB

List all configured database environments

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, and it offers only that environments are listed. It does not say whether this is a safe read-only call, whether it requires configuration/credentials, or what the result set looks like. The risk is low for a zero-parameter list tool, but the disclosure is thin.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words; it conveys the verb, resource, and scope compactly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a trivial zero-parameter listing tool with no output schema, the description says enough to invoke it correctly. A brief note on what an 'environment' represents or how results are ordered would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. The description correctly implies no filtering or input is required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('configured database environments'), making the tool's scope immediately clear. It is distinguishable from siblings like list-tables and list-schemas by the distinct 'environments' resource, though it does not explicitly name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus the sibling discovery tools (list-tables, list-schemas, describe-table) or what prerequisites exist. The agent must infer usage entirely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list-schemasB

List all user-defined schemas in the database

ParametersJSON Schema
NameRequiredDescriptionDefault
envYesEnvironment (staging, test, prod)

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'List' implies a read-only, non-destructive operation and 'user-defined' scopes the result set, but there is no mention of permissions, output shape, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words. The scope qualifier 'user-defined' is placed where it matters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter listing tool with a fully documented schema and no output schema required, the description is nearly complete. The only minor gap is that sibling differentiation is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single env parameter has a documented enum, so the schema fully carries parameter meaning. The description adds nothing beyond what the schema already provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (user-defined schemas in the database), which is clear and unambiguous. It does not, however, distinguish itself from siblings like list-tables or list-environments, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives such as list-tables, describe-table, or list-environments. No prerequisites or exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list-tablesC

List all tables in a schema

ParametersJSON Schema
NameRequiredDescriptionDefault
envYesEnvironment (staging, test, prod)
schemaNoSchema name (defaults to the environment's configured schema)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. 'List' implies a read-only operation, but the description says nothing about permissions, result size limits, pagination, or whether large schemas are truncated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence, front-loaded with the verb and resource, with no filler. It is efficient, though arguably under-specifies for a tool with an environment parameter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with a fully documented two-parameter schema, one sentence is nearly adequate. The lack of any output/pagination context and no annotations leaves it only minimally complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both the env enum and the schema default behavior. The description only restates 'in a schema' and adds no syntax, format, or default-behavior detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('List all tables'), which is clearly distinct from siblings like list-schemas or describe-table. However, it does not explicitly differentiate itself from those siblings or state scope (e.g., whether it includes views).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of when an agent should call list-tables versus describe-table or query, and no prerequisites. Usage is only implied by the name and description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Execute a read-only SQL query on a PostgreSQL database.

⛔ WRITE OPERATIONS ARE STRICTLY FORBIDDEN (INSERT, UPDATE, DELETE, DROP, etc.)

  • Always use schema-qualified table names (e.g., schema.table_name)

  • Only SELECT queries are accepted

  • Use parameterized queries for user-provided values

ParametersJSON Schema
NameRequiredDescriptionDefault
envYesTarget environment (staging, test, prod)
sqlYesSQL SELECT query to execute (read-only)
paramsNoOptional parameters for parameterized queries

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden and does so well: it discloses the read-only contract emphatically, warns that write ops are forbidden, and prescribes schema-qualified names. This is exactly the behavioral context an agent needs before touching a production database.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then constraints in a compact bullet list. The ⛔ emoji is a bit heavy-handed but the substance all earns its place. Minor redundancy between the top-line 'read-only' and the bullet re-stating SELECT-only.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-param query tool with no output schema and no annotations, the description covers the essential safety contract and rules. It could say more about result shape or limits (row caps, timeouts), but the core agent needs are addressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so env, sql, and params are already documented in the schema. The description adds the parameterized-query convention ('use parameterized queries for user-provided values'), which connects the params array to the sql placeholder pattern – useful but minimal beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (execute) and resource (read-only SQL query on PostgreSQL) in the first sentence. The tool is cleanly distinguished from siblings like list-tables and describe-table, which are metadata tools, while this one runs actual queries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear constraints on when this tool applies – only SELECT queries, read-only. The constraint list effectively excludes write operations. However, it doesn't explicitly say when to reach for this vs. describe-table/list-tables for schema exploration, leaving some ambiguity about discovery vs. query workflows.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv2.0.0
    • First observeddescribe-table
    • First observedlist-environments
    • First observedlist-schemas
    • First observedlist-tables
    • First observedquery

TDQS

A3.6/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct target: query executes SQL, list-tables and list-schemas enumerate metadata, describe-table inspects a single table's structure, and list-environments reports configured connections. There is no meaningful overlap between any pair.

Naming Consistency4/5

Four tools follow a clean verb_noun kebab-case pattern (list-tables, describe-table, list-schemas, list-environments) with uniform casing. The lone exception is 'query', a bare verb with no object, which is a minor deviation from the established pattern.

Tool Count5/5

Five tools is well-scoped for a read-only database accessor: one execution tool plus four discovery/introspection tools. Nothing feels redundant or missing at the count level.

Completeness4/5

The surface covers the natural discovery-to-query workflow (schemas → tables → structure → SQL), and omitting writes is intentional for a read-only server. Minor gaps exist, such as listing views/indexes or an EXPLAIN tool, but core workflows are fully supported.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables secure querying of PostgreSQL databases through MCP-compatible clients. Supports read-only SQL execution, table exploration, and connection management with built-in security validation.
    3
    30 npm
    9
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with PostgreSQL databases through MCP, allowing users to explore database structures, inspect table schemas, and execute read-only SQL queries.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only access to PostgreSQL databases via MCP, enforcing least-privilege roles, row-level security, masked views, and SQL AST guardrails to prevent data leakage and unauthorized operations, enabling AI agents to safely query sensitive production data.
    MIT