diff --git a/packages/klz-payload-mcp/src/index.ts b/packages/klz-payload-mcp/src/index.ts index ccac3f3..7aa4294 100644 --- a/packages/klz-payload-mcp/src/index.ts +++ b/packages/klz-payload-mcp/src/index.ts @@ -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( { name: "klz-payload-mcp", version: "1.0.0" }, { capabilities: { tools: {} } } @@ -106,8 +184,14 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({ LIST_LEADS_TOOL, LIST_PAGES_TOOL, GET_PAGE_TOOL, + CREATE_PAGE_TOOL, + UPDATE_PAGE_TOOL, + DELETE_PAGE_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 } }); return { content: [{ type: "text", text: JSON.stringify(res.data.docs, null, 2) }] }; } 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 { if (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) { 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 { isError: true, content: [{ type: "text", text: "Error: must provide slug or id" }] }; } 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' } }); return { content: [{ type: "text", text: JSON.stringify(res.data.docs, null, 2) }] }; } 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" }] }; } 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}`); });