ClickHouse
officielInterrogez votre serveur de base de données ClickHouse.
Que pouvez-vous faire avec ClickHouse MCP ?
- Exécuter des requêtes SQL — Demandez d'exécuter toute requête SQL sur votre cluster ClickHouse via
run_query, avec des paramètres nommés facultatifs. - Lister les bases de données — Demandez de voir toutes les bases de données disponibles sur votre cluster ClickHouse en utilisant
list_databases. - Parcourir les tables avec des filtres — Demandez de lister les tables d'une base de données avec des motifs
LIKE/NOT LIKEet une pagination vialist_tables. - Inspecter le schéma d'une requête — Demandez de vérifier les colonnes et types de sortie d'une requête avant de l'exécuter en utilisant
DESCRIBE. - Estimer le coût d'une requête — Demandez d'apercevoir les lectures estimées (parties, lignes, marques) pour un
SELECTen utilisantEXPLAIN ESTIMATE.
Documentation
Serveur MCP ClickHouse
Un serveur MCP pour ClickHouse.
Le serveur implémente MCP 2026-07-28 et prend en charge les poignées de main initialize héritées de
2024-11-05 à 2025-11-25. Les clients modernes utilisent des requêtes sans session et
server/discover. Les clients existants peuvent continuer à négocier le protocole hérité.
[!NOTE] Les requêtes HTTP sans
MCP-Protocol-Versionsont routées via le traitement hérité afin que les clients antérieurs à2025-06-18puissent continuer à se connecter. MCP2026-07-28permet ce comportement sur les serveurs qui prennent en charge ces clients. Les clients modernes doivent envoyer l'en-tête sur chaque requête POST.
Fonctionnalités
Outils ClickHouse
Les réponses des outils ClickHouse sont des chaînes encodées en JSON. Les entiers en dehors de
[-9007199254740991, 9007199254740991] sont renvoyés sous forme de chaînes décimales pour préserver les valeurs
exactes dans les clients JavaScript. Cela s'applique aux lignes de requête et aux métadonnées de table entières. Les entiers
dans la plage sûre et les booléens conservent leurs types JSON.
-
run_query- Exécutez des requêtes SQL sur votre cluster ClickHouse.
- Entrée :
query(chaîne) : la requête SQL à exécuter. - Entrée facultative :
params(objet) : valeurs nommées pour les espaces réservés ClickHouse{name:Type}. Voir Paramètres de requête. - Les requêtes s'exécutent en mode lecture seule par défaut (
CLICKHOUSE_ALLOW_WRITE_ACCESS=false), mais les écritures peuvent être activées explicitement si nécessaire. DESCRIBE (<query>)etEXPLAIN ESTIMATE <query>s'exécutent également ici et sont des moyens facultatifs d'inspecter le schéma de résultat d'une requête ou ses lectures estimées. Voir Vérifier une requête avant de l'exécuter.
-
list_databases- Liste toutes les bases de données sur votre cluster ClickHouse.
-
list_tables- Liste les tables d'une base de données avec pagination.
- Entrée requise :
database(chaîne). - Entrées facultatives :
like/not_like(chaîne) : applique des filtresLIKEouNOT LIKEaux noms de tables.page_token(chaîne) : jeton à usage unique renvoyé par un appel précédent. Il est conservé jusqu'à une heure.page_size(entier, défaut50) : nombre de tables renvoyées par page ; doit être supérieur à0.include_detailed_columns(booléen, défauttrue) : lorsquefalse, omet les métadonnées de colonnes pour des réponses plus légères tout en conservant lecreate_table_querycomplet.
- Forme de la réponse :
tables: tableau d'objets de table pour la page courante.next_page_token: renvoyez cette valeur à usage unique avant son expiration pour récupérer la page suivante, ounulllorsqu'il n'y a plus de tables.total_tables: nombre total de tables correspondant aux filtres fournis.
Paramètres de requête
Passez les valeurs séparément du SQL via l'objet facultatif params :
{
"query": "SELECT {id:UInt32} AS id, {name:String} AS name",
"params": {"id": 13, "name": "O'Reilly"}
}
Utilisez les espaces réservés {name:Type} de ClickHouse sans les mettre entre guillemets. Gardez l'accolade
ouvrante, le nom et les deux-points adjacents, comme dans {id:UInt32}. Les espaces après les deux-points et
dans le type sont pris en charge, comme dans {id: UInt32} et {amount:Decimal(18, 4)}.
Pour la compatibilité entre les versions de pilotes prises en charge, commencez les noms par une lettre ou un
trait de soulignement et utilisez uniquement des lettres, des chiffres et des traits de soulignement.
Le formatage de style Python %s ou %(name)s et les paramètres binaires bruts $name$ du pilote
ne sont pas pris en charge. Les appels avec uniquement query fonctionnent toujours. Omettre params,
passer null ou passer un objet vide laisse la requête non liée.
Les valeurs de paramètres peuvent être des chaînes JSON, des nombres, des booléens, null ou des tableaux, à condition
qu'elles correspondent au type ClickHouse déclaré :
- Utilisez
nullavec un typeNullable(...). - Passez les entiers exacts en dehors de la plage sûre de JavaScript sous forme de chaînes décimales, par
exemple
"18446744073709551615"avec{id:UInt64}. Les dates, horodatages et décimales exactes peuvent également être passés sous forme de chaînes avec le type ClickHouse correspondant. - Liez les vecteurs comme un seul tableau, par exemple
{vector:Array(Float32)}avec"params": {"vector": [0.25, 0.5, 0.75]}. - Les valeurs nulles dans les tableaux dépendent du pilote installé. Elles fonctionnent avec clickhouse-connect 1.8.0 mais échouent avec le minimum pris en charge 1.0.0.
- Les listes et objets JSON ne peuvent pas être liés aux types ClickHouse
TupleetMap.
Les valeurs manquantes et les types incompatibles renvoient des erreurs de requête. Avec un params non vide,
une requête contenant de nombreux débuts d'espaces réservés {name: non terminés est rejetée, y compris
le texte ressemblant à des espaces réservés dans les commentaires ou les littéraux de chaîne.
Les requêtes paramétrées utilisent la même protection en écriture, les mêmes délais d'attente, la même annulation et le même
encodage de résultat JSON que les autres requêtes.
Les valeurs de paramètres restent hors des messages de journal SQL normaux du serveur MCP, mais restent
dans les arguments d'outils MCP et peuvent apparaître dans les erreurs backend. ClickHouse 26.3.20.7
substitue les valeurs dans le texte de la requête dans system.query_log, system.processes,
et system.text_log. La liaison de paramètres n'est pas une fonctionnalité de confidentialité et ne
réduit pas le nombre de valeurs vectorielles envoyées dans un appel d'outil.
Vérifier une requête avant de l'exécuter
run_query exécute également DESCRIBE et EXPLAIN ESTIMATE. Les deux sont des vérifications facultatives : utilisez DESCRIBE lorsque vous avez besoin des colonnes et types de sortie d'une requête, et EXPLAIN ESTIMATE avant un SELECT qui pourrait être coûteux.
DESCRIBE (<query>) inspecte le schéma de résultat et renvoie les mêmes métadonnées de colonnes de sortie que DESCRIBE TABLE :
DESCRIBE (SELECT user, sum(amt) FROM events WHERE ts > now() - INTERVAL 30 DAY GROUP BY user)
user String
sum(amt) Decimal(38, 2)
ClickHouse doit analyser la requête pour répondre, donc les erreurs d'analyse apparaissent ici, avec le message propre de ClickHouse, au lieu de se produire en cours d'exécution :
DESCRIBE (SELECT usr FROM events) -> Code: 47. Unknown expression identifier `usr` ... Maybe you meant: ['user']
DESCRIBE (SELECT * FROM nosuch) -> Code: 60. Unknown table expression identifier 'nosuch'
Une requête qui se décrit proprement peut encore échouer lors de son exécution, sur une limite de mémoire ou une erreur de serveur distant, et elle ne dit rien sur le coût.
EXPLAIN ESTIMATE <query> renvoie les parties, lignes et marques que la requête lirait, une ligne par table, ce qui distingue une recherche par clé primaire d'un balayage complet :
EXPLAIN ESTIMATE SELECT count() FROM events WHERE id = 42
database table parts rows marks
default events 1 8192 1
Ce sont des lectures estimées des tables de la famille MergeTree, après élagage de la clé primaire et des partitions. Ce ne sont ni des temps d'exécution ni des tailles de résultat, et les autres moteurs de table ne sont pas couverts.
Aucune des deux instructions n'exécute le corps de la requête, mais l'analyse n'est pas toujours gratuite : DESCRIBE (SELECT (SELECT sleep(1))) exécute la sous-requête scalaire lors de l'analyse. Les deux sont en lecture seule et fonctionnent sous le CLICKHOUSE_ALLOW_WRITE_ACCESS=false par défaut. Voir la documentation ClickHouse pour EXPLAIN ESTIMATE et DESCRIBE.
Outils chDB
run_chdb_select_query- Exécutez des requêtes SQL en utilisant le moteur ClickHouse embarqué de chDB.
- Entrée :
query(chaîne) : la requête SQL à exécuter. - Les entiers en dehors de
[-9007199254740991, 9007199254740991]sont renvoyés sous forme de chaînes décimales. - Interrogez directement les données de diverses sources (fichiers, URL, bases de données) sans processus ETL.
- Nécessite l'extra facultatif
chdb:pip install 'mcp-clickhouse[chdb]'
Point de terminaison de vérification de santé
Lors de l'exécution avec un transport HTTP ou SSE, un point de terminaison de vérification de santé est disponible à /health. Ce point de terminaison :
- Renvoie
200 OK(corps :OK) si le serveur est sain et peut se connecter à ClickHouse - Renvoie
503 Service Unavailableavec un message d'erreur générique si le serveur ne peut pas se connecter à ClickHouse - Renvoie
503si une sonde ClickHouse ne se termine pas dans les deux secondes. Les requêtes concurrentes partagent une seule sonde en vol - Réutilise un résultat de sonde terminé pendant une seconde, donc les sondes qui arrivent en succession rapide ne se connectent pas chacune à ClickHouse. Un échec ou une récupération peut donc être signalé jusqu'à une seconde en retard
Les requêtes GET et HEAD vers le point de terminaison sont intentionnellement non authentifiées et exemptées de la validation Host et Origin afin que les sondes d'orchestration (par exemple, liveness/readiness Kubernetes, équilibreurs de charge) puissent utiliser des IP de pod ou cibles assignées à l'exécution sans configuration supplémentaire. /health est réservé et ne peut pas être utilisé comme chemin de transport MCP. Le corps de la réponse est délibérément minimal pour éviter de fuir les chaînes de version backend ou les détails d'erreur ; déboguez les échecs via les journaux du serveur.
Exemple :
curl http://localhost:8000/health
# Response: OK
Sécurité
Authentification pour les transports HTTP/SSE
Lors de l'utilisation d'un transport HTTP ou SSE, l'authentification est requise par défaut. Le transport stdio (par défaut) ne nécessite pas d'authentification car il ne communique que via l'entrée/sortie standard.
Trois modes d'authentification sont pris en charge. Choisissez-en un :
| Mode | Quand l'utiliser | Variable d'environnement |
|---|---|---|
| Jeton porteur statique | Déploiements simples, services internes | CLICKHOUSE_MCP_AUTH_TOKEN |
| OAuth / OIDC (via FastMCP) | Azure Entra, Google, GitHub, WorkOS, etc. | FASTMCP_SERVER_AUTH=<provider-class-path> (+ variables FASTMCP_SERVER_AUTH_* spécifiques au fournisseur) |
| Désactivé | Développement local uniquement | CLICKHOUSE_MCP_AUTH_DISABLED=true |
Le démarrage échoue si aucun de ces éléments n'est configuré pour les transports HTTP/SSE.
Configuration de l'authentification
-
Générez un jeton sécurisé (peut être n'importe quelle chaîne aléatoire) :
# Using uuidgen (macOS/Linux) uuidgen # Using openssl openssl rand -hex 32 -
Configurez le serveur avec le jeton :
export CLICKHOUSE_MCP_AUTH_TOKEN="your-generated-token" -
Configurez votre client MCP pour inclure le jeton dans les requêtes :
Pour Claude Desktop avec transport HTTP/SSE :
{ "mcpServers": { "mcp-clickhouse": { "url": "http://127.0.0.1:8000", "headers": { "Authorization": "Bearer your-generated-token" } } } }Remarque : le point de terminaison
/healthest intentionnellement non authentifié (voir Point de terminaison de vérification de santé ci-dessus). Pour vérifier que l'authentification par jeton porteur rejette réellement les requêtes non authentifiées, frappez le point de terminaison MCP lui-même, par exemple avec l'inspecteur MCP, ou en POSTant une requête JSON-RPC à/mcpavec et sans l'en-têteAuthorizationet en confirmant que l'appel non authentifié renvoie401.
OAuth / OIDC via FastMCP
Pour les déploiements de production avec des fournisseurs d'identité (Azure Entra, Google, GitHub, WorkOS, etc.), déléguez l'authentification aux fournisseurs d'authentification intégrés de FastMCP au lieu d'utiliser un jeton statique. Définissez FASTMCP_SERVER_AUTH sur le chemin de classe complet d'un fournisseur d'authentification FastMCP, avec les variables FASTMCP_SERVER_AUTH_* spécifiques au fournisseur, et laissez CLICKHOUSE_MCP_AUTH_TOKEN non défini.
Exemple (Azure Entra) :
export FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.azure.AzureProvider
export FASTMCP_SERVER_AUTH_AZURE_TENANT_ID="<tenant-id>"
export FASTMCP_SERVER_AUTH_AZURE_CLIENT_ID="<client-id>"
export FASTMCP_SERVER_AUTH_AZURE_CLIENT_SECRET="<client-secret>"
export FASTMCP_SERVER_AUTH_AZURE_BASE_URL="https://mcp.example.com"
export FASTMCP_SERVER_AUTH_AZURE_REQUIRED_SCOPES="read access_as_user"
mcp-clickhouse conserve ces préfixes d'environnement FastMCP 2.14.7 pour les fournisseurs intégrés FastMCP 4.0.0 :
| Chemin de classe du fournisseur | Préfixe de variable du fournisseur |
|---|---|
fastmcp.server.auth.providers.auth0.Auth0Provider | FASTMCP_SERVER_AUTH_AUTH0_ |
fastmcp.server.auth.providers.aws.AWSCognitoProvider | FASTMCP_SERVER_AUTH_AWS_COGNITO_ |
fastmcp.server.auth.providers.azure.AzureProvider | FASTMCP_SERVER_AUTH_AZURE_ |
fastmcp.server.auth.providers.descope.DescopeProvider | FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_ |
fastmcp.server.auth.providers.discord.DiscordProvider | FASTMCP_SERVER_AUTH_DISCORD_ |
fastmcp.server.auth.providers.github.GitHubProvider | FASTMCP_SERVER_AUTH_GITHUB_ |
fastmcp.server.auth.providers.google.GoogleProvider | FASTMCP_SERVER_AUTH_GOOGLE_ |
fastmcp.server.auth.providers.introspection.IntrospectionTokenVerifier | FASTMCP_SERVER_AUTH_INTROSPECTION_ |
fastmcp.server.auth.providers.jwt.JWTVerifier | FASTMCP_SERVER_AUTH_JWT_ |
fastmcp.server.auth.providers.oci.OCIProvider | FASTMCP_SERVER_AUTH_OCI_ |
fastmcp.server.auth.providers.scalekit.ScalekitProvider | FASTMCP_SERVER_AUTH_SCALEKITPROVIDER_ |
fastmcp.server.auth.providers.supabase.SupabaseProvider | FASTMCP_SERVER_AUTH_SUPABASE_ |
fastmcp.server.auth.providers.workos.WorkOSProvider | FASTMCP_SERVER_AUTH_WORKOS_ |
fastmcp.server.auth.providers.workos.AuthKitProvider | FASTMCP_SERVER_AUTH_AUTHKITPROVIDER_ |
Ajoutez le nom de champ du fournisseur en majuscules au préfixe. Voir la documentation FastMCP pour les exigences de configuration de chaque fournisseur.
Les valeurs d'authentification définies directement dans l'environnement du processus ont priorité, sans tenir compte de la casse.
Le chargement par défaut de .env commence dans le répertoire du paquet mcp_clickhouse installé,
résout d'abord les liens symboliques, puis remonte jusqu'à la racine du système de fichiers. Il charge le premier
.env qu'il trouve et ne charge rien s'il n'y en a pas. Il ne lit jamais le répertoire de travail,
quelle que soit la manière dont le serveur est lancé. Une copie du code source trouve normalement
le .env à la racine du dépôt. Ce fichier peut également fournir FASTMCP_SERVER_AUTH et ses
champs de fournisseur. Ses valeurs ont priorité sur le fichier d'authentification explicite ou de compatibilité.
Pour la compatibilité FastMCP 2, mcp-clickhouse lit les champs de fournisseur manquants depuis .env
dans le répertoire de travail, mais ce repli de compatibilité ne peut pas sélectionner
FASTMCP_SERVER_AUTH. Un FASTMCP_ENV_FILE défini dans le processus remplace ce repli
de compatibilité et peut fournir à la fois le sélecteur et les champs de fournisseur. Définissez-le avant le démarrage.
Le chargeur de compatibilité mcp-clickhouse ne lit que FASTMCP_SERVER_AUTH et
FASTMCP_SERVER_AUTH_* de ce fichier, il ne peut donc pas injecter de paramètres CLICKHOUSE_*.
FastMCP 4 peut utiliser le même fichier pour ses propres paramètres plus larges. Un fournisseur personnalisé ne reçoit
aucun argument de constructeur dérivé de l'environnement et doit prendre en charge la construction sans argument.
Traitez à la fois les fichiers .env découverts et ceux du répertoire de travail comme une configuration
d'authentification de confiance. Toute personne pouvant créer ou écrire un .env dans n'importe quel répertoire
du paquet jusqu'à la racine du système de fichiers peut contrôler quel fichier est découvert, sélectionner le
fournisseur et définir ses champs. Toute personne pouvant écrire le fichier du répertoire de travail contrôle chaque champ
de fournisseur absent du processus et de la configuration découverte, y compris les clés de signature,
les émetteurs et les points de terminaison, ainsi que les secrets clients. Un FASTMCP_ENV_FILE défini dans le processus
qui pointe vers un fichier appartenant à l'opérateur désactive le repli du répertoire de travail.
FastMCP 4 a modifié le stockage par défaut du proxy client OAuth. Les déploiements qui dépendaient du stockage par défaut du proxy OAuth de FastMCP 2 doivent faire réenregistrer et réautoriser les clients. Le stockage personnalisé compatible, les jetons porteurs statiques et la vérification JWT ne sont pas affectés.
Mode Développement (Désactivation de l'Authentification)
Pour le développement local et les tests uniquement, vous pouvez désactiver l'authentification en définissant :
export CLICKHOUSE_MCP_AUTH_DISABLED=true
export CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000
AVERTISSEMENT : Utilisez ceci uniquement pour le développement local. Ne désactivez pas l'authentification lorsque le serveur est exposé à un réseau.
Configuration
Ce serveur MCP prend en charge à la fois ClickHouse et chDB. Vous pouvez activer l'un ou l'autre, ou les deux, selon vos besoins. Python 3.10 à 3.14 sont pris en charge. Python 3.12 est recommandé pour les lancements locaux.
-
Ouvrez le fichier de configuration de Claude Desktop situé à :
- Sur macOS :
~/Library/Application Support/Claude/claude_desktop_config.json - Sur Windows :
%APPDATA%/Claude/claude_desktop_config.json
- Sur macOS :
-
Ajoutez ce qui suit :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_ROLE": "<clickhouse-role>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Mettez à jour les variables d'environnement pour pointer vers votre propre service ClickHouse.
Ou, si vous souhaitez l'essayer avec le SQL Playground ClickHouse, vous pouvez utiliser la configuration suivante :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "sql-clickhouse.clickhouse.com",
"CLICKHOUSE_PORT": "8443",
"CLICKHOUSE_USER": "demo",
"CLICKHOUSE_PASSWORD": "",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Pour chDB (moteur ClickHouse embarqué), ajoutez la configuration suivante :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse[chdb]",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CHDB_ENABLED": "true",
"CLICKHOUSE_ENABLED": "false",
"CHDB_DATA_PATH": "/path/to/chdb/data"
}
}
}
}
Vous pouvez également activer à la fois ClickHouse et chDB simultanément :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse[chdb]",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30",
"CHDB_ENABLED": "true",
"CHDB_DATA_PATH": "/path/to/chdb/data"
}
}
}
}
-
Localisez l'entrée de commande pour
uvet remplacez-la par le chemin absolu vers l'exécutableuv. Cela garantit que la version correcte deuvest utilisée au démarrage du serveur. Sur un Mac, vous pouvez trouver ce chemin en utilisantwhich uv. -
Redémarrez Claude Desktop pour appliquer les modifications.
Accès en Écriture Optionnel
Par défaut, ce MCP impose des requêtes en lecture seule afin que des mutations accidentelles ne puissent pas se produire pendant l'exploration. Pour autoriser les instructions DDL ou INSERT, définissez la variable d'environnement CLICKHOUSE_ALLOW_WRITE_ACCESS sur true. Le serveur continue d'imposer le mode lecture seule si l'instance ClickHouse elle-même interdit les écritures.
Protection contre les Opérations Destructrices
Même lorsque l'accès en écriture est activé (CLICKHOUSE_ALLOW_WRITE_ACCESS=true), les opérations destructrices nécessitent un indicateur d'adhésion supplémentaire pour la sécurité. La vérification couvre toute instruction DROP (y compris les clauses ALTER TABLE ... DROP PARTITION / DROP PART / DROP COLUMN), tout TRUNCATE, DELETE et UPDATE (à la fois les instructions légères et les mutations ALTER TABLE ... DELETE / ALTER TABLE ... UPDATE), REPLACE TABLE, CREATE OR REPLACE, ALTER TABLE ... REPLACE PARTITION, ALTER TABLE ... CLEAR COLUMN / CLEAR INDEX / CLEAR PROJECTION, et DETACH ... PERMANENTLY. Les mots-clés dans les littéraux de chaîne, les identifiants entre guillemets, les commentaires SQL et les noms de paramètres {name:Type} sont ignorés, donc ils ne déclenchent pas la vérification ni ne masquent une instruction de celle-ci.
Cette vérification s'exécute dans le serveur MCP et constitue une protection de bonne foi contre les accidents. Ce n'est pas une frontière de sécurité. La frontière de sécurité est constituée par les privilèges de l'utilisateur ClickHouse. Le mode lecture seule (par défaut) est appliqué côté serveur via readonly=1. La barrière des opérations destructrices n'est pas appliquée côté serveur.
Pour le mode écriture, donnez au serveur MCP un utilisateur ClickHouse dédié avec uniquement les privilèges dont il a besoin :
CREATE USER mcp_agent IDENTIFIED BY '...';
GRANT SELECT, INSERT, CREATE TABLE, ALTER ADD COLUMN ON mydb.* TO mcp_agent;
Toute instruction en dehors de ces privilèges échoue alors côté serveur avec ACCESS_DENIED, indépendamment des indicateurs MCP. Les paramètres serveur max_table_size_to_drop et max_partition_size_to_drop peuvent également limiter le rayon d'impact s'ils sont épinglés avec des contraintes de paramètres.
Pour activer les opérations destructrices, définissez les deux indicateurs :
"env": {
"CLICKHOUSE_ALLOW_WRITE_ACCESS": "true",
"CLICKHOUSE_ALLOW_DROP": "true"
}
Cette approche à deux niveaux rend la suppression accidentelle difficile :
- Opérations d'écriture (INSERT, CREATE, ALTER ADD COLUMN) nécessitent
CLICKHOUSE_ALLOW_WRITE_ACCESS=true - Opérations destructrices (DROP, TRUNCATE, DELETE, UPDATE, et le reste de la liste ci-dessus) nécessitent en plus
CLICKHOUSE_ALLOW_DROP=true
Exécution Sans uv (Utilisation de Python Système)
Si vous préférez utiliser l'installation Python système au lieu de uv, vous pouvez installer le paquet depuis PyPI et l'exécuter directement :
-
Installez le paquet en utilisant pip :
python3 -m pip install mcp-clickhousePour installer également le support chDB :
python3 -m pip install 'mcp-clickhouse[chdb]'Pour mettre à niveau vers la dernière version :
python3 -m pip install --upgrade mcp-clickhouse -
Mettez à jour votre configuration Claude Desktop pour utiliser Python directement :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "python3",
"args": [
"-m",
"mcp_clickhouse.main"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Alternativement, vous pouvez utiliser le script installé directement :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "mcp-clickhouse",
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Remarque : Assurez-vous d'utiliser le chemin complet vers l'exécutable Python ou le script mcp-clickhouse s'ils ne sont pas dans votre PATH système. Vous pouvez trouver les chemins en utilisant :
which python3pour l'exécutable Pythonwhich mcp-clickhousepour le script installé
Middleware Personnalisé
Vous pouvez ajouter un middleware personnalisé au serveur MCP sans modifier le code source. FastMCP fournit un système de middleware qui vous permet d'intercepter et de traiter les messages du protocole MCP (appels d'outils, lectures de ressources, invites, etc.).
Comment l'Utiliser
- Créez un module Python avec des classes de middleware étendant
Middlewareet une fonctionsetup_middleware(mcp):
# my_middleware.py
import logging
from fastmcp.server.middleware import Middleware, MiddlewareContext, CallNext
logger = logging.getLogger("my-middleware")
class LoggingMiddleware(Middleware):
"""Log all tool calls."""
async def on_call_tool(self, context: MiddlewareContext, call_next: CallNext):
tool_name = context.message.name if hasattr(context.message, 'name') else 'unknown'
logger.info(f"Calling tool: {tool_name}")
result = await call_next(context)
logger.info(f"Tool {tool_name} completed")
return result
def setup_middleware(mcp):
"""Register middleware with the MCP server."""
mcp.add_middleware(LoggingMiddleware())
- Définissez la variable d'environnement
MCP_MIDDLEWARE_MODULEsur le nom du module (sans l'extension.py) :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": ["run", "--with", "mcp-clickhouse", "--python", "3.12", "mcp-clickhouse"],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"MCP_MIDDLEWARE_MODULE": "my_middleware"
}
}
}
}
- Assurez-vous que votre module de middleware est dans le chemin d'importation de Python (par exemple, dans le même répertoire où le serveur MCP s'exécute, ou installé comme un paquet).
Exemple de Middleware
Un module de middleware d'exemple est fourni dans example_middleware.py montrant des modèles courants :
- Journalisation de toutes les requêtes MCP
- Journalisation des appels d'outils spécifiquement
- Mesure du temps de traitement des requêtes
Pour utiliser l'exemple :
"env": {
"MCP_MIDDLEWARE_MODULE": "example_middleware"
}
Capacités du Middleware
La classe de base Middleware fournit des hooks pour différentes opérations MCP :
on_message(context, call_next)- Appelé pour tous les messageson_request(context, call_next)- Appelé pour toutes les requêteson_notification(context, call_next)- Appelé pour toutes les notificationson_call_tool(context, call_next)- Appelé lorsqu'un outil est exécutéon_read_resource(context, call_next)- Appelé lorsqu'une ressource est lueon_get_prompt(context, call_next)- Appelé lorsqu'une invite est récupéréeon_list_tools(context, call_next)- Appelé lors de la liste des outilson_list_resources(context, call_next)- Appelé lors de la liste des ressourceson_list_resource_templates(context, call_next)- Appelé lors de la liste des modèles de ressourceson_list_prompts(context, call_next)- Appelé lors de la liste des invites
Chaque hook reçoit un objet MiddlewareContext contenant le message et les métadonnées, et une fonction call_next pour continuer le pipeline.
Configuration Dynamique du Client via l'État de Contexte
Le middleware peut remplacer la configuration du client ClickHouse par requête en utilisant la clé d'état de contexte CLIENT_CONFIG_OVERRIDES_KEY. Le serveur fusionne ces remplacements avec la configuration de base provenant des variables d'environnement.
from fastmcp.server.dependencies import get_context
from fastmcp.server.middleware import CallNext, Middleware, MiddlewareContext
from mcp_clickhouse.mcp_server import CLIENT_CONFIG_OVERRIDES_KEY
class ClientConfigMiddleware(Middleware):
async def on_call_tool(self, context: MiddlewareContext, call_next: CallNext):
ctx = get_context()
await ctx.set_state(
CLIENT_CONFIG_OVERRIDES_KEY,
{
"connect_timeout": 60,
"send_receive_timeout": 120,
},
serializable=False,
)
return await call_next(context)
Cela permet des cas d'utilisation avancés comme les ajustements dynamiques de délai d'attente, le routage spécifique au locataire ou les paramètres de connexion par utilisateur.
La valeur d'état doit être un dictionnaire. Les valeurs imbriquées settings et generic_args doivent être des
mappings et sont fusionnées avec la configuration de base. Les valeurs invalides font échouer l'appel d'outil avant
qu'un client ClickHouse ne soit créé. CLICKHOUSE_ROLE reste actif sauf si le remplacement fournit explicitement
settings.role. Les clés de niveau supérieur role et ch_role, ainsi que les mêmes clés sous
generic_args, sont rejetées.
Définissez verify, ca_cert, client_cert, client_cert_key, tls_mode, server_host_name,
et pool_mgr uniquement comme remplacements de niveau supérieur. Ils ne peuvent pas être imbriqués sous generic_args. Un
pool_mgr personnalisé ne peut pas être combiné avec les paramètres de certificat client ou d'autorité de certification gérés. Les paramètres de requête DSN
ne peuvent pas définir ces clés, et un DSN ne peut pas sélectionner le backend chdb. Utilisez des remplacements explicites
de niveau supérieur host, port, username, password, database et secure pour modifier
la connexion. Un DSN transféré ne remplace pas les champs de connexion de base remplis ni ne sélectionne
TLS. Il peut remplir les champs vides et fournir des paramètres de requête pris en charge tels que query_limit.
Les remplacements secure et verify acceptent les booléens ou les chaînes true et false.
verify accepte également proxy, qui se comporte comme
tls_mode: proxy lorsque tls_mode n'est pas défini et utilise donc l'authentification Basic avec le
mot de passe de l'environnement. Un remplacement secure sélectionne l'interface https ou http correspondante et
ne change pas le port. Un remplacement explicite interface doit être http ou https et être en accord
avec secure. Après la fusion des remplacements, les modes de certificat client par défaut et mutual omettent le
mot de passe. Les modes proxy et strict utilisent l'authentification Basic avec le mot de passe de l'environnement
sauf si le remplacement fournit ses propres informations d'identification.
Traitez ces remplacements comme une entrée de middleware de confiance. Le middleware doit authentifier et autoriser
les valeurs dérivées des requêtes avant de les définir. Utilisez serializable=False afin que FastMCP conserve la
valeur dans l'état local de la requête. Le serializable=True par défaut stocke l'état de session et est
rejeté par le serveur. Le serveur prend un instantané de la valeur avant de répartir le travail de base de données bloquant.
Ne stockez pas de données de locataire dans l'état de contexte de session. Un remplacement de session rejeté
reste attaché à une session MCP héritée et provoque l'échec des appels d'outils ultérieurs dans cette session
jusqu'à ce que le client se reconnecte. Un rôle ClickHouse par requête est une configuration de connexion,
pas une frontière d'autorisation de locataire. Appliquez l'isolation des locataires avec les utilisateurs, rôles
et privilèges ClickHouse.
Développement
-
Dans le répertoire
test-services, exécutezdocker compose up -dpour démarrer le cluster ClickHouse. -
Ajoutez les variables suivantes à un fichier
.envà la racine du dépôt.
Remarque : L'utilisation de l'utilisateur default dans ce contexte est destinée uniquement au développement local.
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
-
Exécutez
uv syncpour installer les dépendances. Pour installeruv, suivez les instructions ici. Ensuite, faitessource .venv/bin/activate. -
Pour des tests faciles avec l'inspecteur MCP, exécutez
uv run fastmcp dev inspector mcp_clickhouse/mcp_server.py:mcppour démarrer le serveur MCP. -
Pour tester avec le transport HTTP et le point de terminaison de vérification de santé :
# For development, disable authentication CLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_DISABLED=true CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000 python -m mcp_clickhouse.main # Or with authentication (generate a token first) CLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_TOKEN="your-token" python -m mcp_clickhouse.main # Then in another terminal: curl http://localhost:8000/health
Variables d'Environnement
La configuration est divisée en groupes indépendants. Les mélanger est une cause fréquente d’échecs de connexion difficiles à déboguer :
| Groupe | Variables | Contrôle |
|---|---|---|
| Connexion à la base de données ClickHouse | CLICKHOUSE_HOST, CLICKHOUSE_PORT, CLICKHOUSE_SECURE, CLICKHOUSE_VERIFY, variables de certificat | Comment ce serveur MCP se connecte à votre cluster ClickHouse via l’interface HTTP |
| Serveur MCP / transport | CLICKHOUSE_MCP_*, FASTMCP_SERVER_AUTH, FASTMCP_SERVER_AUTH_*, FASTMCP_ENV_FILE | Transport MCP, authentification et limites d’exécution des outils de requête |
| Middleware / chDB | MCP_MIDDLEWARE_MODULE, CHDB_* | Extensions optionnelles |
[!IMPORTANT]
CLICKHOUSE_SECURE,CLICKHOUSE_VERIFY,CLICKHOUSE_CA_CERT,CLICKHOUSE_CLIENT_CERT,CLICKHOUSE_CLIENT_CERT_KEY,CLICKHOUSE_TLS_MODEetCLICKHOUSE_PORTs’appliquent uniquement à la connexion sortante à la base de données ClickHouse. Ils ne configurent pas TLS, certificats clients, ports ou authentification pour le point de terminaison MCP entrant HTTP/SSE.Exemple : si le serveur MCP s’exécute dans Kubernetes derrière une passerelle d’entrée qui termine TLS, cela relève du transport MCP. Gardez
CLICKHOUSE_SECUREaligné sur la façon dont le pod atteint ClickHouse lui-même (HTTPS →true, HTTP simple →false). DéfinirCLICKHOUSE_SECURE=falseparce que le serveur MCP est derrière une passerelle d’entrée fera que le serveur se connectera à ClickHouse via HTTP—souvent sur un port HTTPS uniquement—et produira des erreurs HTTP/TLS opaques dans les journaux du serveur.
Connexion à la base de données ClickHouse
Ces variables configurent le client HTTP clickhouse-connect et le comportement des outils basés sur ClickHouse tels que run_query, list_databases et list_tables.
mcp-clickhouse nécessite clickhouse-connect 1.x, à partir de 1.0.0.
Variables requises
CLICKHOUSE_HOST: Le nom d’hôte de votre serveur ClickHouse (point de terminaison de la base de données, pas l’adresse de liaison du serveur MCP)CLICKHOUSE_USER: Le nom d’utilisateur pour l’authentification ClickHouseCLICKHOUSE_PASSWORD: Le mot de passe pour l’authentification ClickHouse- Requis sauf si
CLICKHOUSE_CLIENT_CERTutilise la valeur par défaut ou le mode TLS"mutual" - En mode par défaut ou
"mutual", l’authentification par certificat est utilisée et le mot de passe n’est pas envoyé
- Requis sauf si
[!CAUTION] Il est important de traiter votre utilisateur de base de données MCP comme vous le feriez pour tout client externe se connectant à votre base de données, en n’accordant que les privilèges minimum nécessaires à son fonctionnement. L’utilisation d’utilisateurs par défaut ou administratifs doit être strictement évitée à tout moment.
Variables optionnelles
CLICKHOUSE_PORT: Port de l’interface HTTP de votre serveur ClickHouse- Défaut :
8443siCLICKHOUSE_SECURE=true,8123siCLICKHOUSE_SECURE=false - Généralement inutile à définir sauf en cas de port non standard
- Doit être un port d’interface HTTP, pas le port du protocole TCP natif utilisé par
clickhouse-client - Valeurs courantes :
- HTTP :
8123(simple) /8443(TLS) — utilisé par ce serveur et ClickHouse Cloud HTTPS - TCP natif (non pris en charge ici) :
9000(simple) /9440(TLS) — utilisé parclickhouse-client
- HTTP :
- Si le serveur répond avec
Port 9000 is for clickhouse-client program, vous êtes dirigé vers le protocole natif ; passez au port HTTP (8123/8443ou le mappage HTTP de votre déploiement)
- Défaut :
CLICKHOUSE_ROLE: Le rôle ClickHouse à utiliser pour l’authentification- Défaut : Aucun
- Définissez-le si votre utilisateur nécessite un rôle spécifique
CLICKHOUSE_SECURE: Active HTTPS pour la connexion à la base de données ClickHouse (pas pour les clients MCP)- Défaut :
"true" - Définissez sur
"false"uniquement lorsque le serveur MCP atteint ClickHouse via HTTP simple (typique pour Docker Compose local sur le port8123) - Laissez
"true"pour ClickHouse Cloud et tout point de terminaison de base de données HTTPS—même si le serveur MCP lui-même est exposé via HTTP, stdio ou une passerelle d’entrée qui termine TLS séparément - Une inadéquation de ce drapeau avec le port de la base de données (par ex.
CLICKHOUSE_SECURE=falsecontre le port8443) est une erreur de configuration fréquente et se manifeste généralement par des erreurs de client HTTP déroutantes plutôt qu’un message clair de « schéma incorrect »
- Défaut :
CLICKHOUSE_VERIFY: Active/désactive la vérification des certificats SSL pour la connexion HTTPS ClickHouse- Défaut :
"true" - Définissez sur
"false"pour désactiver la vérification des certificats (non recommandé en production) - Certificats TLS : Le package utilise le magasin de confiance de votre système d’exploitation via
truststore.inject_into_ssl()au démarrage. La gestion SSL par défaut de Python est utilisée si l’injection est désactivée avecMCP_CLICKHOUSE_TRUSTSTORE_DISABLE=1ou échoue.
- Défaut :
MCP_CLICKHOUSE_TRUSTSTORE_DISABLE: Désactive l’intégration du magasin de confiance du système d’exploitation à l’échelle du processus pour TLS- Défaut : non défini (l’intégration du magasin de confiance est activée)
- Définissez exactement sur
"1"avant le démarrage pour ignorertruststore.inject_into_ssl()et utiliser la gestion SSL par défaut de Python. D’autres valeurs ne désactivent pas l’intégration. - Cela ne désactive pas la vérification des certificats.
CLICKHOUSE_VERIFYcontrôle toujours la vérification pour la connexion HTTPS ClickHouse.
CLICKHOUSE_CA_CERT: Chemin vers un bundle de certificats CA PEM pour la connexion HTTPS ClickHouse- Défaut : Aucun (utilise le magasin de confiance du système d’exploitation sauf si l’injection du magasin de confiance est désactivée ou échoue)
- Utilisez-le seul lorsqu’un serveur ClickHouse ou un proxy privé présente un certificat signé par une CA privée. Cela modifie la vérification du certificat du serveur et n’active pas l’authentification par certificat client.
- Nécessite
CLICKHOUSE_SECURE=trueetCLICKHOUSE_VERIFY=true
CLICKHOUSE_CLIENT_CERT: Chemin vers un certificat client PEM pour la connexion HTTPS ClickHouse- Défaut : Aucun
- Le fichier peut également contenir la clé privée. Sinon, définissez
CLICKHOUSE_CLIENT_CERT_KEY. - L’utilisateur ClickHouse provient toujours de
CLICKHOUSE_USER.
CLICKHOUSE_CLIENT_CERT_KEY: Chemin vers la clé privée PEM pourCLICKHOUSE_CLIENT_CERT- Défaut : Aucun
- Optionnel lorsque la clé privée est incluse dans le fichier de certificat client
- Ne peut pas être utilisé sans
CLICKHOUSE_CLIENT_CERT
CLICKHOUSE_TLS_MODE: Comment clickhouse-connect utiliseCLICKHOUSE_CLIENT_CERT- Défaut : Aucun, ce qui se comporte comme
"mutual"lorsqu’un certificat client est défini "mutual": Utilisez le certificat client pour l’authentification utilisateur X.509 ClickHouse.CLICKHOUSE_PASSWORDest optionnel et n’est pas envoyé."proxy": Présentez le certificat client à un proxy de terminaison TLS, puis utilisez l’authentification Basic ClickHouse.CLICKHOUSE_PASSWORDest requis."strict": Présentez le certificat client parce que le serveur ClickHouse en exige un au niveau de la couche TLS, puis utilisez l’authentification Basic ClickHouse.CLICKHOUSE_PASSWORDest requis. Ce mode ne renforce pas la vérification du certificat du serveur.CLICKHOUSE_VERIFYcontrôle cette vérification.- clickhouse-connect traite
"proxy"et"strict"de manière identique. Les deux noms documentent l’intention. - Les valeurs sont tronquées et insensibles à la casse. Une valeur vide est traitée comme non définie. D’autres valeurs sont rejetées avant la création d’un client ClickHouse, lors du premier appel d’outil ClickHouse ou de la sonde
/health. - Nécessite
CLICKHOUSE_CLIENT_CERT. Toutes les options de certificat client nécessitentCLICKHOUSE_SECURE=true.
- Défaut : Aucun, ce qui se comporte comme
CLICKHOUSE_SERVER_HOST_NAME: Nom d’hôte du serveur pour le remplacement SNI et la validation du certificat sur la connexion ClickHouse- Défaut : Aucun (utilise le nom d’hôte de la connexion)
- Utile lors de la connexion via des proxys ou des équilibreurs de charge où le nom d’hôte du certificat diffère du nom d’hôte de la connexion. Lorsqu’il est défini, ce nom d’hôte sera utilisé à la fois pour SNI (Server Name Indication) pendant la poignée de main TLS et pour la validation du nom d’hôte du certificat.
CLICKHOUSE_PROXY_PATH: Préfixe de chemin d’URL pour le point de terminaison HTTP ClickHouse- Défaut : Aucun
- Définissez-le lorsque l’interface HTTP ClickHouse est exposée derrière un proxy inverse sous un préfixe de chemin (par exemple,
/clickhouse)
CLICKHOUSE_CONNECT_TIMEOUT: Délai d’expiration de connexion en secondes pour le client ClickHouse- Défaut :
"30" - Augmentez cette valeur si vous rencontrez des délais d’expiration de connexion
- Défaut :
CLICKHOUSE_SEND_RECEIVE_TIMEOUT: Délai d’expiration d’envoi/réception en secondes pour le client ClickHouse- Défaut : la plus basse de
300ouCLICKHOUSE_MCP_QUERY_TIMEOUT + 5, afin que les threads de travail se débloquent peu après un délai d’expiration de requête - Si défini explicitement, la valeur est utilisée telle quelle (par ex.
"300"pour les requêtes de longue durée)
- Défaut : la plus basse de
CLICKHOUSE_DATABASE: Base de données ClickHouse par défaut à utiliser- Défaut : Aucun (utilise la valeur par défaut du serveur)
- Définissez-la pour vous connecter automatiquement à une base de données spécifique
CLICKHOUSE_ENABLED: Active/désactive les outils de base de données ClickHouse- Défaut :
"true" - Définissez sur
"false"pour désactiver les outils ClickHouse lors de l’utilisation de chDB uniquement
- Défaut :
CLICKHOUSE_ALLOW_WRITE_ACCESS: Autorise les opérations d’écriture (DDL et DML) contre ClickHouse- Défaut :
"false" - Définissez sur
"true"pour autoriser les DDL et DML non destructifs (CREATE, INSERT, ALTER ADD COLUMN). Les instructions destructives nécessitent en plusCLICKHOUSE_ALLOW_DROP=true - Lorsqu’elle est désactivée (par défaut), les requêtes s’exécutent avec le paramètre
readonly=1pour empêcher les modifications de données
- Défaut :
CLICKHOUSE_ALLOW_DROP: Autorise les opérations destructives (toutDROPouTRUNCATE,DELETEetUPDATEy compris les variantesALTER TABLE,REPLACE TABLE/REPLACE PARTITION/CREATE OR REPLACE,CLEAR COLUMN/CLEAR INDEX/CLEAR PROJECTIONetDETACH ... PERMANENTLY)- Défaut :
"false" - N’a d’effet que lorsque
CLICKHOUSE_ALLOW_WRITE_ACCESS=trueest également défini - Cette barrière est une protection contre les accidents au mieux dans le serveur MCP, pas une frontière de sécurité. Restreignez les autorisations de l’utilisateur ClickHouse pour une application réelle (voir Protection contre les opérations destructives)
- Défaut :
Fichiers de certificats TLS ClickHouse
Les variables de certificat contiennent des chemins de fichiers, pas des contenus PEM. mcp-clickhouse transmet ces chemins à clickhouse-connect. Pour Docker ou Kubernetes, montez le certificat et la clé privée en tant que fichiers en lecture seule et utilisez leurs chemins à l’intérieur du conteneur. Ne gravez pas une clé privée dans une image, ne la committez pas dans le contrôle de source et ne mettez pas son contenu dans une variable d’environnement.
En mode mutual, le certificat client configuré identifie ce processus mcp-clickhouse comme CLICKHOUSE_USER. Il n’authentifie pas les clients MCP entrants et ne transmet pas leurs identités à ClickHouse. Configurez l’authentification du transport MCP séparément.
Redémarrez mcp-clickhouse après avoir remplacé un certificat ou une clé au même chemin lorsqu’une rotation ou révocation immédiate est requise. Les clients mis en cache peuvent conserver des connexions TLS existantes, et le cache ne suit pas les contenus de fichiers ni les heures de modification.
ClickHouse Cloud ne prend pas en charge l’authentification par certificat client X.509 pour les utilisateurs de base de données. Utilisez CLICKHOUSE_USER et CLICKHOUSE_PASSWORD pour ClickHouse Cloud. Un certificat CA peut toujours être utile lorsqu’un proxy privé devant un point de terminaison présente un certificat signé par une CA privée.
Serveur MCP et transport
Ces variables contrôlent le processus MCP lui-même, y compris le transport, l’authentification et les limites d’exécution des outils de requête. Elles sont indépendantes des paramètres de base de données ClickHouse ci-dessus. Voir aussi Authentification pour les transports HTTP/SSE.
CLICKHOUSE_MCP_SERVER_TRANSPORT: définit la méthode de transport pour le serveur MCP- Par défaut :
"stdio" - Options valides :
"stdio","http","sse". Utile pour le développement local avec des outils comme MCP Inspector. stdioest typique pour Claude Desktop ;http/sseexposent un écouteur réseau (lier l'hôte/le port ci-dessous)"sse"sélectionne le transport autonome obsolète HTTP+SSE et journalise un avertissement. Utilisez"http"pour Streamable HTTP dans les nouveaux déploiements.
- Par défaut :
CLICKHOUSE_MCP_BIND_HOST: hôte auquel lier le serveur MCP lors de l'utilisation du transport HTTP ou SSE- Par défaut :
"127.0.0.1" - Définissez
"0.0.0.0"pour lier à toutes les interfaces réseau (utile pour Docker ou l'accès à distance) - Utilisé uniquement lorsque le transport est
"http"ou"sse"— sans rapport avecCLICKHOUSE_HOST
- Par défaut :
CLICKHOUSE_MCP_BIND_PORT: port auquel lier le serveur MCP lors de l'utilisation du transport HTTP ou SSE- Par défaut :
"8000" - Utilisé uniquement lorsque le transport est
"http"ou"sse"— sans rapport avecCLICKHOUSE_PORT
- Par défaut :
CLICKHOUSE_MCP_QUERY_TIMEOUT: délai d'expiration en secondes pour les appels d'outils de requête- Par défaut :
"30" - Augmentez-le si vous voyez des erreurs
Query timed out after ...pour les requêtes lourdes - Lorsqu'une requête expire, le serveur tente de l'annuler avec
KILL QUERY - Sauf si
CLICKHOUSE_SEND_RECEIVE_TIMEOUTest explicitement défini, le délai d'expiration de lecture HTTP est plafonné à cette valeur plus cinq secondes
- Par défaut :
CLICKHOUSE_MCP_MAX_WORKERS: nombre maximal de threads de travail de requête simultanés- Par défaut :
"10" - Augmentez si votre charge de travail nécessite de nombreux appels d'outils simultanés
- Les outils de métadonnées utilisent un pool séparé avec
min(4, CLICKHOUSE_MCP_MAX_WORKERS)threads afin que la découverte de schéma ne puisse pas retarder les requêtes
- Par défaut :
CLICKHOUSE_MCP_AUTH_TOKEN: jeton porteur statique pour les transports HTTP/SSE- Par défaut : aucun
- L'un de
CLICKHOUSE_MCP_AUTH_TOKEN,FASTMCP_SERVER_AUTHouCLICKHOUSE_MCP_AUTH_DISABLED=trueest requis pour les transports HTTP/SSE - Générez-le avec
uuidgenouopenssl rand -hex 32 - Les clients doivent envoyer ce jeton dans l'en-tête
Authorization: Bearer <token>
FASTMCP_SERVER_AUTH: délégation de l'authentification à un fournisseur d'authentification FastMCP- Par défaut : aucun
- La valeur est le chemin de classe complet d'une sous-classe AuthProvider, par exemple
fastmcp.server.auth.providers.azure.AzureProvideroufastmcp.server.auth.providers.google.GoogleProvider - Lorsqu'il est défini, mcp-clickhouse charge le fournisseur à partir des variables d'environnement
FASTMCP_SERVER_AUTH_*existantes ; laissezCLICKHOUSE_MCP_AUTH_TOKENnon défini dans ce mode - Les fournisseurs personnalisés ne reçoivent aucun argument de constructeur dérivé de l'environnement et doivent prendre en charge la construction sans argument
- FastMCP 4 ne prend plus en charge la vérification Supabase HS256. Les déploiements Supabase doivent utiliser RS256 ou ES256.
FASTMCP_ENV_FILE: fichier facultatif contenantFASTMCP_SERVER_AUTHet les variables d'environnement spécifiques au fournisseur- Par défaut : aucun. Lorsqu'il n'est pas défini, le chargeur de compatibilité lit les champs de fournisseur manquants à partir de
.envdans le répertoire de travail. Il ne lit pasFASTMCP_SERVER_AUTHà partir de ce repli - Définissez-le dans l'environnement du processus avant le démarrage. Une valeur chargée depuis le
.envpar défaut ne peut pas rediriger le chargeur de compatibilité - S'il est défini par le processus, ce fichier peut fournir à la fois
FASTMCP_SERVER_AUTHet les champs du fournisseur et remplace le repli du répertoire de travail - Les valeurs de l'environnement du processus ont priorité sans tenir compte de la casse
- Le chargeur de compatibilité mcp-clickhouse lit ce fichier uniquement lors de la construction de l'authentification HTTP/SSE et lit uniquement les entrées
FASTMCP_SERVER_AUTHetFASTMCP_SERVER_AUTH_*. FastMCP 4 peut lire le même fichier pour ses paramètres plus larges - Le chargement par défaut de
.envest séparé. Il commence dans le répertoire du paquetmcp_clickhouseinstallé, résout les liens symboliques, remonte jusqu'à la racine du système de fichiers et charge le premier.envtrouvé ou rien. Il ne lit jamais le répertoire de travail, quelle que soit la méthode de lancement. Ce fichier peut fournirFASTMCP_SERVER_AUTHet les champs du fournisseur ainsi que d'autres paramètres du serveur. Une copie source trouve normalement le.envracine du dépôt
- Par défaut : aucun. Lorsqu'il n'est pas défini, le chargeur de compatibilité lit les champs de fournisseur manquants à partir de
CLICKHOUSE_MCP_AUTH_DISABLED: désactivation de l'authentification pour les transports HTTP/SSE- Par défaut :
"false"(l'authentification est activée) - Définissez
"true"pour désactiver l'authentification uniquement pour le développement/les tests locaux - AVERTISSEMENT : à utiliser uniquement pour le développement local. Ne désactivez pas lorsque vous êtes exposé aux réseaux
- Par défaut :
CLICKHOUSE_MCP_ALLOWED_HOSTS: valeurs d'en-têteHostséparées par des virgules auxquelles le serveur HTTP/SSE répond- Par défaut pour une liaison en boucle : formes nues et tout-port de
127.0.0.1,localhostet[::1] - S'il est défini, la valeur doit contenir au moins une entrée Host.
- Une adresse de liaison concrète non-boucle par défaut correspond à cette adresse et au port configuré. Une liaison générique telle que
0.0.0.0ou::nécessite une valeur explicite non vide car le Host public ne peut pas être déduit. - La validation du Host est une défense en profondeur contre le rebinding DNS. La validation de l'origine ci-dessous est requise séparément par MCP.
- Les entrées sont exactes (
localhost:8000) ou acceptent n'importe quel port (localhost:*). Exemple :CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000 - La forme
host:*correspond uniquement aux valeurs qui portent un port. Un Host sans port (un déploiement à port standard où le client omet:80/:443) doit également être répertorié comme entrée exacte nue (example.com). - Les requêtes avec un en-tête
Hostnon correspondant ou manquant reçoivent421 Misdirected Request. Les requêtes GET et HEAD vers/healthsont exemptées de la validation Host et Origin afin que les sondes d'orchestration continuent de fonctionner. - Derrière un proxy inverse, préférez préserver l'en-tête
Hostd'origine. Vous pouvez plutôt répertorier la valeurHosten amont que le proxy envoie. Définissez une liste explicite lorsqu'un lanceur tel quefastmcp runremplace l'adresse de liaison pour l'accès à distance. - mcp-clickhouse force la désactivation de la garde Host et Origin séparée de FastMCP.
FASTMCP_HTTP_HOST_ORIGIN_PROTECTION,FASTMCP_HTTP_ALLOWED_HOSTSetFASTMCP_HTTP_ALLOWED_ORIGINSne s'appliquent pas.CLICKHOUSE_MCP_ALLOWED_HOSTSetCLICKHOUSE_MCP_ALLOWED_ORIGINSsont faisant autorité.
- Par défaut pour une liaison en boucle : formes nues et tout-port de
CLICKHOUSE_MCP_TRUSTED_PROXIES: adresses IP proxy ou réseaux CIDR dont les en-têtesX-Forwarded-*sont approuvés- Par défaut : aucun.
X-Forwarded-Hostest ignoré. La gestion existante d'Uvicorn deX-Forwarded-ForetX-Forwarded-Protoest inchangée. - Les entrées doivent être des adresses IP ou des réseaux CIDR, tels que
127.0.0.1,10.20.0.0/24,2001:db8::1. Les CIDR doivent utiliser leur adresse réseau, donc10.20.0.1/24est rejeté. Les noms d'hôte, les adresses IPv6 à portée,*,0.0.0.0/0et::/0sont également rejetés. - La confiance est basée sur le pair de socket brut immédiat. Une requête de tout autre pair, ou une requête sans adresse client, ignore
X-Forwarded-Hostet valideHost. - Un pair approuvé peut envoyer exactement un en-tête
X-Forwarded-Hostcontenant une valeur non vide. Les champs en double, les valeurs vides et les listes séparées par des virgules reçoivent421 Misdirected Request. Si l'en-tête est absent,Hostest validé. - Utilisez l'adresse ou le réseau le plus étroit possible. Le serveur MCP ne doit être accessible que via des proxys dans les plages configurées. Chaque proxy approuvé doit supprimer et écraser les valeurs
X-Forwarded-HostetX-Forwarded-Protofournies par le client, et construireX-Forwarded-Forà partir du pair de connexion vérifié. - Le serveur intégré et
fastmcp rundésactivent la gestion externe des en-têtes proxy d'Uvicorn, valident le Host à partir du pair brut, puis appliquentX-Forwarded-ForetX-Forwarded-Proto. L'activation explicite deuvicorn_config["proxy_headers"]échoue au démarrage dans ce mode. - L'intégration ASGI directe doit désactiver la gestion des en-têtes proxy dans le serveur ASGI externe et appeler
mcp.http_app(raw_client_address_preserved=True). Sans cette assertion explicite, la construction de l'application échoue lorsque des proxys approuvés sont configurés.
- Par défaut : aucun.
CLICKHOUSE_MCP_ALLOWED_ORIGINS: valeurs d'en-têteOriginséparées par des virgules acceptées sur HTTP/SSE- Par défaut : aucun, ce qui rejette chaque requête portant un en-tête
Origin - MCP exige la validation de l'origine pour les connexions de transport HTTP/SSE. Les requêtes sans Origin sont acceptées car les clients MCP non-navigateur l'omettent normalement. Une origine non correspondante reçoit
403 Forbidden. Le point de terminaison/healthest exempté comme décrit ci-dessus. - Les entrées sont exactes (
http://localhost:3000) ou acceptent n'importe quel port (http://localhost:*). Comme pour les hôtes, la forme tout-port correspond uniquement aux origines qui portent un port ; une origine à port standard (https://app.example.com) doit être répertoriée exactement.
- Par défaut : aucun, ce qui rejette chaque requête portant un en-tête
Gestion du Host du proxy inverse
Préservez Host lorsque c'est possible. Cela maintient la confiance du Host transféré désactivée :
location / {
proxy_pass http://mcp-clickhouse:8000;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
Assainissez X-Forwarded-For et X-Forwarded-Proto indépendamment de la confiance X-Forwarded-Host. Uvicorn peut faire confiance à ces en-têtes en fonction du pair proxy même lorsque CLICKHOUSE_MCP_TRUSTED_PROXIES n'est pas défini.
CLICKHOUSE_MCP_ALLOWED_HOSTS=mcp.example.com
Le nginx standard change Host en nom en amont pour les requêtes proxyées. Il ne crée ni n'écrase X-Forwarded-Host. Si la préservation de Host n'est pas possible, écrasez l'en-tête transféré à la périphérie approuvée :
location / {
proxy_pass http://mcp-clickhouse:8000;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
CLICKHOUSE_MCP_ALLOWED_HOSTS=mcp.example.com
CLICKHOUSE_MCP_TRUSTED_PROXIES=10.20.0.8
La deuxième configuration n'est sûre que lorsque 10.20.0.8 est l'adresse source immédiate du proxy, que le port du serveur est isolé des autres clients et que nginx écrase les en-têtes de transfert entrants comme indiqué. Pour une chaîne de proxys, chaque saut approuvé doit supprimer les valeurs entrantes non vérifiées avant de construire les nouveaux en-têtes de transfert.
Sur une liaison IPv6 ou double pile, les proxys IPv4 peuvent apparaître comme des adresses mappées IPv4 telles que ::ffff:10.20.0.8 ; celles-ci sont automatiquement comparées aux entrées IPv4. Le append_x_forwarded_host d'Envoy ajoute à un X-Forwarded-Host existant plutôt que de l'écraser, produisant une liste séparée par des virgules qui est rejetée, alors configurez le saut approuvé pour écraser l'en-tête à la place. Sur Kubernetes avec NAT source (par exemple externalTrafficPolicy: Cluster), le pair observé peut être une IP de nœud plutôt que le pod proxy, alors faites confiance au pod ou au CIDR du nœud selon le cas ; ingress-nginx écrase lui-même à la fois Host et X-Forwarded-Host.
Variables de middleware
MCP_MIDDLEWARE_MODULE: nom du module Python contenant le middleware personnalisé à injecter dans le serveur MCP- Par défaut : aucun (aucun middleware chargé)
- Définissez le nom du module (sans l'extension
.py) de votre module middleware - Le module doit fournir une fonction
setup_middleware(mcp) - Voir Middleware personnalisé pour les détails et les exemples
Variables chDB
CHDB_ENABLED: activer/désactiver la fonctionnalité chDB- Par défaut :
"false" - Définissez
"true"pour activer les outils chDB - Nécessite l'installation de l'extra optionnel :
mcp-clickhouse[chdb]
- Par défaut :
CHDB_DATA_PATH: le chemin vers le répertoire de données chDB- Par défaut :
":memory:"(base de données en mémoire) - Utilisez
:memory:pour la base de données en mémoire - Utilisez un chemin de fichier pour le stockage persistant (par exemple,
/path/to/chdb/data)
- Par défaut :
Pièges de configuration courants
CLICKHOUSE_SECUREvs TLS MCP / ingress — La désactivation deCLICKHOUSE_SECUREparce que le serveur MCP se trouve derrière un ingress Kubernetes, un proxy inverse, ou est atteint sur HTTP simple ne désactive pas le TLS de la base de données ; cela change uniquement la façon dont ce processus se connecte à ClickHouse. Configurez le TLS de l'ingress séparément des paramètres du client de base de données.- Ports du protocole natif —
CLICKHOUSE_PORTdoit cibler l'interface HTTP de ClickHouse (8123/8443par défaut). Les ports9000/9440sont pour le protocole TCP natif (clickhouse-client) et ne fonctionneront pas avec ce serveur. - Confusion d'hôte —
CLICKHOUSE_HOSTest le nom d'hôte de la base de données.CLICKHOUSE_MCP_BIND_HOSTest uniquement l'adresse sur laquelle le serveur MCP HTTP/SSE écoute.
Exemples de configurations
Pour le développement local avec Docker :
# Required variables
CLICKHOUSE_HOST=localhost
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
# Optional: Override defaults for local development
CLICKHOUSE_SECURE=false # Uses port 8123 automatically
CLICKHOUSE_VERIFY=false
Pour ClickHouse Cloud :
# Required variables
CLICKHOUSE_HOST=your-instance.clickhouse.cloud
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=your-password
# Optional: These use secure defaults
# CLICKHOUSE_SECURE=true # Uses port 8443 automatically
# CLICKHOUSE_DATABASE=your_database
Pour ClickHouse SQL Playground :
CLICKHOUSE_HOST=sql-clickhouse.clickhouse.com
CLICKHOUSE_USER=demo
CLICKHOUSE_PASSWORD=
# Uses secure defaults (HTTPS on port 8443)
Pour une CA de serveur privée sans authentification par certificat client :
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
CLICKHOUSE_USER=your-user
CLICKHOUSE_PASSWORD=your-password
CLICKHOUSE_SECURE=true
CLICKHOUSE_VERIFY=true
CLICKHOUSE_CA_CERT=/run/secrets/clickhouse-ca.pem
Pour l'authentification par certificat client X.509 ClickHouse :
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
CLICKHOUSE_USER=your-certificate-user
CLICKHOUSE_SECURE=true
CLICKHOUSE_CLIENT_CERT=/run/secrets/clickhouse-client.pem
CLICKHOUSE_CLIENT_CERT_KEY=/run/secrets/clickhouse-client-key.pem
# CLICKHOUSE_CA_CERT=/run/secrets/clickhouse-ca.pem # Only for a private server CA
# CLICKHOUSE_TLS_MODE=mutual # Optional. This is the default with a client certificate.
Pour un certificat client requis par un serveur TLS strict tandis que ClickHouse utilise l'authentification Basic :
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
CLICKHOUSE_USER=your-user
CLICKHOUSE_PASSWORD=your-password
CLICKHOUSE_SECURE=true
CLICKHOUSE_CLIENT_CERT=/run/secrets/clickhouse-client.pem
CLICKHOUSE_CLIENT_CERT_KEY=/run/secrets/clickhouse-client-key.pem
CLICKHOUSE_TLS_MODE=strict
Utilisez CLICKHOUSE_TLS_MODE=proxy à la place lorsqu’un proxy de terminaison TLS exige le
certificat client et que ClickHouse utilise toujours l’authentification Basic.
Pour chDB uniquement (en mémoire) :
# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
# CHDB_DATA_PATH defaults to :memory:
Pour chDB avec stockage persistant :
# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
CHDB_DATA_PATH=/path/to/chdb/data
Pour MCP Inspector ou un accès distant avec transport HTTP :
CLICKHOUSE_HOST=localhost
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
CLICKHOUSE_MCP_SERVER_TRANSPORT=http
CLICKHOUSE_MCP_BIND_HOST=0.0.0.0 # Bind to all interfaces
CLICKHOUSE_MCP_BIND_PORT=4200 # Custom port (default: 8000)
CLICKHOUSE_MCP_AUTH_TOKEN=your-generated-token # One auth mode required for HTTP/SSE (or FASTMCP_SERVER_AUTH, or CLICKHOUSE_MCP_AUTH_DISABLED=true)
CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:4200,localhost:4200,mcp.example.com:4200 # Include every Host value clients and proxies send
Pour le développement local avec transport HTTP (authentification désactivée) :
CLICKHOUSE_HOST=localhost
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
CLICKHOUSE_MCP_SERVER_TRANSPORT=http
CLICKHOUSE_MCP_AUTH_DISABLED=true # Only for local development!
CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000
Lorsque vous utilisez le transport HTTP, le serveur s’exécutera sur le port configuré (par défaut 8000). Par exemple, avec la configuration ci-dessus :
- Point de terminaison MCP :
http://localhost:8000/mcp - Vérification de santé :
http://localhost:8000/health
Vous pouvez définir ces variables dans votre environnement, dans un fichier .env, ou dans la configuration de Claude Desktop :
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_DATABASE": "<optional-database>",
"CLICKHOUSE_MCP_SERVER_TRANSPORT": "stdio",
"CLICKHOUSE_MCP_BIND_HOST": "127.0.0.1",
"CLICKHOUSE_MCP_BIND_PORT": "8000"
}
}
}
}
Remarque : Les paramètres d’hôte et de port de liaison ne sont utilisés que lorsque le transport est défini sur « http » ou « sse ».
Exécution des tests
uv sync --all-extras --dev # install dev dependencies
uv run ruff check . # run linting
docker compose up -d test_services # start ClickHouse
uv run pytest -v tests
uv run pytest -v tests/test_tool.py # ClickHouse only
CHDB_ENABLED=true uv run --extra chdb pytest -v tests/test_chdb_tool.py # chDB only
