Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ All notable changes to this project will be documented in this file.
## Unreleased

### Added
- Client connection reuse across tool calls via a config-keyed cache, eliminating per-call connection overhead. ([#152](https://github.com/ClickHouse/mcp-clickhouse/pull/152))
- Server-side query cancellation: timed-out queries now issue `KILL QUERY` on the ClickHouse server instead of leaving zombie workers consuming threads and server resources. ([#152](https://github.com/ClickHouse/mcp-clickhouse/pull/152))
- `CLICKHOUSE_MCP_MAX_WORKERS` environment variable to configure the query worker thread pool size (default: `10`). ([#152](https://github.com/ClickHouse/mcp-clickhouse/pull/152))
- Support for FastMCP OAuth/OIDC auth providers on HTTP/SSE transports via the `FASTMCP_SERVER_AUTH` environment variable (e.g. Azure Entra, Google, GitHub, WorkOS). Static token, FastMCP OAuth, and disabled mode are now mutually exclusive; configure exactly one. ([#171](https://github.com/ClickHouse/mcp-clickhouse/issues/171))

### Changed
- `CLICKHOUSE_SEND_RECEIVE_TIMEOUT` is now auto-capped to `CLICKHOUSE_MCP_QUERY_TIMEOUT + 5` unless explicitly set, so HTTP reads unblock shortly after an MCP timeout fires. ([#152](https://github.com/ClickHouse/mcp-clickhouse/pull/152))
- `/health` endpoint is now unauthenticated across all auth modes (previously gated only under static-token mode, which was asymmetric and incompatible with redirect-based OAuth providers). Response bodies trimmed to `OK` / generic error strings to avoid leaking ClickHouse version information or connection exception details; underlying errors are logged server-side.

### Fixed
- Session config overrides from PR #115 are now resolved on the request thread where the FastMCP context is available, so overrides are correctly applied to queries dispatched to the worker pool. ([#152](https://github.com/ClickHouse/mcp-clickhouse/pull/152))
- Tool responses now return JSON-encoded strings, avoiding MCP protocol validation errors on successful queries. ([#154](https://github.com/ClickHouse/mcp-clickhouse/pull/154))
- Long-running queries no longer block other tool calls. The MCP-facing `run_query` and `run_chdb_select_query` tools now await their thread-pool futures asynchronously, so concurrent tool calls are served while a slow query is in flight. ([#128](https://github.com/ClickHouse/mcp-clickhouse/issues/128))

Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,9 @@ The following environment variables are used to configure the ClickHouse and chD
* `CLICKHOUSE_CONNECT_TIMEOUT`: Connection timeout in seconds
* Default: `"30"`
* Increase this value if you experience connection timeouts
* `CLICKHOUSE_SEND_RECEIVE_TIMEOUT`: Send/receive timeout in seconds
* Default: `"300"`
* Increase this value for long-running queries
* `CLICKHOUSE_SEND_RECEIVE_TIMEOUT`: Send/receive timeout in seconds for the underlying HTTP connection
* Default: automatically set to `CLICKHOUSE_MCP_QUERY_TIMEOUT + 5` so worker threads unblock shortly after a query timeout
* If explicitly set, the value is used as-is (e.g. `"300"` for long-running queries)
* `CLICKHOUSE_DATABASE`: Default database to use
* Default: None (uses server default)
* Set this to automatically connect to a specific database
Expand All @@ -532,9 +532,14 @@ The following environment variables are used to configure the ClickHouse and chD
* `CLICKHOUSE_MCP_BIND_PORT`: Port to bind the MCP server to when using HTTP or SSE transport
* Default: `"8000"`
* Only used when transport is `"http"` or `"sse"`
* `CLICKHOUSE_MCP_QUERY_TIMEOUT`: Timeout in seconds for SELECT tools
* `CLICKHOUSE_MCP_QUERY_TIMEOUT`: Timeout in seconds for query tool calls
* Default: `"30"`
* Increase this if you see `Query timed out after ...` errors for heavy queries
* When a query times out, the server issues a `KILL QUERY` on the ClickHouse server to cancel it
* Unless `CLICKHOUSE_SEND_RECEIVE_TIMEOUT` is explicitly set, the HTTP read timeout is automatically aligned to this value plus a small buffer, so worker threads unblock shortly after a timeout
* `CLICKHOUSE_MCP_MAX_WORKERS`: Maximum number of concurrent query worker threads
* Default: `"10"`
* Increase if your workload requires many concurrent tool calls
* `CLICKHOUSE_MCP_AUTH_TOKEN`: Static bearer token for HTTP/SSE transports
* Default: None
* One of `CLICKHOUSE_MCP_AUTH_TOKEN`, `FASTMCP_SERVER_AUTH`, or `CLICKHOUSE_MCP_AUTH_DISABLED=true` is **required** for HTTP/SSE transports
Expand Down
9 changes: 9 additions & 0 deletions mcp_clickhouse/mcp_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ class MCPServerConfig:
CLICKHOUSE_MCP_BIND_HOST: Bind host for HTTP/SSE (default: 127.0.0.1)
CLICKHOUSE_MCP_BIND_PORT: Bind port for HTTP/SSE (default: 8000)
CLICKHOUSE_MCP_QUERY_TIMEOUT: SELECT tool timeout in seconds (default: 30)
CLICKHOUSE_MCP_MAX_WORKERS: Maximum thread pool workers for query execution (default: 10)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fun fact: the JS client proxies all the CLICKHOUSE_* parameters verbatim to CH. Seems to have worked fine without the need to explicitly enumerate then. It does not forward env vars though.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for the context.

CLICKHOUSE_MCP_AUTH_TOKEN: Static bearer token for HTTP/SSE transports.
One authentication mode must be configured for HTTP/SSE; the other two
options are FASTMCP_SERVER_AUTH (FastMCP OAuth/OIDC providers) and
Expand Down Expand Up @@ -328,6 +329,14 @@ def bind_port(self) -> int:
def query_timeout(self) -> int:
return int(os.getenv("CLICKHOUSE_MCP_QUERY_TIMEOUT", "30"))

@property
def max_workers(self) -> int:
"""Maximum thread pool workers for query execution.

Default: 10
"""
return int(os.getenv("CLICKHOUSE_MCP_MAX_WORKERS", "10"))

@property
def auth_token(self) -> Optional[str]:
"""Get the authentication token for HTTP/SSE transports."""
Expand Down
Loading
Loading