ClickHouse MCPサーバーでOLAP分析クエリを実行する
ClickHouse公式のMCPサーバーmcp-clickhouseの接続手順と、既定で読み取り専用になる書き込み制御、ログ・イベントデータの分析ユースケースをまとめます。
大量のログやイベントデータを溜め込んだClickHouseに対して、SQLを書かずに自然文のまま集計を投げたい場面は多いはずです。MCPを使えば、この橋渡しをAIエージェント側から自然に扱えます。ClickHouse公式組織が提供するMCPサーバーmcp-clickhouseはそのための実装です。PyPIパッケージと、Docker Hubのmcp/clickhouseイメージ(説明は「Official ClickHouse MCP Server」、累計32万プル超)で配布されており、既定では読み取り専用に固定されています。接続手順と、書き込みを許可するときの2段階のガード、ログ分析での実務的な使い方をまとめます。
mcp-clickhouseが提供するツール
現行バージョン(v0.7.0)が公開するツールは、ClickHouse本体向けとchDB向けに分かれます。
| ツール名 | 機能 |
|---|---|
run_query | 機能ClickHouseクラスターにSQLクエリを実行(任意のparamsで値を別渡しできる) |
list_databases | 機能クラスター上の全データベースを一覧表示 |
list_tables | 機能指定データベースのテーブルをページング付きで一覧表示 |
run_chdb_select_query | 機能chDB(組み込みエンジン)経由でSQLを実行 |
list_tablesはpage_tokenとpage_size(既定50件)によるページングに対応します。like/not_likeでテーブル名を絞れ、include_detailed_columns=falseならカラム情報を省けます(create_table_queryは残ります)。テーブル数が多いクラスターでも、1回のレスポンスが肥大化しないよう設計されています。
ツールの応答はすべてJSON形式ですが、数値の扱いに1つ注意点があります。JavaScriptで安全に扱える整数の範囲(-9007199254740991〜9007199254740991)を超える整数は、精度を保つために10進数の文字列として返されます。クエリ結果の行データと、テーブルメタデータに含まれる整数(行数・バイト数など)の両方が対象です。ログ・イベント系のテーブルは行数がこの範囲を超えることも珍しくないため、集計結果を別のシステムに渡す場合はこの文字列化の挙動を踏まえておく必要があります。安全範囲内の整数と真偽値は、通常どおりのJSON型のまま返ります。
インストールと接続手順
uvを使う場合、Claude Desktopの設定ファイルにサーバー定義を追加します。
{
"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_SECURE": "true"
}
}
}
}Claude Codeに接続する
上のJSONはClaude Desktop向けの書き方です。Claude Codeではclaude mcp addで同じ構成を登録します。サーバーに渡す環境変数は-eで指定し、--の後ろに起動コマンドを置きます。
Claude Codeへの登録(v2.1.289の出力例)
- 1
プロジェクトのディレクトリで登録する
--scope projectを付けると、設定がそのディレクトリの.mcp.jsonに書かれます。付けなければlocalスコープで保存されます。 - 2
生成された.mcp.jsonを見る
typeがstdioで補われ、-eの値はenvに入ります。パスワードが平文で残ります。 - 3
初回は承認する
プロジェクトスコープのサーバーは、
claudeを対話で起動して承認するまでPending approvalのままです。
claude mcp add --scope project mcp-clickhouse \
-e CLICKHOUSE_HOST=sql-clickhouse.clickhouse.com \
-e CLICKHOUSE_USER=demo -e CLICKHOUSE_PASSWORD= \
-e CLICKHOUSE_SECURE=true \
-- uv run --with mcp-clickhouse --python 3.12 mcp-clickhouse実行すると、次の出力と.mcp.jsonになります。
Added stdio MCP server mcp-clickhouse with command: uv run --with mcp-clickhouse --python 3.12 mcp-clickhouse to project config
File modified: ./.mcp.json{
"mcpServers": {
"mcp-clickhouse": {
"type": "stdio",
"command": "uv",
"args": ["run", "--with", "mcp-clickhouse", "--python", "3.12", "mcp-clickhouse"],
"env": {
"CLICKHOUSE_HOST": "sql-clickhouse.clickhouse.com",
"CLICKHOUSE_USER": "demo",
"CLICKHOUSE_PASSWORD": "",
"CLICKHOUSE_SECURE": "true"
}
}
}
}本番のクラスターでは、.mcp.jsonのパスワードを"CLICKHOUSE_PASSWORD": "${CLICKHOUSE_PASSWORD}"のように環境変数参照へ書き換えます。未設定の変数があると、Claude Codeは/mcpに警告を出して${VAR}のままサーバーを読み込みます。
手元に接続先のクラスターが無くても試せます。ClickHouseが公開しているSQL Playgroundは、demoユーザー・パスワード空欄の設定で誰でも繋げる公開デモ環境です。
pip install mcp-clickhouse
# またはDockerイメージを使う
docker pull mcp/clickhouseuvを使わずシステムのPythonで動かす場合は、インストール後にmcp-clickhouseコマンドをそのままcommandに指定する構成でも動作します。Python 3.10〜3.14に対応し、ローカル起動では3.12が推奨です。
既定は読み取り専用 — 書き込みは2段階のフラグで許可する
mcp-clickhouseはCLICKHOUSE_ALLOW_WRITE_ACCESS=falseが既定値です。探索目的の接続なら、既定値を変えずに使うのが最も安全です。DDLやINSERTを許可したい場合だけ、明示的にtrueへ切り替えます。
書き込みを許可する運用では、MCPサーバー専用のClickHouseユーザーを作り、必要な権限だけを与えます。
CREATE USER mcp_agent IDENTIFIED BY '...';
GRANT SELECT, INSERT, CREATE TABLE, ALTER ADD COLUMN ON mydb.* TO mcp_agent;このGRANTの範囲外のSQLは、MCPサーバー側のフラグ設定に関わらずサーバー側でACCESS_DENIEDとして弾かれます。max_table_size_to_dropやmax_partition_size_to_dropのようなClickHouse側の設定値も、被害範囲を制限する追加の手段として使えます。
HTTP/SSE接続時の認証
stdioトランスポート(既定)は標準入出力のみで通信するため認証を必要としませんが、HTTPまたはSSEトランスポートでは認証が必須です。3つのモードから選びます。
| モード | 向く用途 | 設定 |
|---|---|---|
| 静的Bearerトークン | 向く用途シンプルな社内デプロイ | 設定CLICKHOUSE_MCP_AUTH_TOKEN |
| OAuth / OIDC(FastMCP経由) | 向く用途Azure Entra・Google・GitHub・WorkOSなど | 設定FASTMCP_SERVER_AUTHに該当プロバイダーのクラスパスを指定 |
| 認証無効化 | 向く用途ローカル開発限定 | 設定CLICKHOUSE_MCP_AUTH_DISABLED=true |
いずれも未設定のままHTTP/SSEトランスポートを起動すると、サーバーは起動に失敗します。ヘルスチェック用の/healthエンドポイントだけは意図的に認証対象外です。Bearerトークンが実際に機能しているかを確認したいときは、/healthではなく/mcpへ直接リクエストを投げ、Authorizationヘッダーの有無で401が返るかを見る必要があります。
OAuth / OIDCはFastMCPの組み込みプロバイダーに委譲する形で、社内で使っているIDプロバイダーに合わせて選びます。
| IDプロバイダー | クラスパス |
|---|---|
| Auth0 | クラスパスfastmcp.server.auth.providers.auth0.Auth0Provider |
| AWS Cognito | クラスパスfastmcp.server.auth.providers.aws.AWSCognitoProvider |
| Azure Entra | クラスパスfastmcp.server.auth.providers.azure.AzureProvider |
| GitHub | クラスパスfastmcp.server.auth.providers.github.GitHubProvider |
クラスパスfastmcp.server.auth.providers.google.GoogleProvider | |
| WorkOS | クラスパスfastmcp.server.auth.providers.workos.WorkOSProvider |
Azure Entraを例にすると、環境変数はテナントID・クライアントID・クライアントシークレット・ベースURL・スコープの5つを設定します。スコープは複数ならスペース区切りで渡します。
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"CLICKHOUSE_MCP_AUTH_TOKENや個々のプロバイダー変数は、プロセスの環境変数として直接設定した値が最優先されます。パッケージディレクトリから遡って見つかる.envファイルはFASTMCP_SERVER_AUTH自体を含め認証プロバイダーの再選択ができ、作業ディレクトリの互換用.envは不足しているプロバイダー設定値を補うだけです。.envファイル、特にパッケージ側の.envへの書き込み権限は、認証設定そのものと同じ重みで扱う必要があります。
chDBで埋め込みエンジンとして使う
run_chdb_select_queryは、独立したクラスターを持たずに使えるchDBの組み込みエンジンを呼び出します。ファイル・URL・別のデータベースに対して、ETLの前処理なしで直接SQLを投げられるのが特徴です。オプション拡張のため、pip install 'mcp-clickhouse[chdb]'でインストールし、CHDB_ENABLED=trueを設定します。
ClickHouseとchDBは同時に有効化できます。稼働中のクラスターに繋ぎながら、手元のCSVファイルもその場で分析するといった構成が1つのサーバーで済みます。
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CHDB_ENABLED": "true",
"CHDB_DATA_PATH": "/path/to/chdb/data"
}この構成では、Claudeが状況に応じてrun_query(クラスター側)とrun_chdb_select_query(chDB側)のどちらを呼ぶか自分で判断します。「このCSVとクラスター上のテーブルを突き合わせて」のような依頼でも、片方だけに接続を絞っている場合よりも自然に処理が進みます。
ログ・イベントデータを自然文で分析する
ClickHouseを使う場面として多いのは、行数が膨らみやすいログ・イベント系のテーブルです。テーブル構造さえlist_tablesで把握できれば、あとは自然文で聞くだけで済みます。
過去24時間でHTTPステータス500が一番多かったエンドポイントを教えてユーザーごとのイベント数を日次で集計して、急増しているユーザーを見つけて裏側ではrun_queryが集計クエリを組み立てて実行します。大規模テーブルへの集計は、ClickHouseの列指向エンジンが想定している使い方です。読み取り専用の既定値のままなら、集計を試行錯誤しても元データを壊す心配がありません。
重いクエリを走らせる前に見積もる
数十億行のテーブルでは、集計クエリを1本投げるだけで時間も費用もかかります。run_queryは通常のSELECTに加えてDESCRIBEとEXPLAIN ESTIMATEも受け付け、どちらも既定の読み取り専用のまま使えます。
実行前に使える2つの確認
DESCRIBE (クエリ)
出力カラムの名前と型が返ります。usrのような列名の打ち間違いは、実行の途中ではなくここでCode: 47として返り、近い候補(Maybe you meant: ['user'])も示されます。
EXPLAIN ESTIMATE クエリ
テーブルごとに、読み込み予定のパーツ数・行数・マーク数が返ります。主キーで絞れているクエリと全走査のクエリを見分けるための数字です。
EXPLAIN ESTIMATEが数えるのはMergeTree系テーブルへの読み取り見込みで、実行時間や結果の大きさではありません。他のテーブルエンジンは対象外です。DESCRIBEも、クエリの解析中にスカラーサブクエリを実行することがあるため、常に無料とは限りません。
値をSQLへ直接埋め込まず、{name:Type}のプレースホルダーとparamsで別渡しする書き方もあります。
{
"query": "SELECT {id:UInt32} AS id, {name:String} AS name",
"params": {"id": 13, "name": "O'Reilly"}
}UInt64の上限のような安全範囲を超える整数は、"18446744073709551615"のように文字列で渡します。TupleとMap型には、JSONのリストやオブジェクトを束縛できません。パラメーターの値はMCPサーバーの通常のSQLログには出ませんが、ツール引数やバックエンドのエラーには残ります。プライバシーの機能ではありません。
長いクエリが途中で切れるときの設定
集計が重いと、ClickHouse側のタイムアウトか、Claude Code側の出力上限に当たります。既定値は次のとおりです。
切れる場所と既定値
クエリのタイムアウト
30秒
CLICKHOUSE_MCP_QUERY_TIMEOUT。超えるとKILL QUERYで中断を試みる
接続のタイムアウト
30秒
CLICKHOUSE_CONNECT_TIMEOUT
同時実行ワーカー
10
CLICKHOUSE_MCP_MAX_WORKERS
Claude Codeの出力上限
25,000トークン
MAX_MCP_OUTPUT_TOKENS。警告は10,000トークンから
Query timed out after ...というエラーが出たら、CLICKHOUSE_MCP_QUERY_TIMEOUTを上げます。CLICKHOUSE_SEND_RECEIVE_TIMEOUTを明示しない限り、HTTPの読み取りタイムアウトは「クエリのタイムアウト+5秒」で頭打ちになります。
Claude Code側では、行数の多い結果を丸ごと返す依頼が出力上限に当たります。LIMITを付けるか、集計してから返す質問にすると収まります。
MCPサーバーからの応答が止まった場合のアイドルタイムアウトは、HTTP・SSE・WebSocket・claude.aiコネクタのサーバーで既定5分、stdioサーバーで30分です。
分析基盤MCPサーバーの使い分け早見表
| シーン | おすすめ | 理由 |
|---|---|---|
| 大規模ログ・イベントの集計分析 | おすすめClickHouse | 理由列指向エンジンで集計する用途 |
| Google Cloud上のDWH | おすすめBigQuery | 理由データがGoogle Cloudにある場合の接続先 |
| ローカルファイルや軽量分析基盤 | おすすめDuckDB / MotherDuck | 理由手元のファイルを対象にする分析 |
| 全文検索・ログの横断検索 | おすすめElasticsearch | 理由キーワード検索・横断調査の用途 |
BigQueryとの接続はClaude BigQuery連携、ローカル完結の分析基盤はDuckDB / MotherDuck MCPサーバーで扱っています。同じログデータでも、集計・OLAP用途ならClickHouse、キーワードでの全文検索や横断的な調査ならElasticsearch MCPサーバーというように、聞きたい質問の種類で使い分けます。「このエラーメッセージを含むログを全部探して」のような検索寄りの質問はElasticsearch側が得意で、「時間帯別のエラー率を集計して」のような集計寄りの質問はClickHouse側が得意です。
よくあるつまずき
Port 9000 is for clickhouse-client programと返る:clickhouse-clientが使うネイティブTCPポートを指している。このサーバーはHTTPインターフェース専用なので、CLICKHOUSE_PORTを8123(平文)か8443(TLS)にする- ポートが合っているのにHTTPクライアントのエラーになる:
CLICKHOUSE_SECUREとポートが食い違っている。CLICKHOUSE_SECURE=falseで8443へ接続するのが典型で、スキーム違いを明示するエラーにならない list_tablesが途中で止まったように見える:page_tokenはone-time利用で約1時間で失効する。時間を置きすぎると次ページの取得に失敗するので、続けて取得する- 書き込みを許可したのに
DROPが通らない:CLICKHOUSE_ALLOW_WRITE_ACCESS=trueだけでは足りず、破壊的操作にはCLICKHOUSE_ALLOW_DROP=trueも必要 - HTTP接続で421や403が返る:
CLICKHOUSE_MCP_ALLOWED_HOSTSとHostヘッダーが一致しないと421 Misdirected Request、Originが一致しないと403 Forbiddenになる - HTTP接続で毎回401になる:
CLICKHOUSE_MCP_AUTH_TOKENを設定しても、クライアント側のAuthorization: Bearer <token>ヘッダーが抜けていると認証が通らない - chDBのクエリでモジュールエラーが出る:
chdbエクストラをインストールせずにCHDB_ENABLED=trueだけ設定している。pip install 'mcp-clickhouse[chdb]'でchdbパッケージ自体を入れる
よくある質問
認証を一時的に無効化してテストできますか
CLICKHOUSE_MCP_AUTH_DISABLED=trueで無効化できますが、ローカル開発限定の設定です。あわせてCLICKHOUSE_MCP_ALLOWED_HOSTSで許可ホストを127.0.0.1などに絞ります。ネットワークに公開されたサーバーでこの設定を使うのは避けます。
ヘルスチェックはどう確認しますか
HTTPまたはSSEトランスポートで起動している場合、/healthにGETまたはHEADでアクセスすると、ClickHouseに接続できていれば200 OK(本文OK)、接続できなければ503が返ります。Kubernetesのliveness/readinessプローブのように認証なしで叩ける設計で、ロードバランサーからのヘルスチェックにもそのまま使えます。
chDBだけを使い、通常のClickHouseクラスターには繋がない構成もできますか
できます。CHDB_ENABLED=trueかつCLICKHOUSE_ENABLED=falseにすれば、クラスターへの接続情報を用意せずchDBの組み込みエンジンだけで動かせます。手元のファイル分析だけが目的で、常設のクラスターを持たないチームに向く構成です。
まとめ
まずはSQL Playgroundのような読み取り専用の接続で、EXPLAIN ESTIMATEを使ってクエリの重さを見る流れから始められます。書き込みが要るときは、先にMCPサーバー専用のユーザーへ必要な権限だけをGRANTし、そのあとでCLICKHOUSE_ALLOW_WRITE_ACCESSを開けます。