ClickHouse MCP Server Overview
mainchDB for executing queries against embedded ClickHouse engines, enabling direct querying of files, URLs, and databases without ETL processes.repository·main·Indexed 21 days ago
https://github.com/clickhouse/mcp-clickhouseA Model Context Protocol (MCP) server that enables AI agents to interact with ClickHouse clusters and chDB. It provides tools for executing SQL queries via `run_query`, listing databases with `list_databases`, and inspecting tables with `list_tables`. The server also supports `run_chdb_select_query` for querying files and URLs using the embedded chDB engine. It includes support for HTTP/SSE transports with static bearer token or OAuth/OIDC authentication, and a /health endpoint for orchestrator probes.
chDB for executing queries against embedded ClickHouse engines, enabling direct querying of files, URLs, and databases without ETL processes.To run the ClickHouse MCP server locally for development, follow these steps:
test-services directory and run docker compose up -d to start the ClickHouse cluster..env file in the repository root with your local credentials:CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouseuv to sync dependencies and activate the virtual environment:uv sync
source .venv/bin/activatefastmcp dev mcp_clickhouse/mcp_server.pyCLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_DISABLED=true python -m mcp_clickhouse.mainCLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_TOKEN="your-token" python -m mcp_clickhouse.main# Example: Running with HTTP transport and authentication disabled for local testing
CLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_DISABLED=true python -m mcp_clickhouse.mainIf you do not want to use uv, you can install the package via pip and run it using your system's Python installation.
Installation:
python3 -m pip install mcp-clickhousepython3 -m pip install 'mcp-clickhouse[chdb]'python3 -m pip install --upgrade mcp-clickhouseClaude Desktop Configuration (using module):
Use python3 -m mcp_clickhouse.main as the command and arguments.
Claude Desktop Configuration (using script):
Use the installed mcp-clickhouse script directly.
Note: Always use the absolute path to the executable (e.g., via which python3 or which mcp-clickhouse).
{
"mcpServers": {
"mcp-clickhouse": {
"command": "/absolute/path/to/python3",
"args": [
"-m",
"mcp_clickhouse.main"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>"
}
}
}
}To secure an HTTP/SSE deployment with a static token, follow these steps:
Generate a secure token:
# macOS/Linux
uuidgen
# or
openssl rand -hex 32Configure the server:
export CLICKHOUSE_MCP_AUTH_TOKEN="your-generated-token"Configure your MCP client (e.g., Claude Desktop):
Add the token to the headers section of your configuration.
Warning: Do not disable authentication when the server is exposed to any network.
{
"mcpServers": {
"mcp-clickhouse": {
"url": "http://127.0.0.1:8000",
"headers": {
"Authorization": "Bearer your-generated-token"
}
}
}
}To use the ClickHouse MCP server with Claude Desktop, add the following configuration to your claude_desktop_config.json. This example uses the stdio transport and provides the necessary environment variables for connecting to a ClickHouse instance.
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.10",
"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"
}
}
}
}For production environments, delegate authentication to FastMCP providers. Set FASTMCP_SERVER_AUTH to the full class path of the provider and provide the necessary provider-specific environment variables. Leave CLICKHOUSE_MCP_AUTH_TOKEN unset.
Example: Azure Entra Configuration
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>"To use the ClickHouse MCP server with Claude Desktop, you must add it to your claude_desktop_config.json file.
File Locations:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%/Claude/claude_desktop_config.jsonSetup Steps:
mcp-clickhouse server entry under mcpServers.uv as the command (ensure you use the absolute path to the uv executable, which you can find via which uv on macOS/Linux).{
"mcpServers": {
"mcp-clickhouse": {
"command": "/absolute/path/to/uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.10",
"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_SEND_RECEIVE_TIMEOUT": "30"
}
}
}
}You can intercept and process MCP protocol messages (tool calls, resource reads, etc.) by implementing custom middleware using the fastmcp system.
Steps to implement:
Middleware.on_call_tool, on_message).setup_middleware(mcp) function in that module to register your class.MCP_MIDDLEWARE_MODULE environment variable in your Claude Desktop config to the name of your module (without .py).Available Hooks:
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)# 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())These variables control the MCP protocol layer, including how clients connect to the server and how they are authenticated. They are independent of the ClickHouse database connection settings.
CLICKHOUSE_MCP_SERVER_TRANSPORT: The transport method. Options: "stdio" (default, typical for Claude Desktop), "http", or "sse".CLICKHOUSE_MCP_BIND_HOST: Host to bind the server to when using http or sse. Default: "127.0.0.1".CLICKHOUSE_MCP_BIND_PORT: Port to bind the server to when using http or sse. Default: "8000".When using http or sse transport, one of the following is required:
CLICKHOUSE_MCP_AUTH_TOKEN: A static bearer token. Clients must send Authorization: Bearer <token>.FASTMCP_SERVER_AUTH: The full class path of a FastMCP auth provider (e.g., fastmcp.server.auth.providers.azure.AzureProvider).CLICKHOUSE_MCP_AUTH_DISABLED: Set to "true" to disable authentication (use for local development only).CLICKHOUSE_MCP_QUERY_TIMEOUT: Timeout in seconds for query tools (Default: "30").These variables control how the MCP server connects to your ClickHouse cluster via the HTTP interface. They are used by tools like run_query, list_databases, and list_tables.
CLICKHOUSE_HOST: The hostname of your ClickHouse server.CLICKHOUSE_USER: Username for ClickHouse authentication.CLICKHOUSE_PASSWORD: Password for ClickHouse authentication.CLICKHOUSE_PORT: The HTTP interface port.8443 if CLICKHOUSE_SECURE=true, 8123 if CLICKHOUSE_SECURE=false.8123), not the native TCP port (e.g., 9000).CLICKHOUSE_SECURE: Enables HTTPS for the connection to ClickHouse. Default is "true". Set to "false" for plain HTTP (common in local Docker setups).CLICKHOUSE_VERIFY: Enables/disables SSL certificate verification. Default is "true".CLICKHOUSE_DATABASE: The default database to use. If not set, the server uses the ClickHouse default.CLICKHOUSE_ROLE: The ClickHouse role to use for authentication.CLICKHOUSE_SERVER_HOST_NAME: Used for SNI override and certificate validation when connecting through proxies.CLICKHOUSE_PROXY_PATH: URL path prefix if ClickHouse is behind a reverse proxy (e.g., /clickhouse).CLICKHOUSE_CONNECT_TIMEOUT: Connection timeout in seconds (Default: "30").CLICKHOUSE_SEND_RECEIVE_TIMEOUT: Send/receive timeout for long-running queries (Default: "300").When using HTTP or SSE transport, authentication is required by default. The stdio transport (default) does not require authentication. You must choose one of the following three modes:
CLICKHOUSE_MCP_AUTH_TOKEN for simple deployments.FASTMCP_SERVER_AUTH=<provider-class-path> for production identity providers (Azure, Google, etc.).CLICKHOUSE_MCP_AUTH_DISABLED=true for local development only.By default, the MCP server is read-only to prevent accidental data mutation. To enable writing or destructive operations, you must explicitly opt-in using environment variables:
INSERT, UPDATE, or CREATE statements, set CLICKHOUSE_ALLOW_WRITE_ACCESS to true.DROP or TRUNCATE statements, you must set both CLICKHOUSE_ALLOW_WRITE_ACCESS=true and CLICKHOUSE_ALLOW_DROP=true."env": {
"CLICKHOUSE_ALLOW_WRITE_ACCESS": "true",
"CLICKHOUSE_ALLOW_DROP": "true"
}