Tutoriel

Statut éditorial : En attente de relecture

Connecter un serveur MCP à une base PostgreSQL

Exposer des outils PostgreSQL en lecture contrôlée via MCP, avec requêtes paramétrées, rôle dédié, limites et journalisation.

Classification du contenu

Types

  • Agents IA
Niveau
Avancé
Publié le
24 août 2026
Dernière relecture
Relecture en attente
Prochaine vérification
24 novembre 2026

Un serveur MCP ne doit pas exposer une console SQL libre au modèle. Il doit proposer des outils métier étroits, paramétrés et autorisés, par exemple rechercher un client ou résumer les commandes d’une période.

Créer un rôle dédié

~~~sql CREATE ROLE mcp_reader LOGIN PASSWORD 'a-remplacer'; GRANT CONNECT ON DATABASE app TO mcp_reader; GRANT USAGE ON SCHEMA reporting TO mcp_reader; GRANT SELECT ON ALL TABLES IN SCHEMA reporting TO mcp_reader; ALTER ROLE mcp_reader SET statement_timeout = '5s'; ~~~

Préférez des vues reporting qui retirent les colonnes sensibles. En production, stockez le mot de passe dans un gestionnaire de secrets et imposez TLS.

Installer le serveur Python

~~~bash python -m venv .venv source .venv/bin/activate pip install -U mcp psycopg[binary] pydantic-settings ~~~

Définir un outil borné

~~~python import os import psycopg from mcp.server.fastmcp import FastMCP

mcp = FastMCP('reporting-postgres')

@mcp.tool() def orders_by_status(status: str, limit: int = 20) -> list[dict]: """Liste les commandes d'un statut autorisé, sans données personnelles.""" allowed = {'pending', 'paid', 'shipped', 'cancelled'} if status not in allowed: raise ValueError('Statut invalide') limit = max(1, min(limit, 100))

with psycopg.connect(os.environ['MCP_DATABASE_URL']) as conn: rows = conn.execute( '''SELECT order_id, status, total_cents, created_at FROM reporting.orders WHERE status = %s ORDER BY created_at DESC LIMIT %s''', (status, limit), ).fetchall() return [ {'order_id': r[0], 'status': r[1], 'total_cents': r[2], 'created_at': r[3].isoformat()} for r in rows ] ~~~

La requête est fixe et paramétrée. Le modèle ne choisit ni table, ni colonne, ni clause SQL.

Tester localement

Lancez le transport recommandé par votre client MCP et utilisez l’inspecteur MCP pour vérifier la découverte de l’outil, son schéma et les erreurs. Testez statut invalide, limite trop grande, timeout et base indisponible.

Sécuriser

Pour un transport distant, authentifiez le client, autorisez les outils par identité et protégez-vous contre les requêtes rejouées. Considérez toute sortie de base comme une donnée non fiable : elle peut contenir du texte ressemblant à une instruction.

Journalisez utilisateur, outil, durée, nombre de lignes et succès, mais pas les résultats sensibles. Ajoutez quotas et limites de connexions. Pour toute écriture, créez un autre rôle, imposez confirmation humaine et idempotence ; ne transformez pas l’outil read-only en SQL arbitraire.

FAQ

Pourquoi utiliser des vues ?

Elles stabilisent le contrat et réduisent les colonnes accessibles même si l’outil comporte un défaut.

MCP remplace-t-il les autorisations PostgreSQL ?

Non. MCP décrit et transporte les outils ; la base et l’application doivent toujours appliquer le moindre privilège.

Sources utilisées