ClickHouse MCP Agent
With this ClickHouse MCP server, you can inspect ClickHouse schema and run SQL queries, read-only by default.
List available databases.
List tables in a database with schema, comments, row/column counts, LIKE/NOT LIKE filters, pagination, and optional detailed column metadata.
Execute SQL queries against ClickHouse; read-only by default, with writes/destructive operations only if explicitly enabled via server environment flags.
Support AI-agent database analysis by exposing these MCP tools to the ClickHouse MCP Agent.
Provides AI-driven analysis of ClickHouse databases via natural language queries, with structured outputs and per-call access restrictions.
Leverages Google Gemini models to generate insights and SQL from natural language queries against ClickHouse.
Leverages OpenAI models (e.g., GPT-4) to generate insights and SQL from natural language queries against ClickHouse.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ClickHouse MCP Agent how many orders were placed last week?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ClickHouse MCP Agent
AI agent for ClickHouse database analysis via MCP (Model Context Protocol).
A single MCP server (mcp-clickhouse) driven by a single agent instance. You can scope what the agent discovers per call with allow-lists (allowed_tables, allowed_databases). See Security for what they do and do not restrict.
Features
Query ClickHouse databases using natural language with AI models
Structured output:
analysis,confidence,sql_usedEasy connection management (predefined or custom)
Conversational context with message-history pruning/summarization
No CLI or external .env required — configure at runtime
Per-call discovery scoping via allow-lists (
allowed_tables,allowed_databases)Read-only queries by default (enforced by
mcp-clickhouse)Streamable results via
run_stream()Persistent MCP server mode via
async with ClickHouseAgent()Parallel queries via
run_batch()Lifecycle reset via
reset()Query result cache via
enable_cache=TrueTyped exception hierarchy for reliable error handling
Optional
structlogintegration (pip install ".[logging]")
Supported Providers
Provider | Key env var | Notes |
Google Gemini |
| Default |
OpenAI |
| |
Anthropic |
| |
Grok (xAI) |
| Model prefix |
Groq |
| Fast open models (e.g. |
Mistral |
| |
Cohere |
|
Related MCP server: ClickHouse MCP Server
Local Development (Docker)
The fastest way to get started — no cloud ClickHouse account needed:
# Start ClickHouse with seeded demo data (orders + products)
docker compose up -d
# Install the package with dev dependencies
pip install -e ".[dev]"
# Run the examples (set your Google API key first)
GOOGLE_API_KEY=... python examples/example_minimal.py
GOOGLE_API_KEY=... python examples/example_stream.py
GOOGLE_API_KEY=... python examples/example_0_11.py
GOOGLE_API_KEY=... python examples/example_integration.pyThe docker/init.sql file seeds demo.orders (25 orders, May 2026) and demo.products (10 products across Electronics, Sports, Home, Books) automatically on first start.
Quickstart
import asyncio
from agent.clickhouse_agent import ClickHouseAgent
from agent.config import config
config.set_ai_model("openai:gpt-4o-mini")
config.set_model_api_key("openai", "your_api_key_here")
config.set_clickhouse(host="localhost", port="8123", user="default", password="", secure="false")
async def main():
agent = ClickHouseAgent()
result = await agent.run(
allowed_tables=["orders", "products"],
allowed_databases=["demo"],
query="give me some insights on the recent data",
)
print("Analysis:", result.analysis)
print("Confidence:", result.confidence)
print("SQL used:", result.sql_used)
asyncio.run(main())Persistent server (multiple queries)
Use the context manager to keep the MCP subprocess alive across calls — avoids subprocess startup overhead on every query:
async def main():
async with ClickHouseAgent() as agent:
r1 = await agent.run(query="how many orders were placed last week?")
r2 = await agent.run(query="which products are selling fastest?", message_history=r1.messages)Parallel queries
async with ClickHouseAgent() as agent:
results = await agent.run_batch(
["how many orders?", "total revenue?", "top 5 products?"],
allowed_databases=["demo"],
)
for r in results:
print(r.analysis)Query result cache
agent = ClickHouseAgent(enable_cache=True)
result = await agent.run(query="how many orders?", allowed_databases=["demo"])
# identical call returns instantly from cache (stateless queries only)Lifecycle reset
agent = ClickHouseAgent()
await agent.run(query="...")
await agent.reset() # tear down MCP subprocess
await agent.run(query="...") # re-initializes on next callSwitching providers
All providers use the same interface — just swap the model string and key:
# Anthropic Claude 4
config.set_ai_model("anthropic:claude-sonnet-4-6")
config.set_model_api_key("anthropic", "your_key")
# Google Gemini
config.set_ai_model("google:gemini-3.1-flash-lite")
config.set_model_api_key("google", "your_key")
# Grok (xAI)
config.set_ai_model("xai:grok-4")
config.set_model_api_key("xai", "your_key")
# Groq (fast open models, free tier — good for testing)
config.set_ai_model("groq:llama-3.3-70b-versatile")
config.set_model_api_key("groq", "your_key")Security
Queries are read-only. mcp-clickhouse runs every query with ClickHouse's readonly setting unless CLICKHOUSE_ALLOW_WRITE_ACCESS=true is set for the server, so the agent cannot modify data.
Allow-lists scope discovery; they are not an access control. allowed_databases and allowed_tables filter what the list_databases and list_tables tools return, which keeps the model focused on the right tables. They do not inspect the SQL passed to run_query: a model that writes SELECT * FROM other_db.other_table directly can still read it.
To restrict what can be read, use ClickHouse permissions. Connect with a ClickHouse user that only has SELECT grants on the data the agent may see:
CREATE USER agent_reader IDENTIFIED BY '...';
GRANT SELECT ON demo.orders TO agent_reader;
GRANT SELECT ON demo.products TO agent_reader;ClickHouse then rejects any query outside those grants, whatever SQL the model generates.
Message History & Summarization
Pass message_history between calls for multi-turn conversations. When token usage exceeds summarize_config.token_limit, older messages are automatically summarized into a compact form by a separate summarizer agent.
summarize_config.set_token_limit(10000)
summarize_config.set_ai_model("google:gemini-3.1-flash-lite")Output
Each call to ClickHouseAgent.run() returns a RunResult:
Field | Description |
| Natural-language result text from the model |
| Confidence level (1–10) |
| List of SQL strings executed during the run |
| Full (possibly pruned/summarized) message history |
| Only messages created in the latest turn |
| The last message in the conversation |
| Token/usage statistics for the run |
Error Handling
All errors raise from a typed hierarchy so you can catch at the right level:
from agent.exceptions import ClickHouseMCPError, MCPConnectionError, AgentExecutionError
try:
result = await agent.run(query="...")
except MCPConnectionError:
# MCP subprocess failed to start or connection dropped
...
except AgentExecutionError:
# Agent logic failed during the run
...
except ClickHouseMCPError:
# Any library error
...Requirements
Python 3.10+
An AI provider API key (Google, OpenAI, Anthropic, Grok, Groq, Mistral, or Cohere)
All dependencies are managed via pyproject.toml.
Roadmap
✅ Done (0.11.x)
MCP integration via
pydantic_ai.mcp.MCPServerStdioSQL generation/execution via MCP tools
Schema inspection (databases/tables/columns)
Config-driven connections (playground/local/custom)
Discovery scoping via per-call allow-lists (
allowed_tables,allowed_databases)Runtime provider/model selection and API key management
Structured outputs (
ClickHouseOutput) andRunResultwithsql_usedMessage history pruning/summarization
Streaming results via
run_stream()Persistent MCP server via
async with ClickHouseAgent()Typed exception hierarchy
Local development via Docker (
docker compose up -d)rufflinting, Python 3.13 support, CI hardenedAsync batch queries via
run_batch()reset()for lifecycle controlQuery result cache (
enable_cache=True)structlogoptional dep (pip install ".[logging]")
✅ 0.12 — Stable
API locked — no breaking changes without a major version
All known bugs resolved
py.typedcheck added to CImypy agent/added to CI matrixUpdated to
mcp-clickhouse0.4.0;list_databasestool now enforced byallowed_databasesallow-listDefault model updated to
google:gemini-3.1-flash-lite
✅ 0.12.1 — Fixes
Allow-list filtering now works against real
mcp-clickhouseresponses (previously bypassed)Contract tests against the real
mcp-clickhouseserver, and live tests against ClickHouse in CIGrok (xAI) and Groq provider setup corrected
🚧 Next
Migrate to pydantic-ai 2.x (
MCPToolset) andmcp-clickhouse0.7roleand query timeout options (ClickHouse-enforced access control)
🔭 Post-1.0 — Future
FastAPI standalone deployment option
Contributing
Open an issue or pull request for features or fixes.
Available Tools
3 toolslist_databasesA
List available ClickHouse databases
Inputs: no named parameters. Returns: Generic wrapper for non-object return types.
list_tablesA
List available ClickHouse tables in a database, including schema, comment, row count, and column count.
Args: database: The database to list tables from like: Optional LIKE pattern to filter table names not_like: Optional NOT LIKE pattern to exclude table names page_token: Token for pagination, obtained from a previous call page_size: Number of tables to return per page (default: 50) include_detailed_columns: Whether to include detailed column metadata (default: True). When False, the columns array will be empty but create_table_query still contains all column information. This reduces payload size for large schemas.
Returns: A JSON-encoded string of an object containing: - tables: List of table information (as dictionaries) - next_page_token: Token for the next page, or None if no more pages - total_tables: Total number of tables matching the filters
Inputs: database (required), like, not_like, page_size, +2 more. Returns: Generic wrapper for non-object return types.
run_queryA
Execute SQL queries in ClickHouse. Queries run in read-only mode by default. Set CLICKHOUSE_ALLOW_WRITE_ACCESS=true to allow DDL and DML operations. Set CLICKHOUSE_ALLOW_DROP=true to additionally allow destructive operations (DROP, TRUNCATE).
Inputs: query (required). Returns: Generic wrapper for non-object return types.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
Each tool has a clear, distinct purpose: listing databases, listing tables with detailed metadata, and running arbitrary SQL queries. There is no overlap or ambiguity.
All tools follow a consistent verb_noun pattern (list_databases, list_tables, run_query), making the naming predictable and easy to understand.
With only 3 tools, the server feels minimal. While it covers basic discovery and query execution, a typical database agent would benefit from additional tools for schema management or data manipulation, even if read-only by default.
The tool set covers essential operations: database listing, table listing with schema, and arbitrary SQL execution (which can include DDL/DML with flags). Minor gaps exist, such as no dedicated tool for viewing query results metadata, but the overall coverage is good for a query-focused agent.
Maintenance
Related MCP Connectors
Governed access to production AI-agent traces in an existing ClickHouse store.
Query Postgres, MySQL, SQL Server, Oracle, BigQuery, ClickHouse and Redshift from your AI client.
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to query and manage ClickHouse databases, supporting SELECT queries, DDL/DML statements, and metadata listing.54 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables executing SQL queries, listing databases, and listing tables on a ClickHouse cluster through natural language.Apache 2.0

Bollard MCPofficial
AlicenseAqualityDmaintenanceEnables safe, AI-driven database interactions with schema discovery, intent validation, and session memory, supporting multiple databases.1424 PyPI2AGPL 3.0- AlicenseNot gradedqualityDmaintenanceEnables natural language querying of SQL databases using AI, supporting multiple database types and automatic schema discovery.1MIT