关于 ClickHouse MCP Server
ClickHouse MCP Server 是面向 ClickHouse 数据库的 MCP 服务,让 AI 助手可以查询和浏览集群中的数据库与表。默认以只读模式运行,并支持 HTTP/SSE 传输下的身份验证。
主要功能
- 01run_query 工具执行 SQL 查询
- 02支持 {name:Type} 形式的参数绑定
- 03list_databases 与 list_tables 浏览集群结构
- 04list_tables 支持分页与 LIKE 过滤
- 05DESCRIBE 与 EXPLAIN ESTIMATE 预先检查查询
- 06/health 健康检查端点
适用场景
- 01让 AI 助手直接查询 ClickHouse 数据进行分析
- 02在执行大型查询前用 EXPLAIN ESTIMATE 评估读取量
- 03通过 chDB 查询文件或 URL 中的数据而无需 ETL
MCP 相关
该项目是 MCP 服务,向 MCP 客户端暴露 run_query、list_databases、list_tables 和 run_chdb_select_query 等工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mcp-clickhouseCLICKHOUSE_HOSTHostname of the ClickHouse serverCLICKHOUSE_USERUsername for ClickHouse authenticationCLICKHOUSE_PASSWORD密钥Password for ClickHouse authentication. Required unless a client certificate uses the default or mutual TLS modeCLICKHOUSE_PORTClickHouse HTTP(S) port. Defaults to 8443 when CLICKHOUSE_SECURE=true, 8123 otherwiseCLICKHOUSE_SECUREUse HTTPS to connect to ClickHouseCLICKHOUSE_VERIFYVerify SSL certificatesCLICKHOUSE_CA_CERTPath to a PEM CA bundle for ClickHouse server certificate verificationCLICKHOUSE_CLIENT_CERTPath to a PEM client certificate for the ClickHouse HTTPS connectionCLICKHOUSE_CLIENT_CERT_KEY密钥Path to the PEM private key for CLICKHOUSE_CLIENT_CERTCLICKHOUSE_TLS_MODEClient certificate mode: mutual, proxy, or strictCLICKHOUSE_DATABASEDefault database to useCLICKHOUSE_ROLEClickHouse role to activate for the sessionCLICKHOUSE_ALLOW_WRITE_ACCESSAllow write operations (DDL and DML). Queries run read-only by defaultCLICKHOUSE_ALLOW_DROPAllow destructive operations (DROP, TRUNCATE, DELETE, UPDATE, REPLACE, CLEAR, and DETACH PERMANENTLY) when write access is also enabledCLICKHOUSE_MCP_QUERY_TIMEOUTQuery tool timeout in secondsCLICKHOUSE_MCP_MAX_WORKERSMaximum query worker thread pool size本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
3收录的工具列表 · 更新于 3 周前
此工具无需参数。
详细介绍
ClickHouse MCP 服务
适用于 ClickHouse 的 MCP 服务。
该服务实现了 MCP 2026-07-28,并支持从 2024-11-05 到 2025-11-25 的旧版初始化握手。现代客户端使用无会话请求和 server/discover。现有客户端可以继续协商旧版协议。
说明
不包含
MCP-Protocol-Version的 HTTP 请求会通过旧版处理路径进行路由,以便2025-06-18之前的客户端继续连接。MCP2026-07-28允许支持这些客户端的服务采用此行为。现代客户端应在每个 POST 请求中发送该标头。
功能
ClickHouse 工具
ClickHouse 工具的响应是经过 JSON 编码的字符串。为确保 JavaScript 客户端中的值精确无误,超出 [-9007199254740991, 9007199254740991] 范围的整数会以十进制字符串形式返回。此规则适用于查询行和整数型表元数据。安全范围内的整数和布尔值仍保留其 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:符合所提供筛选条件的表总数。
Agents 架构发现
当 list_databases 显示存在 AGENTS 数据库时,服务指令建议先通过 run_query 读取 Agents Schema 的规范 AGENTS.ROOT,然后再编写分析 SQL。这是给 Agent 的指导:不会自动获取任何元数据,工具结果保持不变,现有的 ClickHouse 权限仍然适用。如果 AGENTS.ROOT 缺失或无法访问,仍可进行常规发现和查询。
查询参数
通过可选的 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 类型匹配:
- 对
Nullable(...)类型使用null。 - 对超出 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、行数和 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 存活性/就绪性探测、负载均衡器)无需额外配置即可使用运行时分配的 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 文件都视为可信的身份验证配置。任何能够在从包
目录到文件系统根目录之间的任一目录中创建或写入 .env 的人,都可以控制会发现哪个文件、
选择提供方并设置其字段。任何能够写入工作目录文件的人,都可以控制进程环境和已发现配置中
未提供的所有提供方字段,包括签名密钥、签发方和端点,以及客户端密钥。在进程中设置指向
运维人员所拥有文件的 FASTMCP_ENV_FILE,即可禁用工作目录回退。
FastMCP 4 更改了默认的 OAuth 代理客户端存储。依赖 FastMCP 2 默认 OAuth 代理存储的部署, 必须让客户端重新注册并授权。 兼容的自定义存储、静态承载令牌和 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 用户取消自己的查询,包括使用同一用户从其他连接发出的查询。即使在只读模式下,也请使用专用的 ClickHouse 用户。对于不应相互取消查询的工作负载,请使用不同的 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 函数。
通过上下文状态动态配置客户端
中间件可以使用 CLIENT_CONFIG_OVERRIDES_KEY 上下文状态键,按请求覆盖 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 值必须是映射,并会与基础配置合并。值无效时,工具调用会在创建 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_* | 可选扩展 |
重要
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 传输范畴。应根据 Pod 连接 ClickHouse 本身的方式设置
CLICKHOUSE_SECURE(HTTPS →true,普通 HTTP →false)。如果因为 MCP 服务位于 ingress 后面而设置CLICKHOUSE_SECURE=false,服务将通过 HTTP 连接 ClickHouse——通常会连接到仅支持 HTTPS 的端口,并在服务日志中产生难以辨认的 HTTP/TLS 错误。
ClickHouse 数据库连接
这些变量用于配置 clickhouse-connect HTTP 客户端,以及 run_query、list_databases 和 list_tables 等由 ClickHouse 驱动的工具的行为。
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"模式下,使用证书进行身份验证,不会发送密码
- 除非
注意
请务必像对待连接数据库的任何外部客户端一样对待 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 角色- 默认值:无
- 如果用户需要特定角色,请设置此项
CLICKHOUSE_SECURE:为 ClickHouse 数据库连接启用 HTTPS(不适用于 MCP 客户端)- 默认值:
"true" - 仅当 MCP 服务通过普通 HTTP 连接到 ClickHouse 时,才设置为
"false"(本地 Docker Compose 使用端口8123时通常如此) - 对于 ClickHouse Cloud 和任何 HTTPS 数据库端点,请保留为
"true"——即使 MCP 服务本身通过 HTTP、stdio 或单独终止 TLS 的入口对外提供服务 - 此标志与数据库端口不匹配(例如,针对端口
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 证书包的路径- 默认值:无(使用操作系统的信任存储,除非信任存储注入已禁用或失败)
- 如果 ClickHouse 服务或私有代理提供的证书由私有 CA 签名,可单独使用此项。它会更改服务端证书验证方式,但不会启用客户端证书身份验证。
- 需要
CLICKHOUSE_SECURE=true和CLICKHOUSE_VERIFY=true
CLICKHOUSE_CLIENT_CERT:ClickHouse HTTPS 连接所用 PEM 客户端证书的路径- 默认值:无
- 文件也可以包含私钥。否则请设置
CLICKHOUSE_CLIENT_CERT_KEY。 - ClickHouse 用户仍由
CLICKHOUSE_USER指定。
CLICKHOUSE_CLIENT_CERT_KEY:CLICKHOUSE_CLIENT_CERT对应 PEM 私钥的路径- 默认值:无
- 如果客户端证书文件中包含私钥,则此项可选
- 不能在未设置
CLICKHOUSE_CLIENT_CERT时使用
CLICKHOUSE_TLS_MODE:clickhouse-connect 使用CLICKHOUSE_CLIENT_CERT的方式- 默认值:无;如果已设置客户端证书,则行为等同于
"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 工具或探测
/health时、创建 ClickHouse 客户端之前被拒绝。 - 需要
CLICKHOUSE_CLIENT_CERT。所有客户端证书选项都需要CLICKHOUSE_SECURE=true。
- 默认值:无;如果已设置客户端证书,则行为等同于
CLICKHOUSE_SERVER_HOST_NAME:用于覆盖 SNI 并验证 ClickHouse 连接证书的服务主机名- 默认值:无(使用连接主机名)
- 通过代理或负载均衡器连接时,如果证书主机名与连接主机名不同,此项会很有用。设置后,此主机名会同时用于 TLS 握手期间的 SNI(服务器名称指示)和证书主机名验证。
CLICKHOUSE_PROXY_PATH:ClickHouse HTTP 端点的 URL 路径前缀- 默认值:无
- 如果 ClickHouse HTTP 接口通过反向代理以带路径前缀的形式公开(例如
/clickhouse),请设置此项
CLICKHOUSE_CONNECT_TIMEOUT:ClickHouse 客户端的连接超时时间,单位为秒- 默认值:
"30" - 如果遇到连接超时,请增大此值
- 默认值:
CLICKHOUSE_SEND_RECEIVE_TIMEOUT:ClickHouse 客户端的发送/接收超时时间,单位为秒- 默认值:
300和CLICKHOUSE_MCP_QUERY_TIMEOUT + 5中的较小值,使工作线程在查询超时后不久即可解除阻塞 - 如果显式设置,则按原值使用(例如,长时间运行的查询可设置为
"300")
- 默认值:
CLICKHOUSE_DATABASE:要使用的默认 ClickHouse 数据库- 默认值:无(使用服务端默认值)
- 设置此项可自动连接到指定数据库
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 等工具进行本地开发。 - Claude Desktop 通常使用
stdio;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 读取超时时间上限为此值加 5 秒
- 默认值:
CLICKHOUSE_MCP_MAX_WORKERS:并发查询工作线程的最大数量- 默认值:
"10" - 如果工作负载需要大量并发工具调用,可调高此值
- 元数据工具使用独立的线程池,线程数为
min(4, CLICKHOUSE_MCP_MAX_WORKERS),这样模式发现就不会延迟查询
- 默认值:
CLICKHOUSE_MCP_AUTH_TOKEN:用于 HTTP/SSE 传输的静态 bearer 令牌- 默认值:无
- HTTP/SSE 传输必须设置
CLICKHOUSE_MCP_AUTH_TOKEN、FASTMCP_SERVER_AUTH或CLICKHOUSE_MCP_AUTH_DISABLED=true其中之一 - 使用
uuidgen或openssl rand -hex 32生成 - 客户端必须在
Authorization: Bearer <token>标头中发送此令牌
FASTMCP_SERVER_AUTH:将身份验证委托给 FastMCP 身份验证提供程序- 默认值:无
- 值为 AuthProvider 子类的完整类路径,例如
fastmcp.server.auth.providers.azure.AzureProvider或fastmcp.server.auth.providers.google.GoogleProvider - 设置后,mcp-clickhouse 会从现有的
FASTMCP_SERVER_AUTH_*环境变量加载提供程序;此模式下请勿设置CLICKHOUSE_MCP_AUTH_TOKEN - 自定义提供程序不会接收从环境变量派生的构造函数参数,并且必须支持无参数构造
- FastMCP 4 不再支持 Supabase HS256 验证。Supabase 部署必须使用 RS256 或 ES256。
FASTMCP_ENV_FILE:可选文件,包含FASTMCP_SERVER_AUTH和提供程序专用的环境变量- 默认值:无。未设置时,兼容性加载器会从工作目录中的
.env读取缺失的提供程序字段,但不会从该回退文件读取FASTMCP_SERVER_AUTH - 请在启动前于进程环境中设置此变量。从默认
.env加载的值无法重定向兼容性加载器 - 如果在进程环境中设置,此文件可以同时提供
FASTMCP_SERVER_AUTH和提供程序字段,并会取代工作目录回退文件 - 进程环境变量的优先级更高,且比较时不区分大小写
- mcp-clickhouse 兼容性加载器仅在构建 HTTP/SSE 身份验证时读取此文件,且只读取
FASTMCP_SERVER_AUTH和FASTMCP_SERVER_AUTH_*条目。FastMCP 4 可能会为其更广泛的设置读取同一文件 - 默认
.env的加载是独立的。加载器从已安装的mcp_clickhouse包目录开始,解析符号链接,再向上遍历到文件系统根目录,并加载找到的第一个.env,如果没有则不加载任何文件。无论以何种方式启动,它都不会读取工作目录。该文件可以提供FASTMCP_SERVER_AUTH、提供程序字段以及其他服务设置。从源代码检出目录运行时,通常会找到仓库根目录中的.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 重绑定。MCP 还要求单独进行下文所述的 Origin 验证。
- 条目可以是精确值(
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标头。也可以列出代理发送的上游Host值。如果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也会被拒绝。 - 信任判断基于直接的原始套接字对端。来自其他对端的请求,或没有客户端地址的请求,会忽略
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 验证。由于非浏览器 MCP 客户端通常会省略 Origin,因此不带 Origin 的请求会被接受。不匹配的 Origin 会收到
403 Forbidden。如上所述,/health端点不受此限制。 - 条目可以是精确值(
http://localhost:3000),也可以接受任意端口(http://localhost:*)。与 Host 一样,任意端口形式仅匹配带端口的 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
Stock nginx 会将代理请求的 Host 改为上游名称,但不会创建或覆盖 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 模块名称- 默认值:None(不加载中间件)
- 设置为中间件模块名称(不含
.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/入口 TLS — MCP 服务位于 Kubernetes 入口或反向代理之后,或通过普通 HTTP 访问时,关闭CLICKHOUSE_SECURE并不会禁用数据库 TLS;它只会改变此进程连接 ClickHouse 的方式。入口 TLS 与数据库客户端设置应分别配置。- Native 协议端口 —
CLICKHOUSE_PORT必须指向 ClickHouse 的 HTTP 接口(默认端口为8123/8443)。端口9000/9440用于 Native 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
YouTube 概览
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。
