@kontent-ai/mcp-server 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,19 +19,13 @@ Kontent.ai MCP Server implements the Model Context Protocol to connect your Kont
19
19
 
20
20
  ## Table of Contents
21
21
 
22
- * [🔌 Quickstart](#-quickstart)
23
- * [🔑 Prerequisites](#-prerequisites)
24
- * [🛠 Setup Options](#-setup-options)
25
- * [🛠️ Available Tools](#️-available-tools)
26
- * [⚙️ Configuration](#️-configuration)
27
- * [🚀 Transport Options](#-transport-options)
28
- * [📟 STDIO Transport](#-stdio-transport)
29
- * [🌐 SSE Transport](#-sse-transport)
30
- * [💻 Development](#-development)
31
- * [🛠 Local Installation](#-local-installation)
32
- * [📂 Project Structure](#-project-structure)
33
- * [🔍 Debugging](#-debugging)
34
- * [License](#license)
22
+ - [ Key Features](#-key-features)
23
+ - [🔌 Quickstart](#-quickstart)
24
+ - [🛠️ Available Tools](#️-available-tools)
25
+ - [⚙️ Configuration](#️-configuration)
26
+ - [🚀 Transport Options](#-transport-options)
27
+ - [💻 Development](#-development)
28
+ - [License](#license)
35
29
 
36
30
  ## 🔌 Quickstart
37
31
 
@@ -86,7 +80,10 @@ npx @kontent-ai/mcp-server@latest sse
86
80
  * **get-item-dapi** – Get a content item by codename from Delivery API
87
81
  * **get-variant-mapi** – Get a language variant of a content item
88
82
  * **add-content-item-mapi** – Create a new content item (structure only)
83
+ * **update-content-item-mapi** – Update an existing content item by codename (name, collection)
84
+ * **delete-content-item-mapi** – Delete a content item by codename
89
85
  * **upsert-language-variant-mapi** – Create or update a language variant with content
86
+ * **delete-language-variant-mapi** – Delete a language variant of a content item
90
87
 
91
88
  ### Asset Management
92
89
 
@@ -168,6 +165,10 @@ npm run build
168
165
  # Start the server
169
166
  npm run start:sse # For SSE transport
170
167
  npm run start:stdio # For STDIO transport
168
+
169
+ # Start the server with automatic reloading (no need to build first)
170
+ npm run dev:sse # For SSE transport
171
+ npm run dev:stdio # For STDIO transport
171
172
  ```
172
173
 
173
174
  ### 📂 Project Structure
package/build/server.js CHANGED
@@ -4,6 +4,8 @@ import { registerTool as registerAddContentItemMapi } from "./tools/add-content-
4
4
  import { registerTool as registerAddContentTypeMapi } from "./tools/add-content-type-mapi.js";
5
5
  import { registerTool as registerAddContentTypeSnippetMapi } from "./tools/add-content-type-snippet-mapi.js";
6
6
  import { registerTool as registerAddTaxonomyGroupMapi } from "./tools/add-taxonomy-group-mapi.js";
7
+ import { registerTool as registerDeleteContentItemMapi } from "./tools/delete-content-item-mapi.js";
8
+ import { registerTool as registerDeleteLanguageVariantMapi } from "./tools/delete-language-variant-mapi.js";
7
9
  import { registerTool as registerGetAssetMapi } from "./tools/get-asset-mapi.js";
8
10
  import { registerTool as registerGetItemDapi } from "./tools/get-item-dapi.js";
9
11
  import { registerTool as registerGetItemMapi } from "./tools/get-item-mapi.js";
@@ -16,6 +18,7 @@ import { registerTool as registerListContentTypeSnippetsMapi } from "./tools/lis
16
18
  import { registerTool as registerListContentTypesMapi } from "./tools/list-content-types-mapi.js";
17
19
  import { registerTool as registerListLanguagesMapi } from "./tools/list-languages-mapi.js";
18
20
  import { registerTool as registerListTaxonomyGroupsMapi } from "./tools/list-taxonomy-groups-mapi.js";
21
+ import { registerTool as registerUpdateContentItemMapi } from "./tools/update-content-item-mapi.js";
19
22
  import { registerTool as registerUpsertLanguageVariantMapi } from "./tools/upsert-language-variant-mapi.js";
20
23
  // Create server instance
21
24
  export const createServer = () => {
@@ -44,6 +47,9 @@ export const createServer = () => {
44
47
  registerListTaxonomyGroupsMapi(server);
45
48
  registerGetTaxonomyGroupMapi(server);
46
49
  registerAddContentItemMapi(server);
50
+ registerUpdateContentItemMapi(server);
51
+ registerDeleteContentItemMapi(server);
47
52
  registerUpsertLanguageVariantMapi(server);
53
+ registerDeleteLanguageVariantMapi(server);
48
54
  return { server };
49
55
  };
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
5
+ export const registerTool = (server) => {
6
+ server.tool("delete-content-item-mapi", "Delete a content item by codename from Management API", {
7
+ codename: z.string().describe("Codename of the content item to delete"),
8
+ }, async ({ codename }) => {
9
+ const client = createMapiClient();
10
+ try {
11
+ const response = await client
12
+ .deleteContentItem()
13
+ .byItemCodename(codename)
14
+ .toPromise();
15
+ return createMcpToolSuccessResponse({
16
+ message: `Content item '${codename}' deleted successfully`,
17
+ deletedItem: response.data,
18
+ });
19
+ }
20
+ catch (error) {
21
+ return handleMcpToolError(error, "Content Item Deletion");
22
+ }
23
+ });
24
+ };
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
5
+ export const registerTool = (server) => {
6
+ server.tool("delete-language-variant-mapi", "Delete a language variant of a content item from Management API", {
7
+ itemCodename: z.string().describe("Codename of the content item"),
8
+ languageCodename: z
9
+ .string()
10
+ .describe("Codename of the language variant to delete"),
11
+ }, async ({ itemCodename, languageCodename }) => {
12
+ const client = createMapiClient();
13
+ try {
14
+ const response = await client
15
+ .deleteLanguageVariant()
16
+ .byItemCodename(itemCodename)
17
+ .byLanguageCodename(languageCodename)
18
+ .toPromise();
19
+ return createMcpToolSuccessResponse({
20
+ message: `Language variant '${languageCodename}' of content item '${itemCodename}' deleted successfully`,
21
+ deletedVariant: response.data,
22
+ });
23
+ }
24
+ catch (error) {
25
+ return handleMcpToolError(error, "Language Variant Deletion");
26
+ }
27
+ });
28
+ };
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
5
+ export const registerTool = (server) => {
6
+ server.tool("update-content-item-mapi", "Update an existing content item by codename via Management API. The content item must already exist - this tool will not create new items.", {
7
+ codename: z.string().describe("Codename of the content item to update"),
8
+ name: z
9
+ .string()
10
+ .min(1)
11
+ .max(200)
12
+ .optional()
13
+ .describe("New display name of the content item (1-200 characters, optional)"),
14
+ collection: z
15
+ .object({
16
+ id: z.string().optional(),
17
+ codename: z.string().optional(),
18
+ external_id: z.string().optional(),
19
+ })
20
+ .optional()
21
+ .describe("Reference to a collection by id, codename, or external_id (optional)"),
22
+ }, async ({ codename, name, collection }) => {
23
+ const client = createMapiClient();
24
+ try {
25
+ // First, verify the item exists by trying to get it
26
+ await client.viewContentItem().byItemCodename(codename).toPromise();
27
+ // If we get here, the item exists, so we can update it
28
+ const updateData = {};
29
+ if (name !== undefined) {
30
+ updateData.name = name;
31
+ }
32
+ if (collection !== undefined) {
33
+ updateData.collection = collection;
34
+ }
35
+ // If no update data is provided, return an error
36
+ if (Object.keys(updateData).length === 0) {
37
+ return {
38
+ content: [
39
+ {
40
+ type: "text",
41
+ text: "Update Content Item: No update data provided. At least one field (name or collection) must be specified.",
42
+ },
43
+ ],
44
+ isError: true,
45
+ };
46
+ }
47
+ const response = await client
48
+ .upsertContentItem()
49
+ .byItemCodename(codename)
50
+ .withData(updateData)
51
+ .toPromise();
52
+ return createMcpToolSuccessResponse({
53
+ message: `Content item '${codename}' updated successfully`,
54
+ updatedItem: response.rawData,
55
+ });
56
+ }
57
+ catch (error) {
58
+ // Check if the error is because the item doesn't exist
59
+ if (error?.response?.status === 404 ||
60
+ error?.message?.includes("not found")) {
61
+ return {
62
+ content: [
63
+ {
64
+ type: "text",
65
+ text: `Update Content Item: Content item with codename '${codename}' does not exist. Use add-content-item-mapi to create new items.`,
66
+ },
67
+ ],
68
+ isError: true,
69
+ };
70
+ }
71
+ return handleMcpToolError(error, "Content Item Update");
72
+ }
73
+ });
74
+ };
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@kontent-ai/mcp-server",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "rimraf build && tsc",
7
7
  "start:stdio": "node build/bin.js stdio",
8
8
  "start:sse": "node build/bin.js sse",
9
+ "dev:stdio": "tsx watch src/bin.ts stdio",
10
+ "dev:sse": "tsx watch src/bin.ts sse",
9
11
  "format": "cross-env node node_modules/@biomejs/biome/bin/biome ci ./ --config-path=./biome.json",
10
12
  "format:fix": "cross-env node node_modules/@biomejs/biome/bin/biome check ./ --fix --unsafe --config-path=./biome.json"
11
13
  },
@@ -32,6 +34,7 @@
32
34
  "@types/node": "^22.15.19",
33
35
  "cross-env": "^7.0.3",
34
36
  "rimraf": "^6.0.1",
37
+ "tsx": "^4.20.3",
35
38
  "typescript": "^5.8.3"
36
39
  }
37
40
  }