Skip to content

fix: Nudge agents towards macros in raw SQL tiles#2473

Merged
kodiakhq[bot] merged 2 commits into
mainfrom
drew/mcp-warning-missing-macros
Jun 17, 2026
Merged

fix: Nudge agents towards macros in raw SQL tiles#2473
kodiakhq[bot] merged 2 commits into
mainfrom
drew/mcp-warning-missing-macros

Conversation

@pulpdrew

@pulpdrew pulpdrew commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves the MCP schema descriptions for SQL chart tiles and adds warnings when agents create SQL chart tiles without recommended / required macros.

Screenshots or video

Screenshot 2026-06-16 at 12 14 40 PM Screenshot 2026-06-16 at 12 18 15 PM

How to test

Test locally by connecting to the MCP server and asking claude to build some dashboards.

References

  • Linear Issue: HDX-4570
  • Related PRs:

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment Jun 17, 2026 2:42pm
hyperdx-storybook Ready Ready Preview, Comment Jun 17, 2026 2:42pm

Request Review

@changeset-bot

changeset-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b5d1e4e

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

This PR includes changesets to release 4 packages
Name Type
@hyperdx/api Patch
@hyperdx/common-utils 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

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

🟡 Tier 3 — Standard

Introduces new logic, modifies core functionality, or touches areas with non-trivial risk.

Why this tier:

  • Cross-layer change: touches backend (packages/api) + shared utils (packages/common-utils)

Review process: Full human review — logic, architecture, edge cases.
SLA: First-pass feedback within 1 business day.

Stats
  • Production files changed: 6
  • Production lines changed: 208 (+ 510 in test files, excluded from tier calculation)
  • Branch: drew/mcp-warning-missing-macros
  • Author: pulpdrew

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

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves MCP agent guidance for raw SQL dashboard tiles by adding non-blocking advisory warnings when agents create tiles that omit recommended macros ($__timeFilter, $__filters, $__sourceTable, $__timeInterval), and rewrites the sqlTemplate schema description with detailed macro guidelines and expansion examples.

  • Adds hasMacro(), TIME_RANGE_MACROS, and INTERVAL_MACROS to common-utils/macros.ts, and refactors SOURCE_DEPENDENT_MACROS to bare names; also fixes a subtle prefix-match bug in getRawSqlTilesMissingRequiredSource (previously used includes which would match $__filtersExtra).
  • Adds getRawSqlTileMacroWarnings in validation.ts and wires it into saveDashboard, patchDashboard, and queryTile so advisory warnings are returned alongside successful responses.
  • The schema description for $__fromTime/$__toTime states they expand to raw integer parameters, but the actual macro implementations produce toDateTime() expressions. The inline example also has GROUP BY ServiceName, ts while ServiceName is missing from the SELECT list.

Confidence Score: 5/5

Safe to merge — all warnings are non-blocking advisories; no existing query behaviour is altered.

The core logic changes (macro detection, warning generation, wiring into three tools) are well-tested with both unit and integration tests. The only issues are in the new sqlTemplate schema description copy: an inaccurate expansion note for $__fromTime/$__toTime and a SELECT/GROUP BY mismatch in the example query. Neither affects runtime behaviour.

packages/api/src/mcp/tools/dashboards/schemas.ts — the $__fromTime/$__toTime expansion description and the example SQL GROUP BY.

Important Files Changed

