mcpField
C
ClickHouse MCP Server

ClickHouse MCP Server

本地服务
clickhouse.com数据库8982 天前更新

关于 ClickHouse MCP Server

ClickHouse MCP Server 是面向 ClickHouse 数据库的 MCP 服务,让 AI 助手可以查询和浏览集群中的数据库与表。默认以只读模式运行,并支持 HTTP/SSE 传输下的身份验证。

主要功能

  1. 01run_query 工具执行 SQL 查询
  2. 02支持 {name:Type} 形式的参数绑定
  3. 03list_databases 与 list_tables 浏览集群结构
  4. 04list_tables 支持分页与 LIKE 过滤
  5. 05DESCRIBE 与 EXPLAIN ESTIMATE 预先检查查询
  6. 06/health 健康检查端点

适用场景

  1. 01让 AI 助手直接查询 ClickHouse 数据进行分析
  2. 02在执行大型查询前用 EXPLAIN ESTIMATE 评估读取量
  3. 03通过 chDB 查询文件或 URL 中的数据而无需 ETL

MCP 相关

该项目是 MCP 服务,向 MCP 客户端暴露 run_query、list_databases、list_tables 和 run_chdb_select_query 等工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"clickhouse": {
"command": "uvx",
"args": [
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<CLICKHOUSE_HOST>",
"CLICKHOUSE_USER": "<CLICKHOUSE_USER>",
"CLICKHOUSE_PASSWORD": "<CLICKHOUSE_PASSWORD>",
"CLICKHOUSE_PORT": "<CLICKHOUSE_PORT>",
"CLICKHOUSE_SECURE": "<CLICKHOUSE_SECURE>",
"CLICKHOUSE_VERIFY": "<CLICKHOUSE_VERIFY>",
"CLICKHOUSE_CA_CERT": "<CLICKHOUSE_CA_CERT>",
"CLICKHOUSE_CLIENT_CERT": "<CLICKHOUSE_CLIENT_CERT>",
"CLICKHOUSE_CLIENT_CERT_KEY": "<CLICKHOUSE_CLIENT_CERT_KEY>",
"CLICKHOUSE_TLS_MODE": "<CLICKHOUSE_TLS_MODE>",
"CLICKHOUSE_DATABASE": "<CLICKHOUSE_DATABASE>",
"CLICKHOUSE_ROLE": "<CLICKHOUSE_ROLE>",
"CLICKHOUSE_ALLOW_WRITE_ACCESS": "<CLICKHOUSE_ALLOW_WRITE_ACCESS>",
"CLICKHOUSE_ALLOW_DROP": "<CLICKHOUSE_ALLOW_DROP>",
"CLICKHOUSE_MCP_QUERY_TIMEOUT": "<CLICKHOUSE_MCP_QUERY_TIMEOUT>",
"CLICKHOUSE_MCP_MAX_WORKERS": "<CLICKHOUSE_MCP_MAX_WORKERS>"
}
}
}
}
启动命令uvx mcp-clickhouse
需要配置的环境变量
CLICKHOUSE_HOSTHostname of the ClickHouse server
CLICKHOUSE_USERUsername for ClickHouse authentication
CLICKHOUSE_PASSWORD密钥Password for ClickHouse authentication. Required unless a client certificate uses the default or mutual TLS mode
CLICKHOUSE_PORTClickHouse HTTP(S) port. Defaults to 8443 when CLICKHOUSE_SECURE=true, 8123 otherwise
CLICKHOUSE_SECUREUse HTTPS to connect to ClickHouse
CLICKHOUSE_VERIFYVerify SSL certificates
CLICKHOUSE_CA_CERTPath to a PEM CA bundle for ClickHouse server certificate verification
CLICKHOUSE_CLIENT_CERTPath to a PEM client certificate for the ClickHouse HTTPS connection
CLICKHOUSE_CLIENT_CERT_KEY密钥Path to the PEM private key for CLICKHOUSE_CLIENT_CERT
CLICKHOUSE_TLS_MODEClient certificate mode: mutual, proxy, or strict
CLICKHOUSE_DATABASEDefault database to use
CLICKHOUSE_ROLEClickHouse role to activate for the session
CLICKHOUSE_ALLOW_WRITE_ACCESSAllow write operations (DDL and DML). Queries run read-only by default
CLICKHOUSE_ALLOW_DROPAllow destructive operations (DROP, TRUNCATE, DELETE, UPDATE, REPLACE, CLEAR, and DETACH PERMANENTLY) when write access is also enabled
CLICKHOUSE_MCP_QUERY_TIMEOUTQuery tool timeout in seconds
CLICKHOUSE_MCP_MAX_WORKERSMaximum query worker thread pool size

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimcp-clickhouse0.7.0
ocighcr.io/clickhouse/mcp-clickhouse:0.7.0

工具

3

收录的工具列表 · 更新于 3 周前

此工具无需参数。

详细介绍

ClickHouse MCP 服务

PyPI - Version

适用于 ClickHouse 的 MCP 服务。

mcp-clickhouse MCP server

该服务实现了 MCP 2026-07-28,并支持从 2024-11-05 到 2025-11-25 的旧版初始化握手。现代客户端使用无会话请求和 server/discover。现有客户端可以继续协商旧版协议。

