ClickHouse
官方查詢您的 ClickHouse 資料庫伺服器。
你可以用 ClickHouse MCP 做什麼?
- 執行 SQL 查詢 — 透過
run_query在您的 ClickHouse 叢集上執行唯讀 SQL,可選擇使用具名params進行安全的參數綁定。 - 檢查查詢計畫 — 在
run_query中使用DESCRIBE和EXPLAIN ESTIMATE,在執行前預覽結果結構描述或估算讀取量。 - 列出資料庫 — 使用
list_databases列舉叢集上的所有資料庫,以探索可用的資料來源。 - 使用篩選條件瀏覽資料表 — 使用
list_tables搭配like/not_like模式,並透過page_token進行分頁,以探索任何資料庫中的資料表。 - 查詢內嵌 chDB — 使用
run_chdb_select_query對 chDB 的內嵌引擎執行 SQL,以查詢檔案、URL 或資料庫,無需 ETL。
文件
ClickHouse MCP 伺服器
一個用於 ClickHouse 的 MCP 伺服器。
此伺服器實作 MCP 2026-07-28,並支援來自 2024-11-05 至 2025-11-25 的舊版 initialize 交握。現代用戶端使用無 session 的請求與 server/discover。既有用戶端可以繼續協商舊版協定。
[!NOTE] 沒有
MCP-Protocol-Version的 HTTP 請求會透過舊版處理路由,因此2025-06-18之前的用戶端可以繼續連線。MCP2026-07-28允許伺服器在支援這些用戶端時採用此行為。現代用戶端應在每個 POST 請求中傳送此標頭。
功能
ClickHouse 工具
ClickHouse 工具回應是 JSON 編碼的字串。超出 [-9007199254740991, 9007199254740991] 範圍的整數會以十進位字串傳回,以在 JavaScript 用戶端中保留精確值。這適用於查詢列與整數表格中繼資料。安全範圍內的整數與布林值保留其 JSON 型別。
-
run_query -
list_databases- 列出您的 ClickHouse 叢集上的所有資料庫。
-
list_tables- 以分頁列出資料庫中的資料表。
- 必要輸入:
database(字串)。 - 選用輸入:
like/not_like(字串):對資料表名稱套用LIKE或NOT LIKE篩選器。page_token(字串):先前呼叫傳回的單次使用權杖。最多保留一小時。page_size(整數,預設50):每頁傳回的資料表數量;必須大於0。include_detailed_columns(布林值,預設true):當為false時,省略欄位中繼資料以減輕回應負擔,同時保留完整的create_table_query。
- 回應結構:
tables:目前頁面的資料表物件陣列。next_page_token:在到期前將此單次使用值傳回以取得下一頁,或當沒有更多資料表時傳回null。total_tables:符合所提供篩選器的資料表總數。
查詢參數
透過選用的 params 物件,將值與 SQL 分開傳遞:
{
"query": "SELECT {id:UInt32} AS id, {name:String} AS name",
"params": {"id": 13, "name": "O'Reilly"}
}
使用 ClickHouse 的 {name:Type} 佔位符,不需加上引號。保持左大括號、名稱與冒號相鄰,如 {id:UInt32} 所示。冒號後與型別內的空格受支援,如 {id: UInt32} 與 {amount:Decimal(18, 4)} 所示。為確保與支援的驅動程式版本相容,名稱請以字母或底線開頭,且僅使用字母、數字與底線。不支援 Python 風格的 %s 或 %(name)s 格式化,以及驅動程式的 $name$ 原始二進位參數。僅含 query 的呼叫仍可運作。省略 params、傳遞 null 或傳遞空物件時,查詢保持未綁定。
參數值可以是 JSON 字串、數字、布林值、null 或陣列,前提是它們符合宣告的 ClickHouse 型別:
- 使用
null搭配Nullable(...)型別。 - 將 JavaScript 安全範圍外的精確整數以十進位字串傳遞,例如
"18446744073709551615"搭配{id:UInt64}。日期、時間戳記與精確十進位數也可以字串形式搭配對應的 ClickHouse 型別傳遞。 - 將向量綁定為單一陣列,例如
{vector:Array(Float32)}搭配"params": {"vector": [0.25, 0.5, 0.75]}。 - 陣列中的 Null 值取決於安裝的驅動程式。它們在 clickhouse-connect 1.8.0 中可運作,但在支援的最低版本 1.0.0 中會失敗。
- JSON 清單與物件無法綁定到 ClickHouse
Tuple與Map型別。
缺少值與不相容的型別會傳回查詢錯誤。當 params 非空時,帶有許多未終止的 {name: 佔位符開頭的查詢會被拒絕,包括註解或字串字面值中類似佔位符的文字。參數化查詢使用與其他查詢相同的寫入保護、逾時、取消與 JSON 結果編碼。
參數值不會出現在 MCP 伺服器的一般 SQL 日誌訊息中,但仍會保留在 MCP 工具引數中,並可能出現在後端錯誤中。ClickHouse 26.3.20.7 會在 system.query_log、system.processes 與 system.text_log 中將值替換到查詢文字中。參數綁定不是隱私功能,也不會減少工具呼叫中傳送的向量值數量。
執行前檢查查詢
run_query 也會執行 DESCRIBE 與 EXPLAIN ESTIMATE。兩者都是選用檢查:當您需要查詢的輸出欄位與型別時使用 DESCRIBE,在可能耗費資源的 SELECT 之前使用 EXPLAIN ESTIMATE。
DESCRIBE (<query>) 檢查結果結構描述,並傳回與 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 必須分析查詢才能回答,因此分析錯誤會在這裡顯示,並附上 ClickHouse 自己的訊息,而不是在執行中途才出現:
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'
能乾淨描述查詢的查詢在執行時仍可能失敗,例如記憶體限制或遠端伺服器錯誤,而且它不會說明成本。
EXPLAIN ESTIMATE <query> 傳回查詢會讀取的 parts、rows 與 marks,每個資料表一列,這正是區分主鍵查詢與完整掃描的關鍵:
EXPLAIN ESTIMATE SELECT count() FROM events WHERE id = 42
database table parts rows marks
default events 1 8192 1
這些是 MergeTree 系列資料表在主鍵與分割區修剪後的預估讀取量。它們不是執行時間,也不是結果大小,而且其他資料表引擎不涵蓋在內。
兩個陳述式都不會執行查詢主體,但分析並非總是免費:DESCRIBE (SELECT (SELECT sleep(1))) 在分析時會執行純量子查詢。兩者都是唯讀,並在預設的 CLICKHOUSE_ALLOW_WRITE_ACCESS=false 下運作。請參閱 ClickHouse 文件中的 EXPLAIN ESTIMATE 與 DESCRIBE。
chDB 工具
run_chdb_select_query- 使用 chDB 的嵌入式 ClickHouse 引擎執行 SQL 查詢。
- 輸入:
query(字串):要執行的 SQL 查詢。 - 超出
[-9007199254740991, 9007199254740991]範圍的整數會以十進位字串傳回。 - 直接從各種來源(檔案、URL、資料庫)查詢資料,無需 ETL 流程。
- 需要選用的
chdb額外套件:pip install 'mcp-clickhouse[chdb]'
健康檢查端點
使用 HTTP 或 SSE 傳輸執行時,健康檢查端點位於 /health。此端點:
- 若伺服器健康且可連線到 ClickHouse,傳回
200 OK(主體:OK) - 若伺服器無法連線到 ClickHouse,傳回
503 Service Unavailable與一般錯誤訊息 - 若 ClickHouse 探測在兩秒內未完成,傳回
503。並行請求共用一個進行中的探測 - 重複使用已完成的探測結果一秒鐘,因此快速連續到達的探測不會各自連線到 ClickHouse。因此,失敗或恢復可能延遲最多一秒才回報
對端點的 GET 與 HEAD 請求刻意不要求驗證,且豁免於 Host 與 Origin 驗證,以便編排器探測(例如 Kubernetes liveness/readiness、負載平衡器)可以使用執行時期指派的 pod 或目標 IP,無需額外設定。/health 被保留,不能用作 MCP 傳輸路徑。回應主體刻意保持精簡,以避免洩漏後端版本字串或錯誤詳細資料;請透過伺服器日誌偵錯失敗。
範例:
curl http://localhost:8000/health
# Response: OK
安全性
HTTP/SSE 傳輸的驗證
使用 HTTP 或 SSE 傳輸時,預設需要驗證。stdio 傳輸(預設)不需要驗證,因為它僅透過標準輸入/輸出通訊。
支援三種驗證模式。請選擇一種:
| 模式 | 使用時機 | 環境變數 |
|---|---|---|
| 靜態 bearer 權杖 | 簡單部署、內部服務 | CLICKHOUSE_MCP_AUTH_TOKEN |
| OAuth / OIDC(透過 FastMCP) | Azure Entra、Google、GitHub、WorkOS 等。 | FASTMCP_SERVER_AUTH=<provider-class-path>(+ 供應商特定的 FASTMCP_SERVER_AUTH_* 變數) |
| 停用 | 僅限本機開發 | CLICKHOUSE_MCP_AUTH_DISABLED=true |
若 HTTP/SSE 傳輸未設定其中任何一種,啟動會失敗。
設定驗證
-
產生安全權杖(可以是任何隨機字串):
# Using uuidgen (macOS/Linux) uuidgen # Using openssl openssl rand -hex 32 -
使用權杖設定伺服器:
export CLICKHOUSE_MCP_AUTH_TOKEN="your-generated-token" -
設定您的 MCP 用戶端在請求中包含權杖:
對於使用 HTTP/SSE 傳輸的 Claude Desktop:
{ "mcpServers": { "mcp-clickhouse": { "url": "http://127.0.0.1:8000", "headers": { "Authorization": "Bearer your-generated-token" } } } }注意:
/health端點刻意不要求驗證(請參閱上方健康檢查端點)。若要驗證 bearer 權杖驗證確實拒絕未驗證的請求,請直接存取 MCP 端點本身,例如使用 MCP Inspector,或向/mcpPOST 一個 JSON-RPC 請求,分別帶有與不帶有Authorization標頭,並確認未驗證的呼叫傳回401。
透過 FastMCP 的 OAuth / OIDC
對於使用身分提供者(Azure Entra、Google、GitHub、WorkOS 等)的生產部署,請委派驗證給 FastMCP 的內建驗證提供者,而不是使用靜態權杖。將 FASTMCP_SERVER_AUTH 設定為 FastMCP 驗證提供者的完整類別路徑,加上供應商特定的 FASTMCP_SERVER_AUTH_* 變數,並讓 CLICKHOUSE_MCP_AUTH_TOKEN 保持未設定。
範例(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 為 FastMCP 4.0.0 內建提供者保留這些 FastMCP 2.14.7 環境變數前綴:
| 提供者類別路徑 | 提供者變數前綴 |
|---|---|
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_ |
將大寫的提供者欄位名稱附加到前綴。請參閱 FastMCP 文件 以了解每個提供者的設定需求。
直接在處理程序環境中設定的驗證值會以不區分大小寫的方式優先採用。
預設的 .env 載入會從已安裝的 mcp_clickhouse 套件目錄開始,
先解析符號連結,再向上遍歷至檔案系統根目錄。它會載入找到的第一個
.env,若找不到就不載入任何內容。它絕不會讀取工作目錄,
無論伺服器如何啟動皆然。原始碼檢出通常會找到儲存庫根目錄的
.env。該檔案也可能提供 FASTMCP_SERVER_AUTH 及其提供者欄位。
其值優先於明確或相容性驗證檔案。
為了 FastMCP 2 相容性,mcp-clickhouse 會從工作目錄中的 .env
讀取缺少的提供者欄位,但該相容性後備機制無法選取
FASTMCP_SERVER_AUTH。處理程序設定的 FASTMCP_ENV_FILE 會取代該相容性
後備機制,並可同時提供選取器與提供者欄位。請在啟動前設定它。
mcp-clickhouse 相容性載入器只會從該檔案讀取 FASTMCP_SERVER_AUTH 和
FASTMCP_SERVER_AUTH_*,因此無法注入 CLICKHOUSE_* 設定。
FastMCP 4 可能使用相同的檔案來存放其自身更廣泛的設定。自訂提供者
不會收到任何從環境衍生的建構子引數,且必須支援無引數建構。
請將探索到的與工作目錄中的 .env 檔案都視為受信任的驗證
設定。任何能在從套件目錄到檔案系統根目錄之間的任何目錄中建立或寫入
.env 的人,都能控制探索到哪個檔案、選取提供者,並設定其欄位。
任何能寫入工作目錄檔案的人,都能控制處理程序與探索到的設定中缺少的所有提供者
欄位,包括簽章金鑰、簽發者與端點,以及用戶端密碼。指向
營運商擁有之檔案的處理程序設定 FASTMCP_ENV_FILE 會停用工作目錄後備機制。
FastMCP 4 變更了預設的 OAuth 代理用戶端存放區。依賴 FastMCP 2 預設 OAuth 代理儲存空間的部署,必須讓用戶端重新註冊並重新授權。 相容的自訂儲存空間、靜態 bearer token 與 JWT 驗證則不受影響。
開發模式(停用驗證)
僅供本機開發與測試使用,您可以透過設定以下項目來停用驗證:
export CLICKHOUSE_MCP_AUTH_DISABLED=true
export CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000
警告: 僅限本機開發使用。當伺服器暴露於任何網路時,請勿停用驗證。
設定
此 MCP 伺服器同時支援 ClickHouse 與 chDB。您可以視需求啟用其中一個或兩者。 支援 Python 3.10 至 3.14。本機啟動建議使用 Python 3.12。
-
開啟位於以下位置的 Claude Desktop 設定檔:
- 在 macOS 上:
~/Library/Application Support/Claude/claude_desktop_config.json - 在 Windows 上:
%APPDATA%/Claude/claude_desktop_config.json
- 在 macOS 上:
-
新增以下內容:
{
"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"
}
}
}
}
更新環境變數以指向您自己的 ClickHouse 服務。
或者,如果您想透過 ClickHouse SQL Playground 試用,可以使用以下設定:
{
"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"
}
}
}
}
對於 chDB(嵌入式 ClickHouse 引擎),請新增以下設定:
{
"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"
}
}
}
}
您也可以同時啟用 ClickHouse 與 chDB:
{
"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"
}
}
}
}
-
找到
uv的命令條目,並將其取代為uv可執行檔的絕對路徑。這可確保在啟動伺服器時使用正確版本的uv。在 Mac 上,您可以使用which uv找到此路徑。 -
重新啟動 Claude Desktop 以套用變更。
選用寫入權限
預設情況下,此 MCP 會強制執行唯讀查詢,以避免在探索期間發生意外變更。若要允許 DDL 或 INSERT 陳述式,請將 CLICKHOUSE_ALLOW_WRITE_ACCESS 環境變數設為 true。如果 ClickHouse 實例本身不允許寫入,伺服器仍會持續強制執行唯讀模式。
破壞性操作保護
即使啟用了寫入權限(CLICKHOUSE_ALLOW_WRITE_ACCESS=true),破壞性操作仍需要額外的選擇加入旗標以確保安全。此檢查涵蓋任何 DROP 陳述式(包括 ALTER TABLE ... DROP PARTITION / DROP PART / DROP COLUMN 子句)、任何 TRUNCATE、DELETE 和 UPDATE(輕量陳述式與 ALTER TABLE ... DELETE / ALTER TABLE ... UPDATE 變更皆涵蓋)、REPLACE TABLE、CREATE OR REPLACE、ALTER TABLE ... REPLACE PARTITION、ALTER TABLE ... CLEAR COLUMN / CLEAR INDEX / CLEAR PROJECTION,以及 DETACH ... PERMANENTLY。字串常值、帶引號的識別碼、SQL 註解和 {name:Type} 參數名稱中的關鍵字會被忽略,因此它們既不會觸發檢查,也不會隱藏陳述式。
此檢查在 MCP 伺服器中執行,是防止意外的盡力防護。它不是安全邊界。安全邊界是 ClickHouse 使用者的授權。唯讀模式(預設)是透過 readonly=1 在伺服器端強制執行。破壞性操作閘門並非伺服器端強制執行。
對於寫入模式,請為 MCP 伺服器提供一個專用的 ClickHouse 使用者,僅授予其所需的權限:
CREATE USER mcp_agent IDENTIFIED BY '...';
GRANT SELECT, INSERT, CREATE TABLE, ALTER ADD COLUMN ON mydb.* TO mcp_agent;
這些授權之外的每個陳述式都會在伺服器端以 ACCESS_DENIED 失敗,無論 MCP 旗標為何。伺服器設定 max_table_size_to_drop 和 max_partition_size_to_drop 若固定了設定約束,也能限制爆炸半徑。
若要啟用破壞性操作,請設定兩個旗標:
"env": {
"CLICKHOUSE_ALLOW_WRITE_ACCESS": "true",
"CLICKHOUSE_ALLOW_DROP": "true"
}
這種兩層式方法讓意外刪除變得困難:
- 寫入操作(INSERT、CREATE、ALTER ADD COLUMN)需要
CLICKHOUSE_ALLOW_WRITE_ACCESS=true - 破壞性操作(DROP、TRUNCATE、DELETE、UPDATE 以及上述清單其餘項目)額外需要
CLICKHOUSE_ALLOW_DROP=true
不使用 uv 執行(使用系統 Python)
如果您偏好使用系統 Python 安裝而非 uv,您可以從 PyPI 安裝套件並直接執行:
-
使用 pip 安裝套件:
python3 -m pip install mcp-clickhouse若要同時安裝 chDB 支援:
python3 -m pip install 'mcp-clickhouse[chdb]'若要升級至最新版本:
python3 -m pip install --upgrade mcp-clickhouse -
更新您的 Claude Desktop 設定以直接使用 Python:
{
"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"
}
}
}
}
或者,您可以直接使用已安裝的指令碼:
{
"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"
}
}
}
}
注意:如果 Python 可執行檔或 mcp-clickhouse 指令碼不在您的系統 PATH 中,請務必使用完整路徑。您可以使用以下方式找到路徑:
which python3用於 Python 可執行檔which mcp-clickhouse用於已安裝的指令碼
自訂中介層
您可以在不修改原始碼的情況下,為 MCP 伺服器新增自訂中介層。FastMCP 提供中介層系統,讓您能攔截並處理 MCP 協定訊息(工具呼叫、資源讀取、提示等)。
使用方法
- 建立一個 Python 模組,其中包含繼承
Middleware的中介層類別和一個setup_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())
- 將
MCP_MIDDLEWARE_MODULE環境變數設為模組名稱(不含.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"
}
}
}
}
- 確保您的中介層模組位於 Python 的匯入路徑中(例如,與 MCP 伺服器執行所在的目錄相同,或安裝為套件)。
中介層範例
在 example_middleware.py 中提供了一個範例中介層模組,展示常見模式:
- 記錄所有 MCP 請求
- 專門記錄工具呼叫
- 測量請求處理時間
若要使用此範例:
"env": {
"MCP_MIDDLEWARE_MODULE": "example_middleware"
}
中介層功能
Middleware 基底類別為不同的 MCP 操作提供鉤子:
on_message(context, call_next)- 針對所有訊息呼叫on_request(context, call_next)- 針對所有請求呼叫on_notification(context, call_next)- 針對所有通知呼叫on_call_tool(context, call_next)- 執行工具時呼叫on_read_resource(context, call_next)- 讀取資源時呼叫on_get_prompt(context, call_next)- 擷取提示時呼叫on_list_tools(context, call_next)- 列出工具時呼叫on_list_resources(context, call_next)- 列出資源時呼叫on_list_resource_templates(context, call_next)- 列出資源範本時呼叫on_list_prompts(context, call_next)- 列出提示時呼叫
每個鉤子都會收到一個包含訊息和中繼資料的 MiddlewareContext 物件,以及一個用於繼續管線的 call_next 函式。
透過 Context 狀態進行動態用戶端設定
中介層可以使用 CLIENT_CONFIG_OVERRIDES_KEY context 狀態金鑰,以每個請求為基礎覆寫 ClickHouse 用戶端設定。伺服器會將這些覆寫值與環境變數中的基礎設定合併。
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)
這可實現進階使用案例,例如動態逾時調整、租戶特定路由或每個使用者的連線設定。
狀態值必須是字典。巢狀的 settings 和 generic_args 值必須是
對應(mapping),並與基礎設定合併。無效值會在建立 ClickHouse
用戶端之前使工具呼叫失敗。除非覆寫值明確提供 settings.role,否則
CLICKHOUSE_ROLE 仍保持啟用。頂層的 role 和 ch_role 金鑰,以及
generic_args 下的相同金鑰,都會被拒絕。
僅將 verify、ca_cert、client_cert、client_cert_key、tls_mode、server_host_name、
和 pool_mgr 設定為頂層覆寫值。它們不能巢狀在 generic_args 之下。自訂
pool_mgr 不能與受管理的 CA 或用戶端憑證設定結合。DSN 查詢
參數無法設定這些金鑰,且 DSN 無法選取 chdb 後端。請使用明確的
頂層 host、port、username、password、database 和 secure 覆寫值來變更
連線。轉送的 DSN 不會取代已填入的基礎連線欄位或選取
TLS。它可以填補空白欄位並提供受支援的查詢參數,例如 query_limit。
secure 和 verify 覆寫值接受布林值或字串 true 和 false。
verify 也接受 proxy,當 tls_mode 未設定時,其行為等同於
tls_mode: proxy,因此使用環境密碼進行 Basic 驗證。secure 覆寫值會選取相符的 https 或 http 介面,且
不會變更連接埠。明確的 interface 覆寫值必須是 http 或 https,並與
secure 一致。合併覆寫值後,預設和 mutual 用戶端憑證模式會省略
密碼。proxy 和 strict 模式使用環境密碼進行 Basic 驗證,
除非覆寫值提供自己的憑證。
請將這些覆寫值視為受信任的中介層輸入。中介層必須在設定
請求衍生的值之前對其進行驗證和授權。請使用 serializable=False,讓 FastMCP 將
值保留在請求本機狀態中。預設的 serializable=True 會儲存工作階段狀態,且
會被伺服器拒絕。伺服器會在分派阻斷式資料庫
工作之前快照該值。請勿將租戶資料儲存在工作階段範圍的 Context 狀態中。被拒絕的工作階段範圍
覆寫值會保留在舊版 MCP 工作階段中,並導致該工作階段後續的工具呼叫
失敗,直到用戶端重新連線。每個請求的 ClickHouse 角色是連線設定,
而非租戶授權邊界。請使用 ClickHouse 使用者、角色
和授權來強制執行租戶隔離。
開發
-
在
test-services目錄中執行docker compose up -d以啟動 ClickHouse 叢集。 -
在儲存庫根目錄的
.env檔案中新增以下變數。
注意:在此上下文中使用 default 使用者僅供本機開發之用。
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
-
執行
uv sync以安裝相依套件。若要安裝uv,請依照此處的說明操作。然後執行source .venv/bin/activate。 -
若要輕鬆使用 MCP Inspector 進行測試,請執行
uv run fastmcp dev inspector mcp_clickhouse/mcp_server.py:mcp以啟動 MCP 伺服器。 -
若要使用 HTTP 傳輸和健康檢查端點進行測試:
# 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
程式碼配置
該套件採用扁平模組佈局。從 mcp_server.py 開始進行伺服器組裝與註冊,然後沿著實作進入其所属模組。
| 模組 | 職責 |
|---|---|
| mcp_server.py、main.py | 啟動組裝、工具與提示詞註冊、關閉協調,以及 CLI 啟動 |
| clients.py | 請求設定、快取的 ClickHouse 連線,以及用戶端租約 |
| queries.py | 查詢執行、取消,以及破壞性操作防護 |
| metadata.py | 資料庫與資料表探索、中繼資料模型,以及分頁 |
| chdb_backend.py、chdb_prompt.py | 選用的 chDB 初始化、查詢執行,以及提示詞內容 |
| health.py、executors.py | 健康狀態探測與快取,以及伺服器操作使用的工作者池 |
| auth.py、transport.py、http_security.py | Dotenv 載入、驗證、HTTP/SSE 應用程式建構,以及 Host/Origin 驗證 |
| mcp_env.py、serialization.py | 環境設定與 JSON 結果編碼 |
| mcp_middleware_hook.py、skills_advisor.py | 自訂中介軟體載入與伺服器指示 |
每個伺服器組裝都擁有自己的工作者池、用戶端快取、作用中查詢、分頁快取、健康狀態,以及 chDB 後端。工作者與用戶端的清理作業會在程序結束時執行。套件匯入會初始化預設伺服器,包括首次匯入已抽取的模組時。
在測試中,請在程式碼讀取相依性的位置修補模組或擁有者實例。例如,修補 mcp_clickhouse.clients.clickhouse_connect.get_client 以進行用戶端建立。mcp_server.py 中的相容性匯入可以與實作所使用的繫結分開。
環境變數
設定分為獨立的群組。混淆這些群組是造成難以除錯的連線失敗的常見原因:
| 群組 | 變數 | 控制項目 |
|---|---|---|
| ClickHouse 資料庫連線 | CLICKHOUSE_HOST、CLICKHOUSE_PORT、CLICKHOUSE_SECURE、CLICKHOUSE_VERIFY、憑證變數 | 此 MCP 伺服器如何透過 HTTP 介面連線到您的 ClickHouse 叢集 |
| MCP 伺服器 / 傳輸 | CLICKHOUSE_MCP_*、FASTMCP_SERVER_AUTH、FASTMCP_SERVER_AUTH_*、FASTMCP_ENV_FILE | MCP 傳輸、驗證,以及查詢工具執行限制 |
| 中介軟體 / chDB | MCP_MIDDLEWARE_MODULE、CHDB_* | 選用擴充功能 |
[!IMPORTANT]
CLICKHOUSE_SECURE、CLICKHOUSE_VERIFY、CLICKHOUSE_CA_CERT、CLICKHOUSE_CLIENT_CERT、CLICKHOUSE_CLIENT_CERT_KEY、CLICKHOUSE_TLS_MODE和CLICKHOUSE_PORT僅適用於對外的 ClickHouse 資料庫連線。它們不會設定入站 MCP HTTP/SSE 端點的 TLS、用戶端憑證、連接埠或驗證。範例:如果 MCP 伺服器在 Kubernetes 中執行於終止 TLS 的 ingress 之後,那是 MCP 傳輸的考量。請讓
CLICKHOUSE_SECURE與 Pod 如何連線到 ClickHouse 本身保持一致(HTTPS →true,純 HTTP →false)。因為 MCP 伺服器位於 ingress 之後而設定CLICKHOUSE_SECURE=false,會讓伺服器透過 HTTP 撥打 ClickHouse——通常會指向僅限 HTTPS 的連接埠——並在伺服器日誌中產生難以理解的 HTTP/TLS 錯誤。
ClickHouse 資料庫連線
這些變數設定 clickhouse-connect HTTP 用戶端,以及由 ClickHouse 支援的工具(例如 run_query、list_databases 和 list_tables)的行為。mcp-clickhouse 需要 clickhouse-connect 1.x,從 1.0.0 開始。
必要變數
CLICKHOUSE_HOST:您的 ClickHouse 伺服器主機名稱(資料庫端點,不是 MCP 伺服器繫結位址)CLICKHOUSE_USER:用於 ClickHouse 驗證的使用者名稱CLICKHOUSE_PASSWORD:用於 ClickHouse 驗證的密碼- 除非
CLICKHOUSE_CLIENT_CERT使用預設值或"mutual"TLS 模式,否則為必填 - 在預設或
"mutual"模式下,會使用憑證驗證,且不會傳送密碼
- 除非
[!CAUTION] 請務必將您的 MCP 資料庫使用者視為任何連線到您資料庫的外部用戶端,僅授予其操作所需的最低必要權限。應嚴格避免隨時使用預設或管理員使用者。
選用變數
CLICKHOUSE_PORT:您的 ClickHouse 伺服器的 HTTP 介面連接埠- 預設值:若為
CLICKHOUSE_SECURE=true則為8443,若為CLICKHOUSE_SECURE=false則為8123 - 除非使用非標準連接埠,否則通常不需要設定
- 必須是 HTTP 介面連接埠,不是
clickhouse-client使用的原生 TCP 協定連接埠 - 常見值:
- HTTP:
8123(純文字)/8443(TLS)——由此伺服器及 ClickHouse Cloud HTTPS 使用 - 原生 TCP(此處不支援):
9000(純文字)/9440(TLS)——由clickhouse-client使用
- HTTP:
- 如果伺服器回應
Port 9000 is for clickhouse-client program,表示您指向了原生協定;請切換到 HTTP 連接埠(8123/8443或您部署的 HTTP 對應)
- 預設值:若為
CLICKHOUSE_ROLE:用於驗證的 ClickHouse 角色- 預設值:None
- 如果您的使用者需要特定角色,請設定此項
CLICKHOUSE_SECURE:為 ClickHouse 資料庫連線啟用 HTTPS(不是為 MCP 用戶端)- 預設值:
"true" - 僅在 MCP 伺服器透過純 HTTP 連線到 ClickHouse 時設定為
"false"(典型情況為連接埠8123上的本機 Docker Compose) - 對於 ClickHouse Cloud 和任何 HTTPS 資料庫端點,請保留
"true"——即使 MCP 伺服器本身透過 HTTP、stdio 或分別終止 TLS 的 ingress 公開 - 此旗標與資料庫連接埠不符(例如連接埠
8443上的CLICKHOUSE_SECURE=false)是常見的設定錯誤,通常會顯示為令人困惑的 HTTP 用戶端錯誤,而不是明確的「配置錯誤」訊息
- 預設值:
CLICKHOUSE_VERIFY:為 ClickHouse HTTPS 連線啟用/停用 SSL 憑證驗證- 預設值:
"true" - 設定為
"false"以停用憑證驗證(不建議用於生產環境) - TLS 憑證:套件在啟動時透過
truststore.inject_into_ssl()使用您的作業系統信任儲存庫。如果使用MCP_CLICKHOUSE_TRUSTSTORE_DISABLE=1停用注入或注入失敗,則使用 Python 的預設 SSL 處理。
- 預設值:
MCP_CLICKHOUSE_TRUSTSTORE_DISABLE:停用 TLS 的整個程序作業系統信任儲存庫整合- 預設值:未設定(信任儲存庫整合已啟用)
- 在啟動前設定為完全等於
"1"以略過truststore.inject_into_ssl(),並使用 Python 的預設 SSL 憑證處理。其他值不會停用此整合。 - 這不會停用憑證驗證。
CLICKHOUSE_VERIFY仍控制 ClickHouse HTTPS 連線的驗證。
CLICKHOUSE_CA_CERT:用於 ClickHouse HTTPS 連線的 PEM CA 憑證套件路徑- 預設值:None(除非信任儲存庫注入已停用或失敗,否則使用作業系統信任儲存庫)
- 當 ClickHouse 伺服器或私人代理呈現由私人 CA 簽署的憑證時,請單獨使用此項。這會變更伺服器憑證驗證,且不會啟用用戶端憑證驗證。
- 需要
CLICKHOUSE_SECURE=true和CLICKHOUSE_VERIFY=true
CLICKHOUSE_CLIENT_CERT:用於 ClickHouse HTTPS 連線的 PEM 用戶端憑證路徑- 預設值:None
- 檔案也可能包含私密金鑰。否則請設定
CLICKHOUSE_CLIENT_CERT_KEY。 - ClickHouse 使用者仍來自
CLICKHOUSE_USER。
CLICKHOUSE_CLIENT_CERT_KEY:CLICKHOUSE_CLIENT_CERT的 PEM 私密金鑰路徑- 預設值:None
- 當私密金鑰包含在用戶端憑證檔案中時為選用
- 不能沒有
CLICKHOUSE_CLIENT_CERT而使用
CLICKHOUSE_TLS_MODE:clickhouse-connect 如何使用CLICKHOUSE_CLIENT_CERT- 預設值:None,當設定用戶端憑證時行為等同於
"mutual" "mutual":使用用戶端憑證進行 ClickHouse X.509 使用者驗證。CLICKHOUSE_PASSWORD為選用,且不會傳送。"proxy":向終止 TLS 的代理呈現用戶端憑證,然後使用 ClickHouse Basic 驗證。CLICKHOUSE_PASSWORD為必填。"strict":因為 ClickHouse 伺服器在 TLS 層要求用戶端憑證而呈現用戶端憑證,然後使用 ClickHouse Basic 驗證。CLICKHOUSE_PASSWORD為必填。此模式不會加強伺服器憑證驗證。CLICKHOUSE_VERIFY控制該驗證。- clickhouse-connect 將
"proxy"和"strict"視為相同。這兩個名稱用於說明意圖。 - 值會去除前後空白且不區分大小寫。空白值視為未設定。其他值會在建立 ClickHouse 用戶端之前、於第一次 ClickHouse 工具呼叫或
/health探測時被拒絕。 - 需要
CLICKHOUSE_CLIENT_CERT。所有用戶端憑證選項都需要CLICKHOUSE_SECURE=true。
- 預設值:None,當設定用戶端憑證時行為等同於
CLICKHOUSE_SERVER_HOST_NAME:用於 ClickHouse 連線的 SNI 覆寫和憑證驗證的伺服器主機名稱- 預設值:None(使用連線主機名稱)
- 當透過代理或負載平衡器連線,且憑證主機名稱與連線主機名稱不同時,此項很有用。設定後,此主機名稱將用於 TLS 交握期間的 SNI(伺服器名稱指示)和憑證主機名稱驗證。
CLICKHOUSE_PROXY_PATH:ClickHouse HTTP 端點的 URL 路徑前綴- 預設值:None
- 當 ClickHouse HTTP 介面在反向代理後以路徑前綴公開時設定此項(例如
/clickhouse)
CLICKHOUSE_CONNECT_TIMEOUT:ClickHouse 用戶端的連線逾時(秒)- 預設值:
"30" - 如果您遇到連線逾時,請增加此值
- 預設值:
CLICKHOUSE_SEND_RECEIVE_TIMEOUT:ClickHouse 用戶端的傳送/接收逾時(秒)- 預設值:
300或CLICKHOUSE_MCP_QUERY_TIMEOUT + 5中較低者,因此工作者執行緒會在查詢逾時後不久解除封鎖 - 如果明確設定,則該值會原樣使用(例如長時間執行的查詢使用
"300")
- 預設值:
CLICKHOUSE_DATABASE:要使用的預設 ClickHouse 資料庫- 預設值:None(使用伺服器預設值)
- 設定此項以自動連線到特定資料庫
CLICKHOUSE_ENABLED:啟用/停用 ClickHouse 資料庫工具- 預設值:
"true" - 僅使用 chDB 時,設定為
"false"以停用 ClickHouse 工具
- 預設值:
CLICKHOUSE_ALLOW_WRITE_ACCESS:允許對 ClickHouse 執行寫入操作(DDL 和 DML)- 預設值:
"false" - 設定為
"true"以允許非破壞性 DDL 和 DML(CREATE、INSERT、ALTER ADD COLUMN)。破壞性陳述式還需要CLICKHOUSE_ALLOW_DROP=true - 停用時(預設),查詢會以
readonly=1設定執行,以防止資料修改
- 預設值:
CLICKHOUSE_ALLOW_DROP:允許破壞性操作(任何DROP或TRUNCATE、DELETE和UPDATE包括ALTER TABLE變體、REPLACE TABLE/REPLACE PARTITION/CREATE OR REPLACE、CLEAR COLUMN/CLEAR INDEX/CLEAR PROJECTION,以及DETACH ... PERMANENTLY)- 預設值:
"false" - 僅在同時設定
CLICKHOUSE_ALLOW_WRITE_ACCESS=true時生效 - 此閘道是 MCP 伺服器中的盡力而為意外防護,不是安全邊界。請限制 ClickHouse 使用者的授權以進行真正的強制執行(請參閱 破壞性操作保護)
- 預設值:
ClickHouse TLS 憑證檔案
憑證變數包含檔案路徑,不是 PEM 內容。mcp-clickhouse 會將這些路徑傳遞給 clickhouse-connect。對於 Docker 或 Kubernetes,請將憑證和私密金鑰掛載為唯讀檔案,並使用容器內的路徑。請勿將私密金鑰烘焙到映像中、提交到原始碼控制,或將其內容放入環境變數。
在 mutual 模式下,設定的用戶端憑證會將此 mcp-clickhouse 程序識別為 CLICKHOUSE_USER。它不會驗證入站 MCP 用戶端,也不會將其身分傳遞給 ClickHouse。請另行設定 MCP 傳輸驗證。
若需立即輪換或撤銷憑證,請在相同路徑替換憑證或金鑰後重新啟動 mcp-clickhouse。快取的用戶端可能保留現有的 TLS 連線,且快取不會追蹤檔案內容或修改時間。
ClickHouse Cloud 不支援資料庫用戶端的 X.509 用戶端憑證驗證。請對 ClickHouse Cloud 使用 CLICKHOUSE_USER 和 CLICKHOUSE_PASSWORD。當端點前方的私人代理出示由私人 CA 簽署的憑證時,CA 憑證仍然可能有用。
MCP 伺服器與傳輸
這些變數控制 MCP 程序本身,包括傳輸、驗證和查詢工具執行限制。它們與上述 ClickHouse 資料庫設定無關。另請參閱 HTTP/SSE 傳輸的驗證。
CLICKHOUSE_MCP_SERVER_TRANSPORT:設定 MCP 伺服器的傳輸方法- 預設值:
"stdio" - 有效選項:
"stdio"、"http"、"sse"。這對於使用 MCP Inspector 等工具進行本機開發很有用。 stdio是 Claude Desktop 的典型選擇;http/sse會暴露網路監聽器(繫結下方的主機/連接埠)"sse"選擇已棄用的獨立 HTTP+SSE 傳輸並記錄警告。在新部署中請使用"http"以使用 Streamable HTTP。
- 預設值:
CLICKHOUSE_MCP_BIND_HOST:使用 HTTP 或 SSE 傳輸時,MCP 伺服器繫結的主機- 預設值:
"127.0.0.1" - 設定為
"0.0.0.0"以繫結到所有網路介面(適用於 Docker 或遠端存取) - 僅在傳輸為
"http"或"sse"時使用——與CLICKHOUSE_HOST無關
- 預設值:
CLICKHOUSE_MCP_BIND_PORT:使用 HTTP 或 SSE 傳輸時,MCP 伺服器繫結的連接埠- 預設值:
"8000" - 僅在傳輸為
"http"或"sse"時使用——與CLICKHOUSE_PORT無關
- 預設值:
CLICKHOUSE_MCP_QUERY_TIMEOUT:查詢工具呼叫的逾時秒數- 預設值:
"30" - 若您對重量級查詢看到
Query timed out after ...錯誤,請增加此值 - 當查詢逾時時,伺服器會嘗試使用
KILL QUERY取消它 - 除非明確設定
CLICKHOUSE_SEND_RECEIVE_TIMEOUT,否則 HTTP 讀取逾時上限為此值加五秒
- 預設值:
CLICKHOUSE_MCP_MAX_WORKERS:最大並行查詢工作執行緒數- 預設值:
"10" - 若您的工作負載需要大量並行工具呼叫,請增加此值
- 元資料工具使用具有
min(4, CLICKHOUSE_MCP_MAX_WORKERS)執行緒的單獨執行緒池,因此結構描述探索不會延遲查詢
- 預設值:
CLICKHOUSE_MCP_AUTH_TOKEN:HTTP/SSE 傳輸的靜態 bearer token- 預設值:無
CLICKHOUSE_MCP_AUTH_TOKEN、FASTMCP_SERVER_AUTH或CLICKHOUSE_MCP_AUTH_DISABLED=true其中之一是 HTTP/SSE 傳輸的必要項目- 使用
uuidgen或openssl rand -hex 32產生 - 用戶端必須在
Authorization: Bearer <token>標頭中傳送此 token
FASTMCP_SERVER_AUTH:將驗證委派給 FastMCP auth provider- 預設值:無
- 值為 AuthProvider 子類別的完整類別路徑,例如
fastmcp.server.auth.providers.azure.AzureProvider或fastmcp.server.auth.providers.google.GoogleProvider - 設定後,mcp-clickhouse 會從現有的
FASTMCP_SERVER_AUTH_*環境變數載入 provider;在此模式下請將CLICKHOUSE_MCP_AUTH_TOKEN保留為未設定 - 自訂 provider 不會收到環境衍生的建構子引數,且必須支援無引數建構
- FastMCP 4 不再支援 Supabase HS256 驗證。Supabase 部署必須使用 RS256 或 ES256。
FASTMCP_ENV_FILE:包含FASTMCP_SERVER_AUTH和 provider 特定環境變數的選用檔案- 預設值:無。未設定時,相容性載入器會從工作目錄中的
.env讀取缺少的 provider 欄位。它不會從該後備讀取FASTMCP_SERVER_AUTH - 請在啟動前於程序環境中設定它。從預設
.env載入的值無法重新導向相容性載入器 - 若由程序設定,此檔案可能提供
FASTMCP_SERVER_AUTH和 provider 欄位,並取代工作目錄後備 - 程序環境值以不區分大小寫的方式優先
- mcp-clickhouse 相容性載入器僅在建構 HTTP/SSE 驗證時讀取此檔案,且僅讀取
FASTMCP_SERVER_AUTH和FASTMCP_SERVER_AUTH_*條目。FastMCP 4 可能為其更廣泛的設定讀取相同檔案 - 預設的
.env載入是分開的。它從已安裝的mcp_clickhouse套件目錄開始,解析符號連結,向上走到檔案系統根目錄,並載入找到的第一個.env或什麼都不載入。它永遠不會讀取工作目錄,無論啟動方式為何。該檔案可能提供FASTMCP_SERVER_AUTH和 provider 欄位以及其他伺服器設定。原始碼檢出通常會找到儲存庫根目錄的.env
- 預設值:無。未設定時,相容性載入器會從工作目錄中的
CLICKHOUSE_MCP_AUTH_DISABLED:停用 HTTP/SSE 傳輸的驗證- 預設值:
"false"(驗證已啟用) - 設定為
"true"以僅在本地開發/測試時停用驗證 - 警告: 僅供本地開發使用。暴露於網路時請勿停用
- 預設值:
CLICKHOUSE_MCP_ALLOWED_HOSTS:HTTP/SSE 伺服器回應的逗號分隔Host標頭值- 迴環繫結的預設值:
127.0.0.1、localhost和[::1]的裸形式和任意連接埠形式 - 若設定,值必須包含至少一個 Host 條目。
- 具體的非迴環繫結位址預設為該位址和設定的連接埠。萬用字元繫結(如
0.0.0.0或::)需要明確的非空值,因為無法推斷公開 Host。 - Host 驗證是針對 DNS 重新綁定的縱深防禦。下方的 Origin 驗證由 MCP 另行要求。
- 條目為精確(
localhost:8000)或接受任意連接埠(localhost:*)。範例:CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000 host:*形式僅比對帶有連接埠的值。無連接埠的 Host(用戶端省略:80/:443的標準連接埠部署)也必須列為裸精確條目(example.com)。- 帶有不比對或缺少
Host標頭的要求會收到421 Misdirected Request。對/health的 GET 和 HEAD 要求豁免於 Host 和 Origin 驗證,以便編排器探測繼續運作。 - 在反向代理後方,建議保留原始的
Host標頭。您也可以改為列出代理傳送的 upstreamHost值。當啟動器(如fastmcp run)為遠端存取覆寫繫結位址時,請設定明確的清單。 - mcp-clickhouse 會強制關閉 FastMCP 的獨立 Host 和 Origin 防護。
FASTMCP_HTTP_HOST_ORIGIN_PROTECTION、FASTMCP_HTTP_ALLOWED_HOSTS和FASTMCP_HTTP_ALLOWED_ORIGINS不適用。CLICKHOUSE_MCP_ALLOWED_HOSTS和CLICKHOUSE_MCP_ALLOWED_ORIGINS具有權威性。
- 迴環繫結的預設值:
CLICKHOUSE_MCP_TRUSTED_PROXIES:其X-Forwarded-*標頭受信任的代理 IP 位址或 CIDR 網路- 預設值:無。
X-Forwarded-Host被忽略。Uvicorn 對X-Forwarded-For和X-Forwarded-Proto的現有處理不變。 - 條目必須是 IP 位址或 CIDR 網路,例如
127.0.0.1,10.20.0.0/24,2001:db8::1。CIDR 必須使用其網路位址,因此10.20.0.1/24會被拒絕。主機名稱、有範圍的 IPv6 位址、*、0.0.0.0/0和::/0也會被拒絕。 - 信任基於直接的原始 socket 對端。來自任何其他對端的要求,或沒有用戶端位址的要求,會忽略
X-Forwarded-Host並驗證Host。 - 受信任的對端可能傳送恰好一個包含一個非空值的
X-Forwarded-Host標頭。重複欄位、空值和逗號分隔清單會收到421 Misdirected Request。若標頭不存在,則驗證Host。 - 使用盡可能狹窄的位址或網路。MCP 伺服器必須只能透過設定範圍內的代理存取。每個受信任的代理必須剝離並覆寫用戶端提供的
X-Forwarded-Host和X-Forwarded-Proto值,並從驗證的連線對端建構X-Forwarded-For。 - 內建伺服器和
fastmcp run會停用 Uvicorn 的外部代理標頭處理,從原始對端驗證 Host,然後套用X-Forwarded-For和X-Forwarded-Proto。在此模式下明確啟用uvicorn_config["proxy_headers"]會導致啟動失敗。 - 直接 ASGI 嵌入必須停用外部 ASGI 伺服器中的代理標頭處理,並呼叫
mcp.http_app(raw_client_address_preserved=True)。沒有該明確斷言,在設定受信任代理時應用程式建構會失敗。
- 預設值:無。
CLICKHOUSE_MCP_ALLOWED_ORIGINS:HTTP/SSE 上接受的逗號分隔Origin標頭值- 預設值:無,這會拒絕每個帶有
Origin標頭的要求 - MCP 要求對 HTTP/SSE 傳輸連線進行 Origin 驗證。沒有 Origin 的要求會被接受,因為非瀏覽器 MCP 用戶端通常會省略它。不比對的 Origin 會收到
403 Forbidden。/health端點如上所述豁免。 - 條目為精確(
http://localhost:3000)或接受任意連接埠(http://localhost:*)。與主機一樣,任意連接埠形式僅比對帶有連接埠的 origin;標準連接埠 origin(https://app.example.com)必須精確列出。
- 預設值:無,這會拒絕每個帶有
反向代理 Host 處理
盡可能保留 Host。這會保持轉發的 Host 信任停用:
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;
}
獨立於 X-Forwarded-Host 信任清理 X-Forwarded-For 和 X-Forwarded-Proto。即使 CLICKHOUSE_MCP_TRUSTED_PROXIES 未設定,Uvicorn 也可能基於代理對端信任這些標頭。
CLICKHOUSE_MCP_ALLOWED_HOSTS=mcp.example.com
標準 nginx 會將代理要求的 Host 變更為 upstream 名稱。它不會建立或覆寫 X-Forwarded-Host。若無法保留 Host,請在受信任的邊緣覆寫轉發的標頭:
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
第二個設定僅在 10.20.0.8 是代理的直接來源位址、伺服器連接埠與其他用戶端隔離,且 nginx 如所示覆寫傳入的轉發標頭時才安全。對於代理鏈,每個受信任的跳點必須在建構新的轉發標頭前丟棄未驗證的傳入值。
在 IPv6 或雙堆疊繫結上,IPv4 代理可能顯示為 IPv4 映射位址(如 ::ffff:10.20.0.8);這些會自動與 IPv4 條目比對。Envoy 的 append_x_forwarded_host 會附加到現有的 X-Forwarded-Host 而非覆寫它,產生會被拒絕的逗號分隔清單,因此請設定受信任的跳點改為覆寫標頭。在具有來源 NAT 的 Kubernetes 上(例如 externalTrafficPolicy: Cluster),觀察到的對端可能是節點 IP 而非代理 pod,因此請視情況信任 pod 或節點 CIDR;ingress-nginx 會自行覆寫 Host 和 X-Forwarded-Host。
中介軟體變數
MCP_MIDDLEWARE_MODULE:包含要注入 MCP 伺服器的自訂中介軟體之 Python 模組名稱- 預設值:無(不載入中介軟體)
- 設定為中介軟體模組的模組名稱(不含
.py副檔名) - 模組必須提供
setup_middleware(mcp)函式 - 詳情和範例請參閱 自訂中介軟體
chDB 變數
CHDB_ENABLED:啟用/停用 chDB 功能- 預設值:
"false" - 設定為
"true"以啟用 chDB 工具 - 需要安裝選用的額外套件:
mcp-clickhouse[chdb]
- 預設值:
CHDB_DATA_PATH:chDB 資料目錄的路徑- 預設值:
":memory:"(記憶體中資料庫) - 使用
:memory:作為記憶體中資料庫 - 使用檔案路徑進行持久化儲存(例如
/path/to/chdb/data)
- 預設值:
常見設定陷阱
CLICKHOUSE_SECURE與 MCP / ingress TLS 的差異 — 關閉CLICKHOUSE_SECURE是因為 MCP 伺服器位於 Kubernetes ingress、反向代理之後,或透過純 HTTP 連線,這並不會停用資料庫的 TLS;它只會改變此程序連線到 ClickHouse 的方式。請將 ingress TLS 與資料庫用戶端設定分開配置。- 原生協定連接埠 —
CLICKHOUSE_PORT必須指向 ClickHouse 的 HTTP 介面(預設為8123/8443)。連接埠9000/9440用於原生 TCP 協定(clickhouse-client),無法與此伺服器搭配使用。 - 主機名稱混淆 —
CLICKHOUSE_HOST是資料庫主機名稱。CLICKHOUSE_MCP_BIND_HOST僅是 MCP HTTP/SSE 伺服器監聽的位址。
範例配置
用於本機 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
用於 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
用於 ClickHouse SQL Playground:
CLICKHOUSE_HOST=sql-clickhouse.clickhouse.com
CLICKHOUSE_USER=demo
CLICKHOUSE_PASSWORD=
# Uses secure defaults (HTTPS on port 8443)
用於沒有用戶端憑證驗證的私有伺服器 CA:
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
用於 ClickHouse X.509 用戶端憑證驗證:
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.
當嚴格 TLS 伺服器要求用戶端憑證,而 ClickHouse 使用 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
當 TLS 終止代理要求用戶端憑證,而 ClickHouse 仍使用 Basic 驗證時,請改用 CLICKHOUSE_TLS_MODE=proxy。
僅用於 chDB(記憶體中):
# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
# CHDB_DATA_PATH defaults to :memory:
用於具有持久化儲存的 chDB:
# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
CHDB_DATA_PATH=/path/to/chdb/data
用於 MCP Inspector 或透過 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
用於本機開發搭配 HTTP 傳輸(停用驗證):
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
使用 HTTP 傳輸時,伺服器將在配置的連接埠(預設 8000)上執行。例如,使用上述配置:
- MCP 端點:
http://localhost:8000/mcp - 健康檢查:
http://localhost:8000/health
您可以將這些變數設定在環境中、.env 檔案中,或 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"
}
}
}
}
注意:綁定主機和連接埠設定僅在傳輸設定為 "http" 或 "sse" 時使用。
執行測試
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
