Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 40 additions & 50 deletions src/tools/checkRenderStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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}`,
Expand All @@ -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
);
}
}
);
Expand Down
6 changes: 2 additions & 4 deletions src/tools/getRenderableItemDetails.ts
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -124,10 +125,7 @@ Follow-ups:
isDesign
);

return {
content: [{ type: "text", text: JSON.stringify(itemDetails) }],
structuredContent: { itemDetails },
};
return toToolResponse({ itemDetails });
}
);
}
6 changes: 2 additions & 4 deletions src/tools/listRenderableItems.ts
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -111,10 +112,7 @@ Follow-ups:
excludeProjects,
});

return {
content: [{ type: "text", text: JSON.stringify(items) }],
structuredContent: { items },
};
return toToolResponse({ items });
}
);
}
49 changes: 12 additions & 37 deletions src/tools/renderItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TemplateVariantNotFoundError,
} from "./errors";
import env from "../env";
import { toToolResponse } from "../utils/toolResponse";

export function registerRenderItem(server: McpServer) {
const Input = {
Expand Down Expand Up @@ -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);
}
}
);
Expand Down
28 changes: 28 additions & 0 deletions src/utils/toolResponse.ts
Original file line number Diff line number Diff line change
@@ -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,
};
}
};