Skip to content

Conversation

@dcramer
Copy link
Member

@dcramer dcramer commented Jan 27, 2026

Add interactive chart visualizations for aggregate query results using the MCP Apps protocol. When search_events returns aggregate data, it now includes structured chart data that MCP Apps-compatible clients can render as bar, pie, line charts, tables, or single numbers.

What this adds

  • New mcp-apps-ui package - Contains Chart.js-based visualization app bundled as a single HTML file using Vite
  • UI resource registration - Server registers ui://sentry/search-events-chart.html resource that clients can fetch
  • Tool metadata - search_events now includes _meta.ui.resourceUri in its tool definition
  • Chart data in responses - Aggregate queries return both text (for backward compatibility) and an embedded resource with structured chart data
  • AI-suggested chart types - The search_events agent can suggest appropriate chart types (bar, pie, line, table, number) based on query intent

How it works

  1. MCP Apps-compatible clients see _meta.ui.resourceUri in tool definition
  2. Client fetches the UI resource and renders it in a sandboxed iframe
  3. When search_events returns aggregate results, the response includes:
    • Text content (works everywhere)
    • Embedded resource with mimeType: "application/json;chart" containing structured data
  4. The UI app receives the tool result via app.ontoolresult and renders the chart

Backward compatibility

Clients without MCP Apps support continue to receive text responses exactly as before. The chart data is an additional content block that non-Apps clients simply ignore.

Chart type inference

The system infers chart type based on data shape:

  • Single value → number display
  • Non-numeric labels → pie chart
  • Time-based labels → line chart
  • Default → bar chart

The AI agent can also explicitly suggest a chart type based on query intent.

Add interactive chart visualizations for aggregate query results using
the MCP Apps protocol. When search_events returns aggregate data, it now
includes structured chart data that MCP Apps-compatible clients can
render as bar, pie, line charts, tables, or single numbers.

Key changes:
- Create new mcp-apps-ui package with Chart.js-based visualization
- Extend ToolConfig with optional UI metadata for resource URIs
- Register UI resources in server for client fetching
- Enhance formatters to return chart data alongside text for aggregates
- Add chartType field to search_events agent for visualization hints

The implementation maintains backward compatibility - clients without
MCP Apps support continue to receive text responses.

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

chartType,
),
];
}
Copy link

Choose a reason for hiding this comment

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

list_events returns chart data without UI configuration

Low Severity

The list_events tool uses the shared formatters (formatErrorResults, formatLogResults, formatSpanResults) which now return chart data for aggregate queries. However, list_events doesn't have a ui configuration, so MCP Apps clients won't receive the _meta.ui.resourceUri in tool annotations and won't know to render the chart. This creates inconsistent behavior where chart data is returned but can never be used.

Fix in Cursor Fix in Web

return value.toLocaleString();
}
return String(value);
}
Copy link

Choose a reason for hiding this comment

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

Unescaped user data in innerHTML creates XSS vulnerability

Medium Severity

The formatNumber function uses String(value) for non-numeric values without HTML escaping, then the result is inserted via innerHTML in renderTable and renderNumberDisplay. Sentry event data (error messages, span descriptions, custom attributes) can contain user-controlled content, which would be rendered as HTML. An attacker who can inject malicious content into Sentry events (e.g., <img onerror=...>) could execute JavaScript when a user visualizes that data.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

2 participants