import { McpToolResult } from "./types" const OMIT_ARCHIVED = Symbol("omit-archived") /** Attach images to a tool payload; they become MCP image content next to the JSON text. */ export const MCP_IMAGES = Symbol("mcp-images") export type McpImage = { data: string, mimeType: string } export const withImages = >(payload: T, images: McpImage[]) => Object.assign(payload, { [MCP_IMAGES]: images }) function omitArchivedRecords(value: unknown): unknown | typeof OMIT_ARCHIVED { if (Array.isArray(value)) { return value .map(omitArchivedRecords) .filter((item) => item !== OMIT_ARCHIVED) } if (!value || typeof value !== "object") return value const prototype = Object.getPrototypeOf(value) if (prototype !== Object.prototype && prototype !== null) return value const record = value as Record if (record.archived === true) return OMIT_ARCHIVED return Object.fromEntries( Object.entries(record) .map(([key, item]) => [key, omitArchivedRecords(item)] as const) .filter(([, item]) => item !== OMIT_ARCHIVED), ) } export function asToolResult(payload: unknown): McpToolResult { const sanitizedPayload = omitArchivedRecords(payload) const resultPayload = sanitizedPayload === OMIT_ARCHIVED ? {} : sanitizedPayload const structuredContent = resultPayload && typeof resultPayload === "object" && !Array.isArray(resultPayload) ? resultPayload as Record : { result: resultPayload } const images: McpImage[] = (payload as any)?.[MCP_IMAGES] || [] return { content: [ { type: "text", text: JSON.stringify(resultPayload, null, 2), }, ...images.map((image) => ({ type: "image" as const, data: image.data, mimeType: image.mimeType })), ], structuredContent, } } export function asToolError(error: unknown): McpToolResult { const message = error instanceof Error ? error.message : "Unbekannter Fehler" return { content: [ { type: "text", text: message, }, ], isError: true, structuredContent: { error: message, }, } }