A CallToolResult has three parts, read by different consumers:
| Part | Read by | Put here |
|---|---|---|
content |
the model | a short text summary the model can talk about |
structuredContent |
the View (and the model, in hosts that pass it) | the data the View renders |
_meta |
the View only | data the model should not see (ids, large payloads, signed URLs) |
When your handler returns a plain object, moonpeak puts it in structuredContent and a JSON copy in content. For large data, return the shape yourself so the model gets a summary:
export default async function ({ from }) {
const events = upcomingPhases(parseDate(from), 8);
return {
content: [{ type: "text", text: `Next: ${events[0].phase} on ${events[0].date}.` }],
structuredContent: { from, events },
};
}Throwing returns isError: true with your message as text. The View sees isError in useToolData; useCallTool throws it as an Error.