Skip to main content
A POST /api/v2/murph/chat response always carries the assistant’s text answer. On turns where Murph runs a tool that has a canonical interactive surface, the response also carries a structured rendering artifact. MCPUI hosts (the in-product Murph UI, and external hosts such as Claude or ChatGPT) render that artifact instead of reconstructing the surface from the text.
Each artifact field is optional and nullable. A client that does not render MCPUI can ignore every artifact and show the text answer alone — the answer is always self-contained.

How to render an artifact

Every artifact names the MCP App that renders it and the data to hand it:
  1. Load the MCP App at the artifact’s resourceUri.
  2. Pass the artifact’s data object to the app as the tool result’s structuredContent. The app routes on data.endpoint to the named view.
The host decides where to place the surface — the in-product Murph UI renders the discovery widget above the text answer, for example.

discoveryMcpui

Emitted on a successful discover_products tool call. Renders the product discovery surface — a browsable, selectable list of the discovered products grouped by storefront, with per-product brief-relevance reasoning.
When this artifact is present, Murph’s text answer is a concise orientation (totals, price range, any recommended plans) plus next steps — it deliberately does not re-list every product, because the widget already shows the full, selectable set.

Other rendering artifacts

The chat response uses the same pattern for other canonical surfaces: Each carries kind, resourceUri, canonicalSurface, and a data payload to hand the app as structuredContent; creativeMcpui additionally carries a refresh directive describing the tool call that reloads the surface, and inventoryMcpui carries the esaId and the initial selector filters.

ask_murph MCP tool result (conformant MCP-UI)

The artifacts above ride the REST /api/v2/murph/chat response as named fields — the in-product Murph UI reads them directly. An external MCP-UI host (Claude, ChatGPT) that calls the ask_murph MCP tool never sees those named fields; it sees a standard tool result. So ask_murph surfaces a turn’s widget the conformant way any MCP-UI host renders:
  • It selects one primary widget per turn — an MCP-UI tool result carries a single render payload. Precedence, highest-intent first: mcpAppWidgetcreativeIntentMcpuiinventoryMcpuicreativeMcpuidiscoveryMcpuisellerAnalyticsmurphEscalations.
  • The result embeds that widget’s ui:// resource in content and sets a per-call _meta (ui.resourceUri and the legacy ui/resourceUri) so the host loads the right MCP App for this result.
  • For api-call-style widgets (discovery, inventory, creative, creative-intent), the app reads the flat api-call envelope (success, endpoint, params, data), so that envelope is spread onto the top level of structuredContent where ontoolresult reads it. The now-redundant named field is dropped so the payload isn’t carried twice.
  • Launch widgets (mcpAppWidget) and named-field panels (sellerAnalytics, murphEscalations) carry no api-call envelope; their data already sits under their named key in structuredContent, which the host hands the app.
A turn that produced several widgets still renders one in a generic host; the in-product drawer can show all of them via the REST fields above.

Token usage

Every POST /api/v2/murph/chat response carries a usage object reporting the turn’s token consumption, cumulative across the tool-loop iterations of the turn.
The model reports cache reads and creations separately from inputTokens — they are not included in it. To get the true total input volume for a turn, sum inputTokens + cacheReadInputTokens + cacheCreationInputTokens. Murph caches its system prompt and tool surface, so on a warm conversation cacheReadInputTokens is typically the largest of the three.

Conversation scope

Bind a Murph conversation to your account or a single advertiser.

Ask Murph

How Murph works as the in-product assistant.