说明

不包含 MCP-Protocol-Version 的 HTTP 请求会通过旧版处理路径进行路由,以便 2025-06-18 之前的客户端继续连接。MCP 2026-07-28 允许支持这些客户端的服务采用此行为。现代客户端应在每个 POST 请求中发送该标头。

功能

ClickHouse 工具

ClickHouse 工具的响应是经过 JSON 编码的字符串。为确保 JavaScript 客户端中的值精确无误,超出 [-9007199254740991, 9007199254740991] 范围的整数会以十进制字符串形式返回。此规则适用于查询行和整数型表元数据。安全范围内的整数和布尔值仍保留其 JSON 类型。

  • run_query

    • 在 ClickHouse 集群上执行 SQL 查询。
    • 输入:query(字符串):要执行的 SQL 查询。
    • 可选输入:params(对象):用于 ClickHouse {name:Type} 占位符的命名值。请参阅查询参数。
    • 查询默认以只读模式运行(CLICKHOUSE_ALLOW_WRITE_ACCESS=false),但可按需显式启用写入。
    • DESCRIBE (<query>) 和 EXPLAIN ESTIMATE <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 传输,如果未配置上述任何一种模式,启动将失败。

设置身份验证
  1. 生成安全令牌(可以是任意随机字符串):

    # Using uuidgen (macOS/Linux)
    uuidgen
    
    # Using openssl
    openssl rand -hex 32
    
  2. 使用该令牌配置服务:

    export CLICKHOUSE_MCP_AUTH_TOKEN="your-generated-token"
    
  3. 配置 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,或向 /mcp POST 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.Auth0ProviderFASTMCP_SERVER_AUTH_AUTH0_
fastmcp.server.auth.providers.aws.AWSCognitoProviderFASTMCP_SERVER_AUTH_AWS_COGNITO_
fastmcp.server.auth.providers.azure.AzureProviderFASTMCP_SERVER_AUTH_AZURE_
fastmcp.server.auth.providers.descope.DescopeProviderFASTMCP_SERVER_AUTH_DESCOPEPROVIDER_
fastmcp.server.auth.providers.discord.DiscordProviderFASTMCP_SERVER_AUTH_DISCORD_
fastmcp.server.auth.providers.github.GitHubProviderFASTMCP_SERVER_AUTH_GITHUB_
fastmcp.server.auth.providers.google.GoogleProviderFASTMCP_SERVER_AUTH_GOOGLE_
fastmcp.server.auth.providers.introspection.IntrospectionTokenVerifierFASTMCP_SERVER_AUTH_INTROSPECTION_
fastmcp.server.auth.providers.jwt.JWTVerifierFASTMCP_SERVER_AUTH_JWT_
fastmcp.server.auth.providers.oci.OCIProviderFASTMCP_SERVER_AUTH_OCI_
fastmcp.server.auth.providers.scalekit.ScalekitProviderFASTMCP_SERVER_AUTH_SCALEKITPROVIDER_
fastmcp.server.auth.providers.supabase.SupabaseProviderFASTMCP_SERVER_AUTH_SUPABASE_
fastmcp.server.auth.providers.workos.WorkOSProviderFASTMCP_SERVER_AUTH_WORKOS_
fastmcp.server.auth.providers.workos.AuthKitProviderFASTMCP_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。

  1. 打开位于以下路径的 Claude Desktop 配置文件:

    • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows:%APPDATA%/Claude/claude_desktop_config.json
  2. 添加以下内容:

{
  "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"
      }
    }
  }
}
  1. 找到 uv 命令条目,并将其替换为 uv 可执行文件的绝对路径。这样可以确保启动服务时使用正确版本的 uv。在 Mac 上,可通过 which uv 查找此路径。

  2. 重启 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 安装软件包并直接运行:

  1. 使用 pip 安装软件包:

    python3 -m pip install mcp-clickhouse
    

    如需同时安装 chDB 支持:

    python3 -m pip install 'mcp-clickhouse[chdb]'
    

    如需升级到最新版本:

    python3 -m pip install --upgrade mcp-clickhouse
    
  2. 更新 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 协议消息(工具调用、资源读取、提示词等)。

使用方法
  1. 创建一个 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())
  1. 将 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"
      }
    }
  }
}
  1. 确保中间件模块位于 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 用户、角色和授权规则强制执行租户隔离。

开发

  1. 在 test-services 目录中运行 docker compose up -d,启动 ClickHouse 集群。

  2. 将以下变量添加到仓库根目录的 .env 文件中。

注意:此处使用 default 用户仅用于本地开发。

CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
  1. 运行 uv sync 安装依赖。按照此处的说明安装 uv。然后运行 source .venv/bin/activate。

  2. 如需使用 MCP Inspector 进行便捷测试,请运行 uv run fastmcp dev inspector mcp_clickhouse/mcp_server.py:mcp 启动 MCP 服务。

  3. 若要使用 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.pydotenv 加载、身份验证、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_FILEMCP 传输、身份验证及查询工具执行限制
中间件 / chDBMCP_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 使用
    • 如果服务响应 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 概览

YouTube

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。