( content: Array<any>, )
| 15 | } |
| 16 | |
| 17 | export function mcpContentToTanstack( |
| 18 | content: Array<any>, |
| 19 | ): string | Array<ContentPart> { |
| 20 | // A valid MCP result may carry only structuredContent (no content[]) → guard |
| 21 | // against undefined/non-array before reading length/map. |
| 22 | if (!Array.isArray(content)) return '' |
| 23 | // Single text block → plain string (most common, best for the model). |
| 24 | if (content.length === 1 && content[0]?.type === 'text') |
| 25 | return content[0].text |
| 26 | const parts = content |
| 27 | .map((c): ContentPart => { |
| 28 | switch (c.type) { |
| 29 | case 'text': |
| 30 | return { type: 'text', content: c.text } |
| 31 | case 'image': |
| 32 | return { |
| 33 | type: 'image', |
| 34 | source: { type: 'data', value: c.data, mimeType: c.mimeType }, |
| 35 | } |
| 36 | case 'resource': { |
| 37 | const uri = c.resource?.uri |
| 38 | if (typeof uri === 'string' && uri.startsWith('ui://')) { |
| 39 | // ui:// resources are surfaced via readResource (MCP Apps); omit from model text. |
| 40 | return { type: 'text', content: '' } |
| 41 | } |
| 42 | return { type: 'text', content: JSON.stringify(c.resource) } |
| 43 | } |
| 44 | default: |
| 45 | return { type: 'text', content: JSON.stringify(c) } |
| 46 | } |
| 47 | }) |
| 48 | .filter((p) => !(p.type === 'text' && p.content === '')) |
| 49 | return parts.length ? parts : '' |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Build the execute body that proxies a TanStack tool call to an MCP server's |
no outgoing calls
no test coverage detected