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 for the
in-product UI and other direct REST clients.
These named REST fields are not an MCP Apps protocol. External hosts such as
Claude or ChatGPT do not receive the /murph/chat response when they call the
ask_murph MCP tool; they receive the standard MCP tool result described
below.
Each artifact field is optional and nullable. A client that does not render
MCP Apps can ignore every artifact and show the text
answer alone — the
answer is always self-contained.How a REST client renders an artifact
Every artifact names the MCP App that renders it and the data to hand it:- Load the MCP App at the artifact’s
resourceUri. - Pass the artifact’s
dataobject to the app as the tool result’sstructuredContent. The app routes ondata.endpointto the namedview.
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 Apps)
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 Apps host
(Claude, ChatGPT) that calls the ask_murph MCP tool does not receive that
REST response directly; it receives a standard tool result. Some result kinds
retain named compatibility data inside structuredContent, but rendering is
selected by standard result metadata:
- It selects one primary widget per turn — this result contract carries a
single render payload. Precedence, highest-intent first:
mcpAppWidget→creativeIntentMcpui→inventoryMcpui→creativeMcpui→discoveryMcpui→sellerAnalytics→murphEscalations. - The result embeds that widget’s
ui://resource incontentand sets a per-call_meta(ui.resourceUriand the legacyui/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 ofstructuredContentwhereontoolresultreads 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 instructuredContent, which the host hands the app.
Sales Agent validation handoff
The Agent page can pass a server-recognized validation context toask_murph.
It supplies identifiers only: the Agent, its returned skill version, an
available profile, and, when present, a Source. It never supplies credentials
or expands the caller’s authority.
A transaction validation can return salesAgentValidation with
status: "PENDING_CONFIRMATION". Its runId, implementationRevision,
generation, pendingStepId, and
nextAction: "CONFIRM_TRANSACTION_STEP" identify the one no-spend action
waiting for the owner. implementationRevision is read-only evidence. To
continue the run, return agentId, skillVersion, and
profile: "transaction" with the returned runId and pendingStepId, then
map generation to confirmationGeneration and nextAction to
confirmation. The service issues a separate, generation-fenced confirmation
before staging a media buy and before activating the sandbox campaign.
Do not construct or reuse a confirmation from another run. A stale, expired,
cancelled, or consumed confirmation cannot be replayed; start a new validation.
A completed result identifies its implementation revision and cleanup outcome.
It is validation evidence, not a certificate or authorization for a client
connection.
Protected Sales Agent certification request
A directly authenticated administrator of the Agent owner’s organization can ask Murph to record a request for protected technical certification evaluation. The request is accepted only when the exact current implementation already has an unexpired protected fixture and immutable evaluation template. The owner cannot provide either value, dispatch the work, or report an assertion result. Murph returnssalesAgentCertificationRequest when it records that intent:
actionUid identifies the immutable owner request and
implementationRevision identifies the implementation it applies to. The
QUEUED_FOR_PROTECTED_EVALUATION status means a protected system must still
recheck the pinned fixture and template before it can create or dispatch any
work. It does not mean a provider test ran, an assertion passed, or the Agent
is certified. Creative and complete-suite certification results remain
separate evidence.
Conversational MCP profile
The existing Murph MCP endpoint also exposes a portable conversation profile. MCP clients on buyer and seller accounts use the same two tools; existingask_murph calls keep their current request and response shape.
chat
Call chat to begin a conversation or add a turn. The request has one message
and may include up to five Base64 attachments, each no larger than 1 MiB after
decoding.
CallToolResult. Read the portable turn
from structuredContent.conversation:
status is completed, input_required, or failed. Messages contain only
display-safe user and assistant text; tool traces, internal context, and
credentials are never returned. A protocol failure instead sets isError and
may return only text or an error object in structuredContent.
When a turn declares an app widget, it appears as structuredContent.widget.
The result selects the widget through the standard _meta.ui.resourceUri
directive. Hosts must use that shared MCP Apps contract; they must not infer a
widget or route from Murph’s text.
Progress on a long turn
Achat turn runs Murph’s full tool loop, so an involved question can take
minutes to answer. Set the MCP protocol’s _meta.progressToken on the
tools/call request and the server sends notifications/progress messages
while the turn works, so a host can show the caller that a long turn is
running rather than hung.
Each notification carries a short message describing the current phase —
“Reading the docs…”, “Checking your account…”, “Writing it up…” — written in
the language the conversation is already being answered in. Internal tool
names are never sent; the phrases group tools by intent. The first
notification goes out before the turn starts, so a turn that calls no tools
still reports that it began. progress increments on each distinct phase and
no total is sent, because the number of phases is not known in advance —
render it as indeterminate progress rather than a percentage.
Progress is advisory. The tool result stays the authoritative answer, a client
may ignore the notifications, and a client that sends no progress token gets
exactly the synchronous behaviour it got before.
The portable profile also permits the MCP Tasks extension for a turn that a
server does not complete synchronously. Such a result is the native
CreateTaskResult task envelope (taskId, status, createdAt,
lastUpdatedAt, ttl, and optional pollInterval), which a client polls or
cancels using MCP Tasks. Murph’s current orchestration completes this profile
call synchronously.
get_conversation
Call get_conversation with a conversation ID to read display-safe turns. Set
after to the opaque cursor from nextAfter to request the following page.
conversationId, turns, and nextAfter when
another page is available. It does not create an agent-initiated message or
subscribe the caller to notifications.
Token usage
EveryPOST /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.Related
Conversation scope
Set a Murph conversation’s account or advertiser scope.
Ask Murph
How Murph works as the in-product assistant.