Skip to content

chDB-only mode: add introspection tools + safety baseline (P1) - #202

Open
ShawnChen-Sirius wants to merge 1 commit into
ClickHouse:mainfrom
ShawnChen-Sirius:chdb-only-introspection-tools
Open

chDB-only mode: add introspection tools + safety baseline (P1)#202
ShawnChen-Sirius wants to merge 1 commit into
ClickHouse:mainfrom
ShawnChen-Sirius:chdb-only-introspection-tools

Conversation

@ShawnChen-Sirius

Copy link
Copy Markdown

What

Implements P1 of the chDB-in-mcp-clickhouse design: a richer chDB-only tool surface plus a chDB-session security baseline. Adds the five introspection tools alongside the existing run_chdb_select_query, in self-contained modules with no changes to the ClickHouse-server path.

New tools (registered only in chDB-only modeCLICKHOUSE_ENABLED=false, CHDB_ENABLED=true):

  • list_databases
  • list_tables
  • describe_table
  • get_sample_data
  • list_functions

Security baseline: quote_ident / quote_string helpers and result truncate() (in chdb_safety.py).

Why

Discussion and full design: Refs #201

Today mcp-clickhouse ships only a single blind run_chdb_select_query on the chDB side — no way for an agent to discover what's queryable, while the ClickHouse-server side already has list_databases / list_tables. This brings parity, using bare canonical names (collision-free since the CH-server tools aren't registered in chDB-only mode).

Scope / safety

  • Both mode is frozen: when CLICKHOUSE_ENABLED=true, nothing is registered beyond the existing 0.4.0 tools — behavior is unchanged.
  • New code is isolated in mcp_clickhouse/chdb_tools.py and mcp_clickhouse/chdb_safety.py; the ClickHouse path has no dependency on them.

Files

  • mcp_clickhouse/chdb_tools.py (new) — the five introspection tools
  • mcp_clickhouse/chdb_safety.py (new) — pure safety helpers
  • mcp_clickhouse/mcp_server.py — chDB-only registration
  • tests/test_chdb_tools.py (new), tests/test_chdb_safety.py (new)
  • README.md — document the chDB-only introspection tools

Tests

  • New + existing chDB tests: 32 passing (test_chdb_tools, test_chdb_safety, test_chdb_tool, test_optional_chdb).
  • Full suite against a live ClickHouse 26.6: 109 passing, 1 pre-existing failure (test_system_database_access, unrelated to this change — reproduces identically on main because the test assumes system.tables fits in the first page, while this ClickHouse build has 120 system tables).

This is the first of three planned phases (P1 introspection; P2 federated source catalog; P3 co-located DataFrame query).

@ShawnChen-Sirius

Copy link
Copy Markdown
Author

Hi @iskakaushik and @serprex, Could you take a look of this PR when you have a chance?

My view is that chDB is a special deployment form within the ClickHouse ecosystem, so from a user perspective it makes more sense to expose it as an option in the same MCP package.

This PR adds chDB APIs to mcp-clickhouse, while keeping the implementation decoupled through env vars, existing paths, and separate Python files instead of mixing it directly into the server logic.

It also introduces CHDB_SOURCES_CONFIG to define richer source addresses, similar in spirit to NAMED_COLLECTION.

Thanks!

@ShawnChen-Sirius
ShawnChen-Sirius force-pushed the chdb-only-introspection-tools branch 6 times, most recently from 0858e4c to e3dd3bd Compare July 2, 2026 10:20
…ts.ChDBTool

Adds a richer chDB-only tool surface (registered only when CLICKHOUSE_ENABLED=false
and CHDB_ENABLED=true), alongside the existing run_chdb_select_query:

- list_databases / list_tables / describe_table / get_sample_data / list_functions
  as bare, ClickHouse-server-parity tool names (collision-free in chDB-only mode).
- Capability layer unified on chdb.agents.ChDBTool (chdb>=4.2.0): query execution,
  identifier quoting, parameter binding, result caps, typed errors, engine
  read-only, timeout, and the file-path allowlist all come from ChDBTool — mcp
  re-implements none of it. (database, table) maps to ChDBTool's database=.
- Presentation aligned to the ClickHouse-server tools: success is bare JSON, and
  any failure is raised as ToolError (like run_query). max_result_bytes and
  allow_write are read from ChDBConfig (single source), and allow_write is passed
  to register so the shared session is not clobbered to readonly=2 in write mode.
- CHDB_FILE_ALLOWLIST is a *path* allowlist (DuckDB allowed_directories style),
  enforced via chdb.agents.safety so raw SQL and ChDBTool agree: file-like paths
  under an allowed prefix are permitted, paths outside and DSN-based external
  sources are refused. run_chdb_select_query stays on its own executor (routing
  it through ChDBTool would flip 64-bit ints to quoted strings — a visible change).

Security baseline retained on the session (SET readonly=2 unless writes allowed,
max_result_bytes, timeout). Both-engine mode unchanged. Tests: 64 chDB tests pass
against a clean install of chdb 4.2.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant