diff --git a/src/tools/checkRenderStatus.ts b/src/tools/checkRenderStatus.ts index 5484e4f..3974073 100644 --- a/src/tools/checkRenderStatus.ts +++ b/src/tools/checkRenderStatus.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { getRenderItem } from "../sdk"; import env from "../env"; +import { toToolResponse } from "../utils/toolResponse"; export function registerCheckRenderStatus(server: McpServer) { const Input = { @@ -96,43 +97,36 @@ Use when: // Handle successful completion if (render.state === "DONE") { - return { - content: [], - structuredContent: { - message: "Render completed successfully.", - renderId: render.id, - renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, - projectDesignId: render.projectId, - templateVariantId: render.templateId, - projectDesignName: render.projectName, - templateVariantName: render.templateName, - state: render.state, - output: render.output, - }, - }; + return toToolResponse({ + message: "Render completed successfully.", + renderId: render.id, + renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, + projectDesignId: render.projectId, + templateVariantId: render.templateId, + projectDesignName: render.projectName, + templateVariantName: render.templateName, + state: render.state, + output: render.output, + }); } if (render.state === "CANCELLED") { - return { - content: [], - structuredContent: { - message: "Render was cancelled.", - renderId: render.id, - renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, - projectDesignId: render.projectId, - templateVariantId: render.templateId, - projectDesignName: render.projectName, - templateVariantName: render.templateName, - state: render.state, - }, - }; + return toToolResponse({ + message: "Render was cancelled.", + renderId: render.id, + renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, + projectDesignId: render.projectId, + templateVariantId: render.templateId, + projectDesignName: render.projectName, + templateVariantName: render.templateName, + state: render.state, + }); } // Handle error states if (render.state === "FAILED" || render.state === "INVALID") { - return { - content: [], - structuredContent: { + return toToolResponse( + { message: "Render failed.", renderId: render.id, renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, @@ -144,35 +138,31 @@ Use when: errorMessage: render.error.message, errorDetails: JSON.stringify(render.error.details), }, - isError: true, - }; + true + ); } // Processing - return { - content: [], - structuredContent: { - message: "Render is processing. Please wait and check back later.", - renderId: render.id, - renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, - projectDesignId: render.projectId, - templateVariantId: render.templateId, - projectDesignName: render.projectName, - templateVariantName: render.templateName, - state: render.state, - }, - }; + return toToolResponse({ + message: "Render is processing. Please wait and check back later.", + renderId: render.id, + renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, + projectDesignId: render.projectId, + templateVariantId: render.templateId, + projectDesignName: render.projectName, + templateVariantName: render.templateName, + state: render.state, + }); } catch (err: any) { - return { - content: [], - structuredContent: { + return toToolResponse( + { message: "Render status could not be retrieved.", renderId, errorMessage: err.message || "Failed to check render status", errorDetails: err, }, - isError: true, - }; + true + ); } } ); diff --git a/src/tools/getRenderableItemDetails.ts b/src/tools/getRenderableItemDetails.ts index 61f934d..f85b716 100644 --- a/src/tools/getRenderableItemDetails.ts +++ b/src/tools/getRenderableItemDetails.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { getRenderableItemsDetails } from "../sdk"; +import { toToolResponse } from "../utils/toolResponse"; export function registerGetRenderableItemDetails(server: McpServer) { const Input = { @@ -124,10 +125,7 @@ Follow-ups: isDesign ); - return { - content: [{ type: "text", text: JSON.stringify(itemDetails) }], - structuredContent: { itemDetails }, - }; + return toToolResponse({ itemDetails }); } ); } diff --git a/src/tools/listRenderableItems.ts b/src/tools/listRenderableItems.ts index 7d15f32..04c2c60 100644 --- a/src/tools/listRenderableItems.ts +++ b/src/tools/listRenderableItems.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { listRenderableItems } from "../sdk"; +import { toToolResponse } from "../utils/toolResponse"; export function registerListRenderableItems(server: McpServer) { const Input = { @@ -111,10 +112,7 @@ Follow-ups: excludeProjects, }); - return { - content: [{ type: "text", text: JSON.stringify(items) }], - structuredContent: { items }, - }; + return toToolResponse({ items }); } ); } diff --git a/src/tools/renderItem.ts b/src/tools/renderItem.ts index fa9d8ec..26ac448 100644 --- a/src/tools/renderItem.ts +++ b/src/tools/renderItem.ts @@ -14,6 +14,7 @@ import { TemplateVariantNotFoundError, } from "./errors"; import env from "../env"; +import { toToolResponse } from "../utils/toolResponse"; export function registerRenderItem(server: McpServer) { const Input = { @@ -152,55 +153,29 @@ Use when: } // Successful submission - const output = { + return toToolResponse({ renderId: render.id, renderDetailsPageUrl: `${env.PLAINLY_APP_URL}/dashboard/renders/${render.id}`, projectDesignId: render.projectId, templateVariantId: render.templateId, projectDesignName: render.projectName, templateVariantName: render.templateName, - }; - return { - content: [ - { - type: "text", - text: JSON.stringify(output), - }, - ], - structuredContent: output, - }; + }); } catch (err: any) { // Known errors with specific handling if (err instanceof PlainlyMcpServerError) { - const errorOutput = { - message: err.message, - solution: err.solution, - details: err.details, - }; - - return { - content: [ - { - type: "text", - text: JSON.stringify(errorOutput), - }, - ], - structuredContent: errorOutput, - isError: true, - }; + return toToolResponse( + { + message: err.message, + solution: err.solution, + details: err.details, + }, + true + ); } // All other errors - return { - content: [ - { - type: "text", - text: JSON.stringify(err), - }, - ], - structuredContent: err, - isError: true, - }; + return toToolResponse(err, true); } } ); diff --git a/src/utils/toolResponse.ts b/src/utils/toolResponse.ts new file mode 100644 index 0000000..4f97f5a --- /dev/null +++ b/src/utils/toolResponse.ts @@ -0,0 +1,28 @@ +import { CallToolResult } from "@modelcontextprotocol/sdk/types"; + +export const toToolResponse = ( + output: { + [key: string]: any; + }, + isError = false +): CallToolResult => { + try { + const outputString = JSON.stringify(output); + return { + content: [ + { + type: "text", + text: outputString, + }, + ], + structuredContent: output, + isError, + }; + } catch { + return { + content: [], + structuredContent: output, + isError, + }; + } +};