Filename Overview
packages/common-utils/src/macros.ts Adds hasMacro() helper and exports three new const arrays (SOURCE_DEPENDENT_MACROS refactored to bare names, TIME_RANGE_MACROS, INTERVAL_MACROS) used by the new advisory-warning logic. Implementation is correct and well-tested.
packages/api/src/mcp/tools/dashboards/validation.ts Adds getRawSqlTileMacroWarnings which produces advisory strings for raw SQL tiles missing time-range, interval, or source macros. Also updates getRawSqlTilesMissingRequiredSource to use hasMacro instead of includes, fixing false-positive prefix matches. Logic is sound and well-covered by tests.
packages/api/src/mcp/tools/dashboards/schemas.ts Expands the sqlTemplate description with detailed macro guidelines and an example. Two minor issues: $__fromTime/$__toTime are described as expanding to raw integer params rather than toDateTime() expressions, and the example GROUP BY references ServiceName which is absent from the SELECT list.
packages/api/src/mcp/tools/dashboards/saveDashboard.ts Calls getRawSqlTileMacroWarnings after building tilesWithId and conditionally injects warnings into the JSON response for both create and update paths. Non-blocking and correctly structured.
packages/api/src/mcp/tools/dashboards/patchDashboard.ts Adds macro warnings to the patch response by checking the single patched tile. Clean and minimal change.
packages/api/src/mcp/tools/dashboards/queryTile.ts Injects macro warnings into the JSON body of a successful query result. The try/catch correctly silences any parse failure and leaves the response unmodified.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Agent calls save/patch/query tile] --> B{Is tile a raw SQL tile?}
    B -- No --> C[Skip macro check]
    B -- Yes --> D[getRawSqlTileMacroWarnings]
    D --> E{Missing time-range macro?}
    E -- Yes --> F[Add time-range warning]
    E -- No --> G{Time-series display type?}
    G -- Yes --> H{Missing interval macro?}
    H -- Yes --> I[Add interval warning]
    H -- No --> J{Missing filters/sourceTable macros?}
    G -- No --> J
    J -- Yes --> K[Add filters/sourceTable warning]
    J -- No --> L[No warnings]
    F --> M[Collect all warnings]
    I --> M
    K --> M
    M --> N{warnings.length > 0?}
    N -- Yes --> O[Attach warnings array to response]
    N -- No --> P[Return response as-is]
    O --> Q[Non-blocking: operation still succeeds]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Agent calls save/patch/query tile] --> B{Is tile a raw SQL tile?}
    B -- No --> C[Skip macro check]
    B -- Yes --> D[getRawSqlTileMacroWarnings]
    D --> E{Missing time-range macro?}
    E -- Yes --> F[Add time-range warning]
    E -- No --> G{Time-series display type?}
    G -- Yes --> H{Missing interval macro?}
    H -- Yes --> I[Add interval warning]
    H -- No --> J{Missing filters/sourceTable macros?}
    G -- No --> J
    J -- Yes --> K[Add filters/sourceTable warning]
    J -- No --> L[No warnings]
    F --> M[Collect all warnings]
    I --> M
    K --> M
    M --> N{warnings.length > 0?}
    N -- Yes --> O[Attach warnings array to response]
    N -- No --> P[Return response as-is]
    O --> Q[Non-blocking: operation still succeeds]
Loading

Reviews (3): Last reviewed commit: "Merge branch 'main' into drew/mcp-warnin..." | Re-trigger Greptile

Comment thread packages/api/src/mcp/tools/dashboards/schemas.ts
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

E2E Test Results

All tests passed • 198 passed • 3 skipped • 1386s

Status Count
✅ Passed 198
❌ Failed 0
⚠️ Flaky 6
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

@pulpdrew pulpdrew force-pushed the drew/mcp-warning-missing-macros branch from c52f0ac to 820ffab Compare June 16, 2026 16:19
Comment on lines +240 to +246
/**
* True if the SQL contains at least one occurrence of the `$__<name>` macro.
*/
export function hasMacro(sql: string, name: string): boolean {
return findMacros(sql, name).length > 0;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

backported from EE repo

@knudtty knudtty left a comment

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.

Just one observation

- $__timeFilter_ms(col) is the same but should be used when col has millisecond precision (DateTime64 type)
- $__dateFilter(col) is the same but should be used when col has Day granularity (Date type)
- $__dateTimeFilter(dateCol, dateTimeCol) should be used when there are both Date and DateTime columns that should be filtered on.
- NEVER hardcode a fixed time range unless the user specifically asks for it.

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.

I'm wondering if this is too strict? I would think a fixed time range is useful when investigating an event

@pulpdrew pulpdrew Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

IMO this is correct for these schemas, since they're only for dashboard building tools, not general incident investigation or notebooks. Even when building dashboards for an investigation, I would still think it makes sense to include these macros so that the time input to works on the dashboard. A user can always set the time range in links they share with others. I can soften the language though if you think there are legitimate cases for fixed-time-range dashboard tiles (even though those aren't really possible with builder tiles)

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.

Nope makes sense! Thanks for the clarification

@kodiakhq kodiakhq Bot merged commit caba7c2 into main Jun 17, 2026
19 checks passed
@kodiakhq kodiakhq Bot deleted the drew/mcp-warning-missing-macros branch June 17, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge review/tier-3 Standard — full human review required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants