Skip to main content
Glama
AranNomante

ClickHouse MCP Agent

by AranNomante

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

Related MCP server: clickhouse

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

  • FastAPI standalone deployment option

Contributing

Open an issue or pull request for features or fixes.

Available Tools

3 tools
list_databasesA

List available ClickHouse databases

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description should disclose behavioral traits such as whether the listing includes all databases or only those with specific permissions, but it only states the basic action. There is no mention of performance, side effects, or access requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, consisting of one short phrase with no redundant information. Every word serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters and a simple action, the description provides the essential information. It does not mention the output schema, but that is covered by the output schema itself. It is sufficiently complete for a straightforward listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so per the baseline the description is adequate. It correctly indicates no parameters are needed for this operation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb ('List') and specific resource ('available ClickHouse databases'), making the tool's purpose immediately understandable. It distinguishes from siblings like list_tables (which list tables) and run_query (which executes queries).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus its siblings or in what context. The description does not mention prerequisites, alternatives, or when-not-to-use scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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

ParametersJSON Schema
NameRequiredDescriptionDefault
likeNo
databaseYes
not_likeNo
page_sizeNo
page_tokenNo
include_detailed_columnsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavior: returns tables with metadata, supports pagination, filtering via LIKE/NOT LIKE, and an include_detailed_columns parameter that reduces payload. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with Args and Returns sections, and every sentence adds value. It is somewhat lengthy but justified by the number of parameters and details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (6 params, pagination, optional detailed columns) and the presence of an output schema, the description covers all aspects including return values. It is comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All six parameters are explained in detail in the Args section, including defaults and the effect of include_detailed_columns. The input schema has 0% description coverage, so the description compensates fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List available ClickHouse tables in a database, including schema, comment, row count, and column count.' It distinguishes itself from siblings list_databases and run_query by specifying tables and their metadata.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on what the tool does, but lacks explicit guidance on when to use it vs. the sibling tools (list_databases, run_query). No exclusions or alternative recommendations are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It discloses the critical behavioral trait that queries default to read-only and requires explicit flags for mutation or destruction. This covers the most important safety aspect, though it lacks details on timeouts, error handling, or response format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description consists of three concise sentences, front-loading the primary purpose in the first sentence. Every sentence adds necessary information (purpose, default mode, flags for extended use) without redundancy or wordiness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (single parameter, output schema exists), the description addresses key behavioral controls (read-only default, write/drop flags). It does not cover potential risks or limits, but the presence of an output schema reduces the need to document return values. Overall, it is sufficiently complete for typical usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% for the single 'query' parameter, so the description must compensate. It only says 'SQL queries' which is minimal and does not add constraints like syntax, length limits, or examples. The parameter name is self-explanatory, but the description adds little extra value beyond the schema definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Execute SQL queries in ClickHouse,' specifying both the action (execute) and the resource (ClickHouse SQL queries). It distinguishes from sibling tools (list_databases, list_tables) which are listing-oriented, making the tool's unique purpose evident.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use write and destructive operations via environment variables (CLICKHOUSE_ALLOW_WRITE_ACCESS and CLICKHOUSE_ALLOW_DROP), setting this apart from the default read-only mode. Although it does not explicitly contrast with siblings, the context is clear for typical query execution.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4/5.0
Disambiguation5/5

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.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern (list_databases, list_tables, run_query), making the naming predictable and easy to understand.

Tool Count3/5

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.

Completeness4/5

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

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to query and interact with CockroachDB clusters through natural language, supporting schema discovery, CRUD operations, transactions, cluster monitoring, and data export with configurable safety controls.
    30
    Apache 2.0
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to query and manage ClickHouse databases, supporting SELECT queries, DDL/DML statements, and metadata listing.
    5
    15
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables executing SQL queries, listing databases, and listing tables on a ClickHouse cluster through natural language.
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables safe, AI-driven database interactions with schema discovery, intent validation, and session memory, supporting multiple databases.
    14
    2
    AGPL 3.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AranNomante/clickhousemcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server