| 1136 | }; |
| 1137 | |
| 1138 | const renderedInAppResult = (input: { |
| 1139 | readonly code: string; |
| 1140 | readonly artifactId: string; |
| 1141 | readonly title: string; |
| 1142 | readonly url?: string | undefined; |
| 1143 | }): McpToolResult => ({ |
| 1144 | content: [ |
| 1145 | { |
| 1146 | type: "text", |
| 1147 | text: [ |
| 1148 | `Rendered "${input.title}" as an interactive UI component. Saved as artifact ${input.artifactId}.`, |
| 1149 | // The link rides along even though the widget rendered: clients lose |
| 1150 | // rendered widgets in ways the server never sees (a transcript |
| 1151 | // reopened without re-reading the ui:// resource shows raw JSON), and |
| 1152 | // when that happens this URL in the conversation is the only path |
| 1153 | // back to the artifact the model can offer. |
| 1154 | ...(input.url ? [`It also stays available at ${input.url}`] : []), |
| 1155 | ].join("\n"), |
| 1156 | }, |
| 1157 | ], |
| 1158 | structuredContent: { |
| 1159 | code: input.code, |
| 1160 | artifactId: input.artifactId, |
| 1161 | ...(input.url ? { url: input.url } : {}), |
| 1162 | }, |
| 1163 | }); |
| 1164 | |
| 1165 | const renderedAsLinkResult = (input: { |
| 1166 | readonly url: string; |