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
7 changes: 7 additions & 0 deletions .changeset/table-tile-alternate-row-mcp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@hyperdx/api": patch
---

feat(mcp): expose table tile alternate row background in the dashboard authoring tool

The clickstack_save_dashboard MCP tool now accepts alternateRowBackground on builder table tiles, so AI-authored dashboards can turn on zebra striping. Defaults to false.
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ describe('MCP Dashboard Tools - clickstack_save_dashboard', () => {
select: [{ aggFn: 'count' }],
groupBy: 'SpanName',
groupByColumnsOnLeft: true,
alternateRowBackground: true,
},
},
{
Expand Down Expand Up @@ -251,6 +252,7 @@ describe('MCP Dashboard Tools - clickstack_save_dashboard', () => {
);
expect(tableTile).toBeDefined();
expect(tableTile.config.groupByColumnsOnLeft).toBe(true);
expect(tableTile.config.alternateRowBackground).toBe(true);
});

it('should create a dashboard with a raw SQL tile', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/mcp/prompts/dashboards/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Apply these before calling clickstack_save_dashboard. Each rule is enforced by t

3. GROUP BY HAS NO ALIAS HOOK. The chart config's groupBy is a single expression string and the renderer uses it verbatim as the column header (tables) and as the raw column name everywhere else (CSV export, tooltips, orderBy references, onClick template references). Grouping a table by SpanAttributes['http.route'] produces a column header that reads literally as arrayElement(SpanAttributes, 'http.route'). When a top-level column carries the same semantic, prefer it: SpanName for operation, ServiceName for service, SeverityText for log severity. When the dimension exists only as a Map attribute and the column header matters, drop to a raw SQL tile (configType: "sql") and write the column with AS alias. Line, stacked_bar, and pie tiles legend by the value not the column name, so the issue is invisible on the chart itself but still bites CSV export and onClick template references.

4. INVENTORY-STYLE TABLES PUT THE GROUP BY ON THE LEFT. Set groupByColumnsOnLeft: true on tables that read like a list of things (one row per service, per endpoint, per tenant).
4. INVENTORY-STYLE TABLES PUT THE GROUP BY ON THE LEFT. Set groupByColumnsOnLeft: true on tables that read like a list of things (one row per service, per endpoint, per tenant). For wide tables that are hard to scan, set alternateRowBackground: true to zebra-stripe the rows (default false).

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.

P1 Raw SQL setting is stripped

When an agent follows this unqualified guidance for a wide raw SQL table, mcpSqlTileSchema strips alternateRowBackground before the downstream schema receives it, causing the save to succeed without applying the requested zebra striping. Scope this guidance to builder tables or expose the field on the raw SQL MCP schema, which already has downstream support for it.

Knowledge Base Used: MCP server, AI assistant, and OpAMP integration

Fix in Claude Code Fix in Conductor Fix in Cursor Fix in Codex


5. RED COLUMNS FOR SERVICE / ENDPOINT TABLES. Request rate (count), Error rate (count with where: "StatusCode:STATUS_CODE_ERROR"), Duration (quantile P95 on the Duration column). Three columns, all aliased.

Expand Down
7 changes: 7 additions & 0 deletions packages/api/src/mcp/tools/dashboards/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,13 @@ const mcpTableTileSchema = mcpTileLayoutSchema.extend({
'Render Group By columns on the left side of the table, before the series columns. ' +
'Default false (Group By columns on the right).',
),
alternateRowBackground: z
.boolean()
.optional()
.describe(
'Zebra-stripe the table by tinting alternating rows, which aids scanning on wide tables. ' +
'Default false.',
),
numberFormat: mcpNumberFormatSchema
.optional()
.describe(tileLevelNumberFormatDescription),
Expand Down
Loading