Skip to content

environmentd: add cluster/replica targeting and EXPLAIN ANALYZE to MCP developer tool#36792

Draft
sjwiesman wants to merge 1 commit into
MaterializeInc:mainfrom
sjwiesman:worktree-mcp-cluster-replica
Draft

environmentd: add cluster/replica targeting and EXPLAIN ANALYZE to MCP developer tool#36792
sjwiesman wants to merge 1 commit into
MaterializeInc:mainfrom
sjwiesman:worktree-mcp-cluster-replica

Conversation

@sjwiesman
Copy link
Copy Markdown
Contributor

Motivation

The Developer MCP endpoint's query_system_catalog tool always ran on the session default cluster and routed catalog queries to mz_catalog_server. That left two troubleshooting capabilities unreachable:

  • mz_introspection.* relations are per-replica. Their results depend on the active cluster / cluster_replica session variables, and on a multi-replica cluster a replica must be targeted or the read is rejected (UntargetedLogRead).
  • EXPLAIN ANALYZE (MEMORY / CPU / HINTS, object- and cluster-scoped) is planned as a SELECT against mz_introspection and runs on the active cluster/replica — but the tool's read-only allowlist rejected it outright.

This change adds optional cluster and cluster_replica parameters to the tool and enables EXPLAIN ANALYZE, so an MCP client can target a specific replica for introspection and resource-usage analysis. All changes are read-only and confined to src/environmentd/src/http/mcp.rs.

What changed

  • Added optional cluster and cluster_replica to QuerySystemCatalogParams, threaded through dispatch into the handler. When set, the handler prepends SET CLUSTER / SET CLUSTER_REPLICA (via the existing escaped_string_literal) inside the existing BEGIN READ ONLY wrapper.
  • cluster_replica provided without cluster is rejected, since SET cluster_replica targets a replica of the current cluster and the target would otherwise be ambiguous.
  • Added mz_introspection to the handler's search_path so unqualified introspection relation names resolve.
  • Extended validate_readonly_query's allowlist to permit Statement::ExplainAnalyzeObject and Statement::ExplainAnalyzeCluster. validate_system_catalog_query needs no change: the FOR <object> explainee is not a TableFactor, so it neither trips the non-system-table check nor the "must reference a system table" SELECT guard.
  • Updated the tool description and input schema to document the new parameters and EXPLAIN ANALYZE support.

Known limitation

Because the handler pins search_path to system schemas only, an EXPLAIN ANALYZE ... FOR <object> target must be fully qualified (database.schema.name); an unqualified user object name will not resolve. This is documented in the handler and noted here for reviewers — it's the tradeoff of the locked-down search_path that prevents unqualified mz_* names resolving to user objects. Open to relaxing search_path specifically for EXPLAIN ANALYZE if reviewers prefer.

Testing

Adds test_validate_readonly_query_explain_analyze and test_validate_system_catalog_query_allows_explain_analyze. Manually verified end-to-end against a local environmentd: tools/list advertises the new parameters; EXPLAIN ANALYZE CLUSTER MEMORY and EXPLAIN ANALYZE MEMORY FOR MATERIALIZED VIEW <fully-qualified> return results from the targeted replica; cluster_replica without cluster returns the validation error.

Release note

This release adds optional cluster and cluster_replica parameters to the developer MCP query_system_catalog tool and supports EXPLAIN ANALYZE, enabling per-replica introspection queries and resource-usage analysis.

🤖 Generated with Claude Code

…P developer tool

Extend the Developer MCP `query_system_catalog` tool with optional `cluster`
and `cluster_replica` parameters and allow `EXPLAIN ANALYZE`.

Introspection relations in the `mz_introspection` schema are per-replica: their
results depend on the active `cluster` / `cluster_replica` session variables, and
on a multi-replica cluster a replica must be targeted or the read is rejected.
`EXPLAIN ANALYZE` is likewise planned as a SELECT against `mz_introspection` and
runs on the active cluster/replica. Until now the tool always ran on the session
default cluster and rejected `EXPLAIN ANALYZE` outright, so neither capability was
reachable.

Changes:
- Add optional `cluster` and `cluster_replica` to `QuerySystemCatalogParams`,
  threaded through dispatch into the handler. When set, the handler prepends
  `SET CLUSTER` / `SET CLUSTER_REPLICA` inside the existing `BEGIN READ ONLY`
  wrapper. `cluster_replica` without `cluster` is rejected, since the replica
  target would otherwise be ambiguous.
- Add `mz_introspection` to the handler's `search_path` so unqualified
  introspection relation names resolve.
- Allow `Statement::ExplainAnalyzeObject` and `Statement::ExplainAnalyzeCluster`
  in `validate_readonly_query`. `validate_system_catalog_query` needs no change:
  the `FOR <object>` explainee is not a table reference, so it neither trips the
  non-system-table check nor the "must reference a system table" SELECT guard.
- Update the tool description and input schema to document the new parameters and
  EXPLAIN ANALYZE support.

Note: because the handler pins `search_path` to system schemas only, an
`EXPLAIN ANALYZE ... FOR <object>` target must be fully qualified
(`database.schema.name`); an unqualified user object name will not resolve.

Tests: adds `test_validate_readonly_query_explain_analyze` and
`test_validate_system_catalog_query_allows_explain_analyze`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sjwiesman sjwiesman closed this May 29, 2026
@sjwiesman sjwiesman reopened this May 29, 2026
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