feat(mcps): add mutation tools for pages and posts to klz-payload-mcp

This commit is contained in:
2026-03-05 12:50:54 +01:00
parent 751ffd59a0
commit f0d1fb6647

View File

@@ -95,6 +95,84 @@ const GET_POST_TOOL: Tool = {
}, },
}; };
const CREATE_PAGE_TOOL: Tool = {
name: "payload_create_page",
description: "Create a new page in KLZ Payload CMS",
inputSchema: {
type: "object",
properties: {
title: { type: "string", description: "Page title" },
slug: { type: "string", description: "Page slug" },
data: { type: "object", description: "Additional page data (JSON)", additionalProperties: true }
},
required: ["title"]
},
};
const UPDATE_PAGE_TOOL: Tool = {
name: "payload_update_page",
description: "Update an existing page in KLZ Payload CMS",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Page ID to update" },
data: { type: "object", description: "Page data to update (JSON)", additionalProperties: true }
},
required: ["id", "data"]
},
};
const DELETE_PAGE_TOOL: Tool = {
name: "payload_delete_page",
description: "Delete a page from KLZ Payload CMS",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Page ID to delete" }
},
required: ["id"]
},
};
const CREATE_POST_TOOL: Tool = {
name: "payload_create_post",
description: "Create a new post in KLZ Payload CMS",
inputSchema: {
type: "object",
properties: {
title: { type: "string", description: "Post title" },
slug: { type: "string", description: "Post slug" },
data: { type: "object", description: "Additional post data (JSON)", additionalProperties: true }
},
required: ["title"]
},
};
const UPDATE_POST_TOOL: Tool = {
name: "payload_update_post",
description: "Update an existing post in KLZ Payload CMS",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Post ID to update" },
data: { type: "object", description: "Post data to update (JSON)", additionalProperties: true }
},
required: ["id", "data"]
},
};
const DELETE_POST_TOOL: Tool = {
name: "payload_delete_post",
description: "Delete a post from KLZ Payload CMS",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Post ID to delete" }
},
required: ["id"]
},
};
const server = new Server( const server = new Server(
{ name: "klz-payload-mcp", version: "1.0.0" }, { name: "klz-payload-mcp", version: "1.0.0" },
{ capabilities: { tools: {} } } { capabilities: { tools: {} } }
@@ -106,8 +184,14 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
LIST_LEADS_TOOL, LIST_LEADS_TOOL,
LIST_PAGES_TOOL, LIST_PAGES_TOOL,
GET_PAGE_TOOL, GET_PAGE_TOOL,
CREATE_PAGE_TOOL,
UPDATE_PAGE_TOOL,
DELETE_PAGE_TOOL,
LIST_POSTS_TOOL, LIST_POSTS_TOOL,
GET_POST_TOOL GET_POST_TOOL,
CREATE_POST_TOOL,
UPDATE_POST_TOOL,
DELETE_POST_TOOL
], ],
})); }));
@@ -151,7 +235,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
const res = await payloadClient.get('/pages', { params: { limit } }); const res = await payloadClient.get('/pages', { params: { limit } });
return { content: [{ type: "text", text: JSON.stringify(res.data.docs, null, 2) }] }; return { content: [{ type: "text", text: JSON.stringify(res.data.docs, null, 2) }] };
} catch (e: any) { } catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${e.message}` }] }; return { isError: true, content: [{ type: "text", text: `Error: ${e.response?.data?.errors?.[0]?.message || e.message}` }] };
} }
} }
@@ -160,14 +244,45 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
try { try {
if (id) { if (id) {
const res = await payloadClient.get(`/pages/${id}`); const res = await payloadClient.get(`/pages/${id}`);
return { content: [{ type: "text", text: JSON.stringify(res, null, 2) }] }; return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} else if (slug) { } else if (slug) {
const res = await payloadClient.get('/pages', { params: { where: { slug: { equals: slug } }, limit: 1 } }); const res = await payloadClient.get('/pages', { params: { where: { slug: { equals: slug } }, limit: 1 } });
return { content: [{ type: "text", text: JSON.stringify(res.data.docs[0] || {}, null, 2) }] }; return { content: [{ type: "text", text: JSON.stringify(res.data.docs[0] || {}, null, 2) }] };
} }
return { isError: true, content: [{ type: "text", text: "Error: must provide slug or id" }] }; return { isError: true, content: [{ type: "text", text: "Error: must provide slug or id" }] };
} catch (e: any) { } catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${e.message}` }] }; return { isError: true, content: [{ type: "text", text: `Error: ${e.response?.data?.errors?.[0]?.message || e.message}` }] };
}
}
if (request.params.name === "payload_create_page") {
const { title, slug, data = {} } = request.params.arguments as any;
try {
const payload = { title, slug, _status: 'draft', ...data };
const res = await payloadClient.post('/pages', payload);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${JSON.stringify(e.response?.data) || e.message}` }] };
}
}
if (request.params.name === "payload_update_page") {
const { id, data } = request.params.arguments as any;
try {
const res = await payloadClient.patch(`/pages/${id}`, data);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${JSON.stringify(e.response?.data) || e.message}` }] };
}
}
if (request.params.name === "payload_delete_page") {
const { id } = request.params.arguments as any;
try {
const res = await payloadClient.delete(`/pages/${id}`);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${JSON.stringify(e.response?.data) || e.message}` }] };
} }
} }
@@ -177,7 +292,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
const res = await payloadClient.get('/posts', { params: { limit, sort: '-createdAt' } }); const res = await payloadClient.get('/posts', { params: { limit, sort: '-createdAt' } });
return { content: [{ type: "text", text: JSON.stringify(res.data.docs, null, 2) }] }; return { content: [{ type: "text", text: JSON.stringify(res.data.docs, null, 2) }] };
} catch (e: any) { } catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${e.message}` }] }; return { isError: true, content: [{ type: "text", text: `Error: ${e.response?.data?.errors?.[0]?.message || e.message}` }] };
} }
} }
@@ -193,10 +308,42 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
} }
return { isError: true, content: [{ type: "text", text: "Error: must provide slug or id" }] }; return { isError: true, content: [{ type: "text", text: "Error: must provide slug or id" }] };
} catch (e: any) { } catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${e.message}` }] }; return { isError: true, content: [{ type: "text", text: `Error: ${e.response?.data?.errors?.[0]?.message || e.message}` }] };
} }
} }
if (request.params.name === "payload_create_post") {
const { title, slug, data = {} } = request.params.arguments as any;
try {
const payload = { title, slug, _status: 'draft', ...data };
const res = await payloadClient.post('/posts', payload);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${JSON.stringify(e.response?.data) || e.message}` }] };
}
}
if (request.params.name === "payload_update_post") {
const { id, data } = request.params.arguments as any;
try {
const res = await payloadClient.patch(`/posts/${id}`, data);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${JSON.stringify(e.response?.data) || e.message}` }] };
}
}
if (request.params.name === "payload_delete_post") {
const { id } = request.params.arguments as any;
try {
const res = await payloadClient.delete(`/posts/${id}`);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
} catch (e: any) {
return { isError: true, content: [{ type: "text", text: `Error: ${JSON.stringify(e.response?.data) || e.message}` }] };
}
}
throw new Error(`Unknown tool: ${request.params.name}`); throw new Error(`Unknown tool: ${request.params.name}`);
}); });