Extract structured data from an MCP CallToolResult.
AdCP servers put the typed tool response in structuredContent (MCP L3);
content[0].text carries a human-readable summary (MCP L2). Prefer
structuredContent when present, fall back to JSON-parsing a text block
for servers that haven't adopted structuredContent yet.
Returns undefined when neither surface yields usable data. This
is the ergonomic happy-path helper — the companion
unwrapProtocolResponsethrows on missing/invalid payloads and
additionally validates against a per-tool schema, handling protocol
detection and extraction-path provenance. Pick based on the caller:
extractResult<T>(res) — "I just want the payload; undefined if
there's nothing to extract." No throw, no validation.
unwrapProtocolResponse(res, toolName, 'mcp') — "Give me a
validated, schema-narrowed AdCP response or throw." Heavier, tool-aware.
content[] entries that aren't text blocks (image / audio / resource
per the MCP CallToolResult.content schema) are intentionally
skipped — AdCP's typed payload always rides on structuredContent
or the first JSON-parseable text block.
Example
import { extractResult } from'@adcp/sdk';
constres = awaitmcpClient.callTool({ name:'get_products', arguments: {} }); constpayload = extractResult<GetProductsResponse>(res); if (payload && 'products'inpayload) { // payload is the Success arm — narrow further if it's a Success|Error union }
Extract structured data from an MCP
CallToolResult.AdCP servers put the typed tool response in
structuredContent(MCP L3);content[0].textcarries a human-readable summary (MCP L2). PreferstructuredContentwhen present, fall back to JSON-parsing a text block for servers that haven't adoptedstructuredContentyet.Returns
undefinedwhen neither surface yields usable data. This is the ergonomic happy-path helper — the companionunwrapProtocolResponsethrows on missing/invalid payloads and additionally validates against a per-tool schema, handling protocol detection and extraction-path provenance. Pick based on the caller:extractResult<T>(res)— "I just want the payload;undefinedif there's nothing to extract." No throw, no validation.unwrapProtocolResponse(res, toolName, 'mcp')— "Give me a validated, schema-narrowed AdCP response or throw." Heavier, tool-aware.content[]entries that aren't text blocks (image / audio / resource per the MCPCallToolResult.contentschema) are intentionally skipped — AdCP's typed payload always rides onstructuredContentor the first JSON-parseable text block.Example