Skip to main content

ClickHouse MCP Agent

PyPI pydantic-ai-slim mcp-clickhouse

AI agent for ClickHouse database analysis via MCP (Model Context Protocol).

A single MCP server (mcp-clickhouse) driven by a single agent instance. Access restriction is performed via explicit allow-lists you pass per call (allowed_tables, allowed_databases), rather than managing multiple keys or fan-out across multiple agents.

Features

  • Query ClickHouse databases using natural language with AI models
  • Structured output: analysis, confidence, sql_used
  • Easy connection management (predefined or custom)
  • Conversational context with message-history pruning/summarization
  • No CLI or external .env required — configure at runtime
  • Access restriction via per-call allow-lists (allowed_tables, allowed_databases)
  • 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=True
  • Typed exception hierarchy for reliable error handling
  • Optional structlog integration (pip install ".[logging]")

Supported Providers

Provider Key env var Notes
Google Gemini GOOGLE_API_KEY Default
OpenAI OPENAI_API_KEY
Anthropic ANTHROPIC_API_KEY
Grok GROK_API_KEY Free tier, high rate limits
Mistral MISTRAL_API_KEY
Cohere CO_API_KEY

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.py

The 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 call

Switching 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 (free tier, high rate limits — good for testing)
config.set_ai_model("grok:llama-3.3-70b-versatile")
config.set_model_api_key("grok", "your_key")

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
analysis Natural-language result text from the model
confidence Confidence level (1–10)
sql_used List of SQL strings executed during the run
messages Full (possibly pruned/summarized) message history
new_messages Only messages created in the latest turn
last_message The last message in the conversation
usage 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, Mistral, or Cohere)

All dependencies are managed via pyproject.toml.

Roadmap

✅ Done (0.11.x)

  • MCP integration via pydantic_ai.mcp.MCPServerStdio
  • SQL generation/execution via MCP tools
  • Schema inspection (databases/tables/columns)
  • Config-driven connections (playground/local/custom)
  • Access restriction via per-call allow-lists (allowed_tables, allowed_databases)
  • Runtime provider/model selection and API key management
  • Structured outputs (ClickHouseOutput) and RunResult with sql_used
  • Message 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)
  • ruff linting, Python 3.13 support, CI hardened
  • Async batch queries via run_batch()
  • reset() for lifecycle control
  • Query result cache (enable_cache=True)
  • structlog optional dep (pip install ".[logging]")

✅ 0.12 — Stable

  • API locked — no breaking changes without a major version
  • All known bugs resolved
  • py.typed check added to CI
  • mypy agent/ added to CI matrix
  • Updated to mcp-clickhouse 0.4.0; list_databases tool now enforced by allowed_databases allow-list
  • Default model updated to google:gemini-3.1-flash-lite

🔭 Post-1.0 — Future

  • Database-agnostic abstraction (Elasticsearch, MongoDB, Postgres)
  • FastAPI standalone deployment option

Contributing

Open an issue or pull request for features or fixes.

Metadata

Release files for clickhouse-mcp-agent 0.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for clickhouse-mcp-agent 0.12.0
File Size Uploaded
clickhouse_mcp_agent-0.12.0.tar.gz 20.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for clickhouse-mcp-agent 0.12.0
File Interpreter ABI Platform
clickhouse_mcp_agent-0.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.6 kB

Release files / clickhouse_mcp_agent-0.12.0.tar.gz

Download URL clickhouse_mcp_agent-0.12.0.tar.gz
Size 20.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b9d9455bd3cc97781b77685233aa2e65f4428fa1846dd29d46cfe9f0cc126099
BLAKE2b-256 checksum
How to use checksums
9cc98f5f4e10974327bf1d07e507d7e587f061c8bb8bc5b7c1d492cc780b0554
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.

Transparency log

Release files / clickhouse_mcp_agent-0.12.0-py3-none-any.whl

Download URL clickhouse_mcp_agent-0.12.0-py3-none-any.whl
Size 15.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a96297d738ebca83105cc7d06e5d6cc49f1423aa648572b3d7b8831dc5c582ec
BLAKE2b-256 checksum
How to use checksums
0611f1eb1bc15876a86980f4a67191efac0c8536328f733a3f2853dd2287fec1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page