@W-23146707 Add telemetry for errors and URL button clicks in MCP app#530
Merged
Conversation
Add an app-only server tool (record-mcp-app-error) that the sandboxed MCP app calls via app.callServerTool to record a product-telemetry event through the existing DirectTelemetryForwarder. The app reports all four showError scenarios (TOOL_ERROR, PARSE_ERROR, AUTH_ERROR, EMBED_LOAD_ERROR) via a fire-and-forget client that never throws and no-ops when the host cannot proxy server tools. The tool is app-only (hidden from the model) and gated on the mcp-apps feature flag, mirroring get-embed-token. It makes no Tableau REST API calls; the app supplies scenario (+ optional message) and the server enriches with request/session/site/user/pod context. Telemetry fires before the error-UI early-return so errors are recorded even when the viz container is missing.
The error screen ("Unable to load this Tableau view") rendered on an
off-white background — the browser default showing through the
transparent body/.main/.viz-container ancestors, since no rule set a
background. Paint white on body:has(.mcp-app-error) so it propagates to
the whole viewport edge-to-edge, scoped to the error state only so the
normal viz render is unaffected.
Rename the app-only telemetry tool and its client from the error-specific record-mcp-app-error / reportMcpAppError to the generic record-event / recordEvent, so it can carry any MCP-app event, not just errors. The tool name is updated in lockstep across the client call, the OAuth scope allowlist, the passthrough-auth allowlist, and toolName.ts. Add an MCP_APP_CLICKED event: clicking "Open in Tableau" now fires recordEvent(app, 'MCP_APP_CLICKED', url) fire-and-forget before openLink. Reshape the emitted event to match: event type tableau_mcp_event.completed -> tableau_mcp_event, and the payload carries event_type + message in place of the former scenario / request_id / session_id fields.
jarhun88
marked this pull request as ready for review
July 17, 2026 23:01
stephendeoca
approved these changes
Jul 21, 2026
record-event and get-embed-token are app-only, mcp-apps-gated tools that don't belong in token-management (OAuth token/consent lifecycle). Move them into a new mcp-apps group so operators can include/exclude them independently.
- event_type: cap at 64 chars and require SCREAMING_SNAKE_CASE, rejecting malformed values (kept a bounded string, not a hard enum, since the event-type set is intentionally app-extensible) - message: truncate to 1024 chars before forwarding so an over-long detail never fails the telemetry call
…r-telemetry Resolves conflicts from main's src/web/apps/src reorg (flat lib/ split into embed/, hitl/, shared/): recordEventClient relocated to shared/; combined imports preserved in showError, handleToolResult, handleConfirmResult; version reconciled to 3.5.2. Record-event telemetry feature intact.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds product telemetry for MCP app UI errors via a new app-only server tool.
added New tool
record-mcp-app-error(src/tools/web/recordMcpAppError/): the sandboxed MCP app calls it viaapp.callServerToolto record atableau_mcp_event.completedproduct-telemetry event through the existingDirectTelemetryForwarder. Its also called when url link is clickedthis is added for any mcp app call that fails (for the embedded viz mcp app scenario only)
Registration + scopes: added to
toolName.ts/tools.ts, empty mcp/api scopes inscopes.ts, and safelisted in the passthrough-auth guard (the tool makes no Tableau REST API calls).also added a error_message field to the tool call product telemetry to get better undrestanding of onprem errors.
added white coloring to the mcp app error background
Motivation and Context
MCP app UI errors were invisible to product telemetry. This routes them through the server (never the browser) so the ingest endpoint/credentials stay inside the trust boundary and events are enriched with request/session/site/user/pod context the client can't produce. The tool is hidden from the model and gated on the
mcp-appsfeature flag, mirroringget-embed-token.Type of Change
How Has This Been Tested?
New/updated unit tests (all passing locally via
npx vitest run):recordMcpAppError.test.ts(server tool: properties, app-only visibility, telemetry payload + server enrichment, feature gate)recordMcpAppErrorClient.test.ts(fire-and-forget client: never throws, no-ops without serverTools, omits message when no cause)showError.test.ts,handleToolResult.test.ts,handleConfirmResult.test.ts(wiring across all four scenarios, incl. container-missing)passthroughAuthMiddleware.test.ts(no-API-scope safelist)Full suite green apart from one pre-existing, unrelated failure (
adminInsights/getStaleContentReportdate-fixture rot). Lint clean on changed files; MCP app bundles build successfully.Related Issues
None.
Checklist
npm run version.