@kontent-ai/mcp-server 0.21.9 → 0.21.11
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 +30 -1
- package/build/bin.js +7 -0
- package/build/schemas/contentTypeSchemas.js +24 -61
- package/build/schemas/filterVariantSchemas.js +2 -0
- package/build/schemas/listSchemas.js +26 -0
- package/build/schemas/patchSchemas/contentTypePatchSchemas.js +12 -64
- package/build/schemas/referenceObjectSchema.js +3 -5
- package/build/schemas/taxonomySchemas.js +4 -9
- package/build/test/utils/responseHelper.spec.js +450 -0
- package/build/tools/add-content-item-mapi.js +6 -13
- package/build/tools/add-content-type-mapi.js +6 -11
- package/build/tools/add-content-type-snippet-mapi.js +5 -8
- package/build/tools/add-taxonomy-group-mapi.js +1 -1
- package/build/tools/change-variant-workflow-step-mapi.js +5 -14
- package/build/tools/context/initial-context.js +40 -1
- package/build/tools/context/patch-operations-guide.js +58 -0
- package/build/tools/create-variant-version-mapi.js +3 -6
- package/build/tools/delete-content-item-mapi.js +2 -2
- package/build/tools/delete-content-type-mapi.js +2 -2
- package/build/tools/delete-language-variant-mapi.js +3 -5
- package/build/tools/filter-variants-mapi.js +13 -20
- package/build/tools/get-asset-mapi.js +2 -2
- package/build/tools/get-initial-context.js +2 -1
- package/build/tools/get-item-mapi.js +2 -2
- package/build/tools/get-taxonomy-group-mapi.js +2 -2
- package/build/tools/get-type-mapi.js +2 -2
- package/build/tools/get-type-snippet-mapi.js +2 -2
- package/build/tools/get-variant-mapi.js +5 -7
- package/build/tools/list-assets-mapi.js +12 -4
- package/build/tools/list-content-type-snippets-mapi.js +12 -4
- package/build/tools/list-content-types-mapi.js +12 -4
- package/build/tools/list-languages-mapi.js +12 -4
- package/build/tools/list-taxonomy-groups-mapi.js +12 -4
- package/build/tools/list-workflows-mapi.js +1 -1
- package/build/tools/patch-content-type-mapi.js +3 -50
- package/build/tools/publish-variant-mapi.js +5 -8
- package/build/tools/search-variants-mapi.js +3 -29
- package/build/tools/unpublish-variant-mapi.js +5 -8
- package/build/tools/update-content-item-mapi.js +4 -4
- package/build/tools/upsert-language-variant-mapi.js +7 -10
- package/build/utils/responseHelper.js +90 -6
- package/package.json +4 -1
|
@@ -3,14 +3,14 @@ import { createMapiClient } from "../clients/kontentClients.js";
|
|
|
3
3
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
4
4
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
5
|
export const registerTool = (server) => {
|
|
6
|
-
server.tool("update-content-item-mapi", "Update
|
|
7
|
-
id: z.string().describe("
|
|
6
|
+
server.tool("update-content-item-mapi", "Update Kontent.ai content item", {
|
|
7
|
+
id: z.string().describe("Content item ID"),
|
|
8
8
|
name: z
|
|
9
9
|
.string()
|
|
10
10
|
.min(1)
|
|
11
11
|
.max(200)
|
|
12
12
|
.optional()
|
|
13
|
-
.describe("New
|
|
13
|
+
.describe("New name (1-200 chars)"),
|
|
14
14
|
collection: z
|
|
15
15
|
.object({
|
|
16
16
|
id: z.string().optional(),
|
|
@@ -18,7 +18,7 @@ export const registerTool = (server) => {
|
|
|
18
18
|
external_id: z.string().optional(),
|
|
19
19
|
})
|
|
20
20
|
.optional()
|
|
21
|
-
.describe("
|
|
21
|
+
.describe("Collection reference"),
|
|
22
22
|
}, async ({ id, name, collection }, { authInfo: { token, clientId } = {} }) => {
|
|
23
23
|
const client = createMapiClient(clientId, token);
|
|
24
24
|
try {
|
|
@@ -2,20 +2,17 @@ import { z } from "zod";
|
|
|
2
2
|
import { createMapiClient } from "../clients/kontentClients.js";
|
|
3
3
|
import { languageVariantElementSchema } from "../schemas/contentItemSchemas.js";
|
|
4
4
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createVariantMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
6
6
|
export const registerTool = (server) => {
|
|
7
|
-
server.tool("upsert-language-variant-mapi", "Create or update Kontent.ai
|
|
8
|
-
itemId: z.string().describe("
|
|
7
|
+
server.tool("upsert-language-variant-mapi", "Create or update Kontent.ai variant", {
|
|
8
|
+
itemId: z.string().describe("Content item ID"),
|
|
9
9
|
languageId: z
|
|
10
10
|
.string()
|
|
11
|
-
.describe("
|
|
11
|
+
.describe("Language variant ID (default: 00000000-0000-0000-0000-000000000000)"),
|
|
12
12
|
elements: z
|
|
13
13
|
.array(languageVariantElementSchema)
|
|
14
|
-
.describe("
|
|
15
|
-
workflow_step_id: z
|
|
16
|
-
.string()
|
|
17
|
-
.optional()
|
|
18
|
-
.describe("Internal ID of the workflow step (optional)"),
|
|
14
|
+
.describe("Content elements array"),
|
|
15
|
+
workflow_step_id: z.string().optional().describe("Workflow step ID"),
|
|
19
16
|
}, async ({ itemId, languageId, elements, workflow_step_id }, { authInfo: { token, clientId } = {} }) => {
|
|
20
17
|
const client = createMapiClient(clientId, token);
|
|
21
18
|
const data = {
|
|
@@ -31,7 +28,7 @@ export const registerTool = (server) => {
|
|
|
31
28
|
.byLanguageId(languageId)
|
|
32
29
|
.withData(() => data)
|
|
33
30
|
.toPromise();
|
|
34
|
-
return
|
|
31
|
+
return createVariantMcpToolSuccessResponse(response.rawData);
|
|
35
32
|
}
|
|
36
33
|
catch (error) {
|
|
37
34
|
return handleMcpToolError(error, "Language Variant Upsert");
|
|
@@ -1,17 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Utility for creating standardized MCP tool success responses
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export function isEmptyOrDefault(value) {
|
|
5
|
+
if (value === null || value === undefined) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "string" && value === "") {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "string" && value === "<p><br/></p>") {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (typeof value === "object" &&
|
|
18
|
+
!Array.isArray(value) &&
|
|
19
|
+
!(value instanceof Date) &&
|
|
20
|
+
!(value instanceof Function) &&
|
|
21
|
+
Object.keys(value).length === 0) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
export function removeEmptyElementsFromVariant(obj) {
|
|
27
|
+
if (obj === null || obj === undefined || typeof obj !== "object") {
|
|
28
|
+
return obj;
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(obj)) {
|
|
31
|
+
return obj.map((item) => removeEmptyElementsFromVariant(item));
|
|
32
|
+
}
|
|
33
|
+
const result = {};
|
|
34
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
35
|
+
if (key === "elements" && Array.isArray(value)) {
|
|
36
|
+
const filteredElements = value
|
|
37
|
+
.filter((element) => {
|
|
38
|
+
if (typeof element !== "object" || element === null) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
const keys = Object.keys(element);
|
|
42
|
+
return !(keys.length === 1 && keys[0] === "element");
|
|
43
|
+
})
|
|
44
|
+
.map((element) => removeEmptyElementsFromVariant(element));
|
|
45
|
+
if (filteredElements.length > 0) {
|
|
46
|
+
result[key] = filteredElements;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const processedValue = removeEmptyElementsFromVariant(value);
|
|
51
|
+
if (processedValue !== undefined) {
|
|
52
|
+
result[key] = processedValue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
export function removeEmptyValues(obj) {
|
|
59
|
+
if (obj === null || obj === undefined) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
if (typeof obj !== "object") {
|
|
63
|
+
return isEmptyOrDefault(obj) ? undefined : obj;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(obj)) {
|
|
66
|
+
const cleaned = obj
|
|
67
|
+
.map((item) => removeEmptyValues(item))
|
|
68
|
+
.filter((item) => item !== undefined);
|
|
69
|
+
return cleaned.length === 0 ? undefined : cleaned;
|
|
70
|
+
}
|
|
71
|
+
const cleaned = {};
|
|
72
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
73
|
+
const cleanedValue = removeEmptyValues(value);
|
|
74
|
+
if (cleanedValue !== undefined) {
|
|
75
|
+
cleaned[key] = cleanedValue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const keys = Object.keys(cleaned);
|
|
79
|
+
return keys.length === 0 ? undefined : cleaned;
|
|
80
|
+
}
|
|
9
81
|
export const createMcpToolSuccessResponse = (data) => {
|
|
10
82
|
return {
|
|
11
83
|
content: [
|
|
12
84
|
{
|
|
13
85
|
type: "text",
|
|
14
|
-
text: JSON.stringify(data),
|
|
86
|
+
text: JSON.stringify(removeEmptyValues(data)),
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
export const createVariantMcpToolSuccessResponse = (data) => {
|
|
92
|
+
const cleaned = removeEmptyValues(data);
|
|
93
|
+
const optimized = removeEmptyElementsFromVariant(cleaned);
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: JSON.stringify(optimized),
|
|
15
99
|
},
|
|
16
100
|
],
|
|
17
101
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontent-ai/mcp-server",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"mcpName": "io.github.kontent-ai/mcp-server",
|
|
6
6
|
"scripts": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dev:shttp": "tsx watch src/bin.ts shttp",
|
|
12
12
|
"format": "cross-env biome ci",
|
|
13
13
|
"format:fix": "cross-env biome check --fix --unsafe",
|
|
14
|
+
"test": "npm run build && mocha --timeout 10s -- \"build/test/**/*.spec.js\"",
|
|
14
15
|
"sync-version": "node --experimental-strip-types scripts/syncVersion.ts",
|
|
15
16
|
"version": "npm run sync-version sync && npm run format:fix -- server.json && git add server.json"
|
|
16
17
|
},
|
|
@@ -35,8 +36,10 @@
|
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@biomejs/biome": "^2.0.5",
|
|
37
38
|
"@types/express": "^5.0.2",
|
|
39
|
+
"@types/mocha": "^10.0.10",
|
|
38
40
|
"@types/node": "^22.15.19",
|
|
39
41
|
"cross-env": "^7.0.3",
|
|
42
|
+
"mocha": "^11.7.5",
|
|
40
43
|
"rimraf": "^6.0.1",
|
|
41
44
|
"tsx": "^4.20.3",
|
|
42
45
|
"typescript": "^5.8.3"
|