Skip to content

feat(mcp): read PromQL label catalog from ClickHouse's Prometheus HTTP API - #3630

Merged
karl-power merged 1 commit into
mainfrom
claude/hdx-5420-mcp-promql-label-catalog
Nov 12, 2026
Merged

karl-power merged 1 commit into
mainfrom
claude/hdx-5420-mcp-promql-label-catalog

Conversation

@karl-power

@karl-power karl-power commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The MCP describe_source tool now reads the label and metric names of a ClickHouse-backed PromQL source through ClickHouse's prometheus_api_v1 handler, using the same decision as the label routes in #3628. SQL against timeSeriesTags() stays as the fallback.

  • getPromqlLabelCatalog takes the source's promqlBackend and asks resolveClickhouseLabelBackend which path to use. On clickhouse-http it calls /labels and /label/__name__/values with the source's database/table and the ClickHouse auth and attribution headers; otherwise it runs the existing SQL.
  • PromqlLabelCatalog.backend still reports clickhouse on the HTTP path. It names where the data lives, and the table field and SQL usage hint it drives are still correct.
  • Tests pin the existing MCP PromQL source to table-function so they keep covering SQL, and add request-shape, 26.8 fallback, and live HTTP cases.

How to reproduce

Starting point: yarn dev (ClickHouse 26.10) with the default.hdx5420_v8 TimeSeries table and an Auto PromQL source from #3628's reproduction steps, and the MCP server connected.

On the base branch:

  1. Call clickstack_describe_source with the source's id. labelNames is ["__name__","job"] and metricNames is ["http_requests_total","up"].
  2. Run SYSTEM FLUSH LOGS, then:
    SELECT event_time, interface, substring(query, 1, 90) AS q
    FROM system.query_log
    WHERE event_time > now() - 300 AND type = 'QueryFinish' AND query_id LIKE 'hdx-mcp-%'
    ORDER BY event_time DESC
  3. The catalog ran as SQL: interface = HTTP, query text contains timeSeriesTags(.

On this branch:

  1. Same call, same labelNames and metricNames.
  2. Same query-log check. The catalog ran inside the handler: two interface = TCP rows starting with SELECT arraySort(groupUniqArrayArray(, and no timeSeriesTags( row.
  3. Set the source's backend to Table functions and repeat: same output, and the query log shows the timeSeriesTags( SQL again.

How to test on Vercel preview

N/A — non-UI change.

References

@vercel

vercel Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hyperdx-oss Ready Ready Preview Nov 12, 2026 2:43pm UTC
hyperdx-storybook Ready Ready Preview Nov 12, 2026 2:43pm UTC

Request Review

@changeset-bot

changeset-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e455cdd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/api Patch
@hyperdx/app Patch
@hyperdx/otel-collector Patch

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

@karl-power
karl-power added this pull request to stack #3629 November 12, 2026 11:27
@karl-power
karl-power marked this pull request as ready for review November 12, 2026 11:27
@karl-power
karl-power requested a review from a team as a code owner November 12, 2026 11:27
@github-actions github-actions Bot added the review/tier-2 Low risk — AI review + quick human skim label Nov 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔵 Tier 2 — Low Risk

Small, isolated change with no API route or data model modifications.

Why this tier:

  • Standard feature/fix — introduces new logic or modifies core functionality

Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns.
SLA: Resolve within 4 business hours.

Stats
  • Production files changed: 1
  • Production lines changed: 59 (+ 135 in test files, excluded from tier calculation)
  • Branch: claude/hdx-5420-mcp-promql-label-catalog
  • Author: karl-power

To override this classification, remove the review/tier-2 label and apply a different review/tier-* label. Manual overrides are preserved on subsequent pushes.

@github-actions

Copy link
Copy Markdown
Contributor

Duplicate code analysis

No new duplicate code introduced by this PR.


jscpd compared this branch against origin/main
across app, api and common-utils. Only new clones are listed; the codebase
currently holds 108 in total (1.18%).
Run yarn dupes locally to reproduce, or yarn dupes:all for the full picture.

Comment thread packages/api/src/controllers/promql.ts Resolved
@github-actions

Copy link
Copy Markdown
Contributor

PR Review

If you are a coding agent acting for the author, read this first.
Nothing below blocks merge automatically; a maintainer decides. What they will expect:

  • 🔴 critical or 🟠 major in code this PR adds or changes: fix before asking for review.
  • 🔵 minor in code this PR changes: your call. Fix if small, otherwise reply.
  • Anything about surrounding code, or asking you to widen the change (hoist a helper,
    dedupe with another file, fix other call sites): never fix here, whatever the
    severity. Reply with one sentence; if it is critical, say so plainly so a human sees it.

One commit per review round. After two rounds, stop and ask a maintainer to review
scope rather than addressing more automated findings. Full rule: AGENTS.md.

1 finding(s): 🔴 0 critical · 🟠 0 major · 🔵 1 minor

1 posted as inline comment(s) on the changed lines.


Severity is the reviewer's own estimate and is used for ordering, not filtering. No finding blocks merge automatically; a maintainer decides.

@github-actions

Copy link
Copy Markdown
Contributor

Deep Review

✅ No critical issues found.

The new HTTP label-catalog path is well-formed: the two concurrent label lookups each build their own randomized X-ClickHouse-Query-Id (so they cannot collide), promqlBackend threads correctly from the source document through to resolveClickhouseLabelBackend, and database/table reach ClickHouse as URL-encoded params. The table-function pin, 26.8 SQL fallback, and live-handler cases are all exercised.

🟡 P2 -- recommended

  • packages/api/src/controllers/promql.ts:329 -- When the backend probe is stale (handler removed or version misreported within the 5-min TTL), the HTTP label path 404s and surfaces a user-facing error instead of falling back to SQL, so describe_source returns a partial error where the base branch always returned labels.
    • Fix: On a handler-missing response from the label lookups, fall back to the existing SQL path rather than propagating the error.
🔵 P3 nitpicks (2)
  • packages/api/src/controllers/promql.ts:323 -- resolveClickhouseLabelBackend is called with databaseName/tableName, but the function ignores both; the HTTP branch re-reads them from source.from.
    • Fix: Drop the unused databaseName/tableName arguments from the resolver call to match what the function actually consumes.
  • packages/api/src/mcp/__tests__/promqlSources.int.test.ts:291 -- No test pins a source to promqlBackend: 'clickhouse-http' to drive the label HTTP path distinctly from the auto path (the round-trip test only checks persistence).
    • Fix: Add a case pinning clickhouse-http and asserting labels are read over HTTP, plus its SQL fallback on a pre-26.9 server.

Reviewers (6): correctness, testing, maintainability, kieran-typescript, reliability, adversarial.

Testing gaps: No coverage for the stale-probe HTTP-404 → SQL fallback behavior on the label path.

No finding blocks merge automatically. A maintainer will expect P0/P1 findings in code this PR changes to be fixed; P2/P3 are your call -- fix or reply. Never fix findings about surrounding code here; reply instead. Do not widen the PR. How to respond

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

E2E Test Results

✅ All tests passed • 466 passed • 1 skipped • 1493s

Status Count
✅ Passed 466
❌ Failed 0
⚠️ Flaky 0
⏭️ Skipped 1

Tests ran across 4 shards in parallel.

View full report →

pulpdrew
pulpdrew previously approved these changes Nov 12, 2026

This branch was successfully deployed

2 active deployments
Preview – hyperdx-oss — e455cddc Deployed Nov 12, 2026 by vercel[bot]
Preview – hyperdx-storybook — e455cddc Deployed Nov 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review/tier-2 Low risk — AI review + quick human skim

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants