Skip to content

feat(mcp): support chart visualization for HogQL queries#53806

Open
posthog[bot] wants to merge 1 commit intomasterfrom
posthog-code/mcp-hogql-chart-visualization
Open

feat(mcp): support chart visualization for HogQL queries#53806
posthog[bot] wants to merge 1 commit intomasterfrom
posthog-code/mcp-hogql-chart-visualization

Conversation

@posthog
Copy link
Copy Markdown
Contributor

@posthog posthog bot commented Apr 8, 2026

Problem

When using the MCP to create dashboards/insights with HogQL queries, results always render as table views — even for time-series data that should be displayed as line charts. This is because:

  1. The DataVisualizationNodeSchema in the MCP only accepted kind and source, missing the display and chartSettings fields that the backend supports
  2. analyzeQuery() hardcoded DataVisualizationNode to visualization: 'table'
  3. No prompt guidance existed to tell the LLM when to use chart visualizations

Changes

Schema (services/mcp/src/schema/query.ts):

  • Added display field to DataVisualizationNodeSchema with enum values: ActionsLineGraph, ActionsBar, ActionsAreaGraph, ActionsTable, BoldNumber
  • Added chartSettings field with xAxis, yAxis, and seriesBreakdownColumn configuration
  • Rich descriptions guide the LLM on when to use each display type

Query analysis (services/mcp/src/tools/shared.ts):

  • analyzeQuery() now checks for chart display types on DataVisualizationNode and returns visualization: 'trends' instead of always 'table'

Tool descriptions (services/mcp/schema/tool-definitions.json):

  • Updated query-run description with guidance and example for wrapping HogQL queries in DataVisualizationNode with chart settings
  • Updated insight-create-from-query description with visualization type selection guidance

How did you test this code?

  • All 478 MCP unit tests pass including updated schema snapshots
  • TypeScript type check passes
  • This was authored by an agent; manual testing of MCP tool calls against a live instance has not been performed

🤖 LLM context

Authored by PostHog Code agent. The fix addresses all three layers needed: schema (accepting the fields), runtime (detecting chart visualization), and prompt (guiding the LLM to use charts for time-series data).


Created with PostHog Code

…lizationNode

HogQL queries created via MCP always produced table views because the
DataVisualizationNode schema lacked display and chartSettings fields.
This adds display type selection (line graph, bar, area, bold number,
table) and chart axis configuration to the MCP tool schema, updates
analyzeQuery to detect chart visualizations, and adds prompt guidance
so the LLM knows when to use line charts for time-series data.

Generated-By: PostHog Code
Task-Id: 05b5a308-0893-459c-802f-972f80e59a59
@rafaeelaudibert rafaeelaudibert marked this pull request as ready for review April 8, 2026 23:27
@rafaeelaudibert
Copy link
Copy Markdown
Member

@fercgomes in case you wanna own this! also cc @skoob13 since you might know if this is a good solution. More context in https://posthog.slack.com/archives/C0ACRAMJUAG/p1775669298592529

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 8, 2026

Vulnerabilities

No security concerns identified. Changes are limited to schema field additions, LLM prompt descriptions, and visualization-type detection logic with no user data handling or auth-boundary impact.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: services/mcp/src/tools/shared.ts
Line: 67-73

Comment:
**Chart path returns results without column names, breaking UI rendering**

When a `DataVisualizationNode` with a chart display type is detected, `analyzeQuery()` returns `visualization: 'trends'` with no `innerQuery`. In `run.ts`, the `'trends'` branch then returns `results: queryResult.data.results`. For a DataVisualizationNode wrapping a HogQL query, the PostHog API returns `{ results: [[row, ...], ...], columns: ['col1', 'col2'] }`, so `queryResult.data.results` is raw row arrays without column names.

`Component.tsx`'s `inferVisualizationType` then receives those raw arrays and:
- `isTrendsResult` fails (items lack `.data`/`.labels`/`.days` arrays)
- `isHogQLResult` fails (it's an array, not `{columns, results}`)
- The query-kind fallback only handles `TrendsQuery`, `FunnelsQuery`, and `HogQLQuery``DataVisualizationNode` is not covered

The result is `null` and the UI shows _"This visualization type isn't supported in this view yet"_ instead of a chart. The chart feature is effectively silently broken end-to-end.

Two changes are needed together:
1. In `run.ts`, keep the `{ columns, results }` format for `DataVisualizationNode` (same as the table path), or add a dedicated `'dataViz'` branch that preserves columns.
2. In `Component.tsx`, add a `DataVisualizationNode` case to `inferVisualizationType`'s query-kind fallback and a corresponding chart renderer that reads `chartSettings` from the query to map column names to positions.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(mcp): support chart visualization f..." | Re-trigger Greptile

Comment on lines 67 to 73
// DataVisualizationNode wraps HogQL queries for custom visualizations
if (q.kind === 'DataVisualizationNode' && q.source && typeof q.source === 'object') {
// When a chart display type is set, treat as trends-style visualization
if (typeof q.display === 'string' && CHART_DISPLAY_TYPES.has(q.display)) {
return { visualization: 'trends', innerKind: 'HogQLQuery' }
}
return { visualization: 'table', innerKind: 'HogQLQuery' }
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 Chart path returns results without column names, breaking UI rendering

When a DataVisualizationNode with a chart display type is detected, analyzeQuery() returns visualization: 'trends' with no innerQuery. In run.ts, the 'trends' branch then returns results: queryResult.data.results. For a DataVisualizationNode wrapping a HogQL query, the PostHog API returns { results: [[row, ...], ...], columns: ['col1', 'col2'] }, so queryResult.data.results is raw row arrays without column names.

Component.tsx's inferVisualizationType then receives those raw arrays and:

  • isTrendsResult fails (items lack .data/.labels/.days arrays)
  • isHogQLResult fails (it's an array, not {columns, results})
  • The query-kind fallback only handles TrendsQuery, FunnelsQuery, and HogQLQueryDataVisualizationNode is not covered

The result is null and the UI shows "This visualization type isn't supported in this view yet" instead of a chart. The chart feature is effectively silently broken end-to-end.

Two changes are needed together:

  1. In run.ts, keep the { columns, results } format for DataVisualizationNode (same as the table path), or add a dedicated 'dataViz' branch that preserves columns.
  2. In Component.tsx, add a DataVisualizationNode case to inferVisualizationType's query-kind fallback and a corresponding chart renderer that reads chartSettings from the query to map column names to positions.
Prompt To Fix With AI
This is a comment left during a code review.
Path: services/mcp/src/tools/shared.ts
Line: 67-73

Comment:
**Chart path returns results without column names, breaking UI rendering**

When a `DataVisualizationNode` with a chart display type is detected, `analyzeQuery()` returns `visualization: 'trends'` with no `innerQuery`. In `run.ts`, the `'trends'` branch then returns `results: queryResult.data.results`. For a DataVisualizationNode wrapping a HogQL query, the PostHog API returns `{ results: [[row, ...], ...], columns: ['col1', 'col2'] }`, so `queryResult.data.results` is raw row arrays without column names.

`Component.tsx`'s `inferVisualizationType` then receives those raw arrays and:
- `isTrendsResult` fails (items lack `.data`/`.labels`/`.days` arrays)
- `isHogQLResult` fails (it's an array, not `{columns, results}`)
- The query-kind fallback only handles `TrendsQuery`, `FunnelsQuery`, and `HogQLQuery``DataVisualizationNode` is not covered

The result is `null` and the UI shows _"This visualization type isn't supported in this view yet"_ instead of a chart. The chart feature is effectively silently broken end-to-end.

Two changes are needed together:
1. In `run.ts`, keep the `{ columns, results }` format for `DataVisualizationNode` (same as the table path), or add a dedicated `'dataViz'` branch that preserves columns.
2. In `Component.tsx`, add a `DataVisualizationNode` case to `inferVisualizationType`'s query-kind fallback and a corresponding chart renderer that reads `chartSettings` from the query to map column names to positions.

How can I resolve this? If you propose a fix, please make it concise.

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