Repository navigation
fix(mcp): add ClickHouse safety settings (max_execution_time, max_result_rows, readonly) - #2427
Conversation
Add max_execution_time, max_result_rows, and readonly to all MCP query-tool ClickHouse executions. Previously, MCP raw SQL queries could run for up to 1 hour with no row limits and no DDL/DML protection. Other MCP tools (eventDeltas, eventPatterns, trace) already set these limits — this brings the core query path into alignment.
🦋 Changeset detectedLatest commit: 02c4fc6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🔵 Tier 2 — Low RiskSmall, isolated change with no API route or data model modifications. Why this tier:
Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns. Stats
|
E2E Test Results✅ All tests passed • 197 passed • 3 skipped • 1289s
Tests ran across 4 shards in parallel. |
Greptile SummaryThis PR adds ClickHouse safety guardrails (
Confidence Score: 5/5Safe to merge — the safety settings are correctly applied to both execution paths and verified by end-to-end integration tests. The change is well-scoped: a single constant governs both code paths, processClickhouseSettings confirms the external settings take precedence over defaults, and the new propagation tests cover the full MCP round-trip. The only nit is max_result_rows being typed as a string literal rather than a number, which has no runtime impact. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[MCP Tool Call\nclickstack_sql / clickstack_timeseries / etc.] --> B[runConfigTile]
B --> C{Builder or Raw SQL?}
C -- Builder --> D[new ClickhouseClient\nrequestTimeout: 32s]
C -- Raw SQL --> E[new ClickhouseClient\nrequestTimeout: 32s]
D --> F[queryChartConfig\nopts: clickhouse_settings]
E --> G[queryChartConfig\nopts: clickhouse_settings]
F --> H[MCP_CLICKHOUSE_SETTINGS\nmax_execution_time: 30\nmax_result_rows: 100000\nreadonly: 1]
G --> H
H --> I[processClickhouseSettings\nmerge with defaults]
I --> J[ClickHouse HTTP query]
J -- success --> K[formatQueryResult]
J -- error --> L[clickHouseErrorResult]
L --> M{errorHint match?}
M -- DateTime64 / AS syntax\nV8 string / RESULT_IS_TOO_LARGE --> N[Append actionable HINT]
M -- no match --> O[raw error message]
Reviews (2): Last reviewed commit: "fix(mcp): add RESULT_IS_TOO_LARGE errorH..." | Re-trigger Greptile |
…tests - Add errorHint for RESULT_IS_TOO_LARGE / TOO_MANY_ROWS_OR_BYTES so agents get actionable guidance when hitting the 100k row limit. - Add integration tests that use getSetting() to verify max_execution_time, max_result_rows, and readonly are propagated through the full MCP tool path to ClickHouse.
|
Addressed both Greptile findings: Issue 1 ( Issue 2 (Missing |
Summary
MCP query tools (
clickstack_sql,clickstack_timeseries,clickstack_table,clickstack_search,clickstack_query_tile) now enforce ClickHouse safety limits that were previously missing. A runaway agent-supplied query could hold a connection for up to 1 hour (the defaultrequestTimeout) with no row cap and no protection against DDL/DML injection.Closes HDX-4476
What changed
A single constant governs all MCP query execution in
runConfigTile():max_execution_timemax_result_rowsreadonlyrequestTimeoutApplied to both the builder config path and the raw SQL path. The settings constant is shared so they can't drift.
Tests
Integration tests against real ClickHouse verify actual enforcement:
CREATE TABLE,INSERT, andDROP TABLEviaclickstack_sqlare rejected with a readonly error;SELECTstill workssleep(3)withmax_execution_time: 1throwsTIMEOUT_EXCEEDED