@kontent-ai/mcp-server 0.23.3 → 0.25.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 +21 -2
- package/build/bin.js +1 -1
- package/build/schemas/assetFolderSchemas.js +44 -0
- package/build/schemas/assetSchemas.js +23 -0
- package/build/schemas/{contentTypeSchemas.js → contentTypeAndSnippetSchemas.js} +9 -10
- package/build/schemas/patchSchemas/baseTypeAndSnippetPatchSchemas.js +41 -0
- package/build/schemas/patchSchemas/contentTypePatchSchemas.js +4 -46
- package/build/schemas/patchSchemas/snippetPatchSchemas.js +22 -0
- package/build/schemas/patchSchemas/taxonomyPatchSchemas.js +67 -0
- package/build/schemas/searchOperationSchemas.js +5 -5
- package/build/schemas/spaceSchemas.js +30 -0
- package/build/schemas/workflowSchemas.js +74 -76
- package/build/server.js +28 -0
- package/build/telemetry/applicationInsights.js +1 -1
- package/build/tools/add-content-type-mapi.js +1 -1
- package/build/tools/add-content-type-snippet-mapi.js +1 -1
- package/build/tools/add-space-mapi.js +23 -0
- package/build/tools/add-workflow-mapi.js +24 -0
- package/build/tools/change-variant-workflow-step-mapi.js +4 -6
- package/build/tools/context/patch-guide-path-based.js +53 -0
- package/build/tools/context/patch-guide-property-based.js +42 -0
- package/build/tools/context/patch-guide-reference-based.js +86 -0
- package/build/tools/delete-space-mapi.js +20 -0
- package/build/tools/delete-taxonomy-group-mapi.js +20 -0
- package/build/tools/delete-type-snippet-mapi.js +23 -0
- package/build/tools/delete-workflow-mapi.js +20 -0
- package/build/tools/get-patch-guide.js +31 -3
- package/build/tools/get-taxonomy-group-mapi.js +2 -2
- package/build/tools/list-asset-folders-mapi.js +15 -0
- package/build/tools/list-roles-mapi.js +15 -0
- package/build/tools/list-spaces-mapi.js +1 -1
- package/build/tools/list-taxonomy-groups-mapi.js +1 -1
- package/build/tools/patch-asset-folders-mapi.js +25 -0
- package/build/tools/patch-content-type-mapi.js +10 -6
- package/build/tools/patch-space-mapi.js +28 -0
- package/build/tools/patch-taxonomy-group-mapi.js +28 -0
- package/build/tools/patch-type-snippet-mapi.js +30 -0
- package/build/tools/update-asset-mapi.js +24 -0
- package/build/tools/update-workflow-mapi.js +32 -0
- package/package.json +1 -1
- package/build/tools/context/patch-operations-guide.js +0 -58
package/build/server.js
CHANGED
|
@@ -4,12 +4,18 @@ 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 registerAddLanguageMapi } from "./tools/add-language-mapi.js";
|
|
7
|
+
import { registerTool as registerAddSpaceMapi } from "./tools/add-space-mapi.js";
|
|
7
8
|
import { registerTool as registerAddTaxonomyGroupMapi } from "./tools/add-taxonomy-group-mapi.js";
|
|
9
|
+
import { registerTool as registerAddWorkflowMapi } from "./tools/add-workflow-mapi.js";
|
|
8
10
|
import { registerTool as registerChangeVariantWorkflowStepMapi } from "./tools/change-variant-workflow-step-mapi.js";
|
|
9
11
|
import { registerTool as registerCreateVariantVersionMapi } from "./tools/create-variant-version-mapi.js";
|
|
10
12
|
import { registerTool as registerDeleteContentItemMapi } from "./tools/delete-content-item-mapi.js";
|
|
11
13
|
import { registerTool as registerDeleteContentTypeMapi } from "./tools/delete-content-type-mapi.js";
|
|
12
14
|
import { registerTool as registerDeleteLanguageVariantMapi } from "./tools/delete-language-variant-mapi.js";
|
|
15
|
+
import { registerTool as registerDeleteSpaceMapi } from "./tools/delete-space-mapi.js";
|
|
16
|
+
import { registerTool as registerDeleteTaxonomyGroupMapi } from "./tools/delete-taxonomy-group-mapi.js";
|
|
17
|
+
import { registerTool as registerDeleteTypeSnippetMapi } from "./tools/delete-type-snippet-mapi.js";
|
|
18
|
+
import { registerTool as registerDeleteWorkflowMapi } from "./tools/delete-workflow-mapi.js";
|
|
13
19
|
import { registerTool as registerFilterVariantsMapi } from "./tools/filter-variants-mapi.js";
|
|
14
20
|
import { registerTool as registerGetAssetMapi } from "./tools/get-asset-mapi.js";
|
|
15
21
|
import { registerTool as registerGetItemMapi } from "./tools/get-item-mapi.js";
|
|
@@ -19,11 +25,13 @@ import { registerTool as registerGetPublishedVariantMapi } from "./tools/get-pub
|
|
|
19
25
|
import { registerTool as registerGetTaxonomyGroupMapi } from "./tools/get-taxonomy-group-mapi.js";
|
|
20
26
|
import { registerTool as registerGetTypeMapi } from "./tools/get-type-mapi.js";
|
|
21
27
|
import { registerTool as registerGetTypeSnippetMapi } from "./tools/get-type-snippet-mapi.js";
|
|
28
|
+
import { registerTool as registerListAssetFoldersMapi } from "./tools/list-asset-folders-mapi.js";
|
|
22
29
|
import { registerTool as registerListAssetsMapi } from "./tools/list-assets-mapi.js";
|
|
23
30
|
import { registerTool as registerListCollectionsMapi } from "./tools/list-collections-mapi.js";
|
|
24
31
|
import { registerTool as registerListContentTypeSnippetsMapi } from "./tools/list-content-type-snippets-mapi.js";
|
|
25
32
|
import { registerTool as registerListContentTypesMapi } from "./tools/list-content-types-mapi.js";
|
|
26
33
|
import { registerTool as registerListLanguagesMapi } from "./tools/list-languages-mapi.js";
|
|
34
|
+
import { registerTool as registerListRolesMapi } from "./tools/list-roles-mapi.js";
|
|
27
35
|
import { registerTool as registerListSpacesMapi } from "./tools/list-spaces-mapi.js";
|
|
28
36
|
import { registerTool as registerListTaxonomyGroupsMapi } from "./tools/list-taxonomy-groups-mapi.js";
|
|
29
37
|
import { registerTool as registerListVariantsCollectionMapi } from "./tools/list-variants-collection-mapi.js";
|
|
@@ -32,13 +40,19 @@ import { registerTool as registerListVariantsItemMapi } from "./tools/list-varia
|
|
|
32
40
|
import { registerTool as registerListVariantsSpaceMapi } from "./tools/list-variants-space-mapi.js";
|
|
33
41
|
import { registerTool as registerListVariantsTypeMapi } from "./tools/list-variants-type-mapi.js";
|
|
34
42
|
import { registerTool as registerListWorkflowsMapi } from "./tools/list-workflows-mapi.js";
|
|
43
|
+
import { registerTool as registerPatchAssetFoldersMapi } from "./tools/patch-asset-folders-mapi.js";
|
|
35
44
|
import { registerTool as registerPatchCollectionsMapi } from "./tools/patch-collections-mapi.js";
|
|
36
45
|
import { registerTool as registerPatchContentTypeMapi } from "./tools/patch-content-type-mapi.js";
|
|
37
46
|
import { registerTool as registerPatchLanguageMapi } from "./tools/patch-language-mapi.js";
|
|
47
|
+
import { registerTool as registerPatchSpaceMapi } from "./tools/patch-space-mapi.js";
|
|
48
|
+
import { registerTool as registerPatchTaxonomyGroupMapi } from "./tools/patch-taxonomy-group-mapi.js";
|
|
49
|
+
import { registerTool as registerPatchTypeSnippetMapi } from "./tools/patch-type-snippet-mapi.js";
|
|
38
50
|
import { registerTool as registerPublishVariantMapi } from "./tools/publish-variant-mapi.js";
|
|
39
51
|
import { registerTool as registerSearchVariantsMapi } from "./tools/search-variants-mapi.js";
|
|
40
52
|
import { registerTool as registerUnpublishVariantMapi } from "./tools/unpublish-variant-mapi.js";
|
|
53
|
+
import { registerTool as registerUpdateAssetMapi } from "./tools/update-asset-mapi.js";
|
|
41
54
|
import { registerTool as registerUpdateContentItemMapi } from "./tools/update-content-item-mapi.js";
|
|
55
|
+
import { registerTool as registerUpdateWorkflowMapi } from "./tools/update-workflow-mapi.js";
|
|
42
56
|
import { registerTool as registerUpsertLanguageVariantMapi } from "./tools/upsert-language-variant-mapi.js";
|
|
43
57
|
// Create server instance
|
|
44
58
|
export const createServer = () => {
|
|
@@ -65,16 +79,27 @@ export const createServer = () => {
|
|
|
65
79
|
registerListCollectionsMapi(server);
|
|
66
80
|
registerPatchCollectionsMapi(server);
|
|
67
81
|
registerListSpacesMapi(server);
|
|
82
|
+
registerAddSpaceMapi(server);
|
|
83
|
+
registerPatchSpaceMapi(server);
|
|
84
|
+
registerDeleteSpaceMapi(server);
|
|
85
|
+
registerListRolesMapi(server);
|
|
68
86
|
registerGetAssetMapi(server);
|
|
69
87
|
registerListAssetsMapi(server);
|
|
88
|
+
registerUpdateAssetMapi(server);
|
|
89
|
+
registerListAssetFoldersMapi(server);
|
|
90
|
+
registerPatchAssetFoldersMapi(server);
|
|
70
91
|
registerAddContentTypeMapi(server);
|
|
71
92
|
registerPatchContentTypeMapi(server);
|
|
72
93
|
registerAddContentTypeSnippetMapi(server);
|
|
73
94
|
registerGetTypeSnippetMapi(server);
|
|
74
95
|
registerListContentTypeSnippetsMapi(server);
|
|
96
|
+
registerPatchTypeSnippetMapi(server);
|
|
97
|
+
registerDeleteTypeSnippetMapi(server);
|
|
75
98
|
registerAddTaxonomyGroupMapi(server);
|
|
76
99
|
registerListTaxonomyGroupsMapi(server);
|
|
77
100
|
registerGetTaxonomyGroupMapi(server);
|
|
101
|
+
registerPatchTaxonomyGroupMapi(server);
|
|
102
|
+
registerDeleteTaxonomyGroupMapi(server);
|
|
78
103
|
registerAddContentItemMapi(server);
|
|
79
104
|
registerUpdateContentItemMapi(server);
|
|
80
105
|
registerDeleteContentItemMapi(server);
|
|
@@ -82,6 +107,9 @@ export const createServer = () => {
|
|
|
82
107
|
registerCreateVariantVersionMapi(server);
|
|
83
108
|
registerDeleteLanguageVariantMapi(server);
|
|
84
109
|
registerListWorkflowsMapi(server);
|
|
110
|
+
registerAddWorkflowMapi(server);
|
|
111
|
+
registerUpdateWorkflowMapi(server);
|
|
112
|
+
registerDeleteWorkflowMapi(server);
|
|
85
113
|
registerChangeVariantWorkflowStepMapi(server);
|
|
86
114
|
registerFilterVariantsMapi(server);
|
|
87
115
|
registerSearchVariantsMapi(server);
|
|
@@ -156,6 +156,6 @@ export function initializeApplicationInsights() {
|
|
|
156
156
|
appInsights.defaultClient.addTelemetryProcessor(createTelemetryProcessor());
|
|
157
157
|
}
|
|
158
158
|
catch (error) {
|
|
159
|
-
console.
|
|
159
|
+
console.error("Failed to initialize Application Insights:", error);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { createMapiClient } from "../clients/kontentClients.js";
|
|
3
|
-
import { contentGroupSchema, elementSchema, } from "../schemas/
|
|
3
|
+
import { contentGroupSchema, elementSchema, } from "../schemas/contentTypeAndSnippetSchemas.js";
|
|
4
4
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
5
5
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
6
6
|
export const registerTool = (server) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { createMapiClient } from "../clients/kontentClients.js";
|
|
3
|
-
import { snippetElementSchema } from "../schemas/
|
|
3
|
+
import { snippetElementSchema } from "../schemas/contentTypeAndSnippetSchemas.js";
|
|
4
4
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
5
5
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
6
6
|
export const registerTool = (server) => {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
|
+
import { addSpaceSchema } from "../schemas/spaceSchemas.js";
|
|
3
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
4
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
|
+
export const registerTool = (server) => {
|
|
6
|
+
server.tool("add-space-mapi", "Add Kontent.ai space", addSpaceSchema.shape, async ({ name, codename, collections }, { authInfo: { token, clientId } = {} }) => {
|
|
7
|
+
const client = createMapiClient(clientId, token);
|
|
8
|
+
try {
|
|
9
|
+
const response = await client
|
|
10
|
+
.addSpace()
|
|
11
|
+
.withData({
|
|
12
|
+
name,
|
|
13
|
+
codename,
|
|
14
|
+
collections,
|
|
15
|
+
})
|
|
16
|
+
.toPromise();
|
|
17
|
+
return createMcpToolSuccessResponse(response.rawData);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return handleMcpToolError(error, "Space Creation");
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
|
+
import { workflowInputSchema } from "../schemas/workflowSchemas.js";
|
|
3
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
4
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
|
+
export const registerTool = (server) => {
|
|
6
|
+
server.tool("add-workflow-mapi", "Add new Kontent.ai workflow", workflowInputSchema.shape, async ({ name, codename, scopes, steps, published_step, archived_step }, { authInfo: { token, clientId } = {} }) => {
|
|
7
|
+
const client = createMapiClient(clientId, token);
|
|
8
|
+
const data = {
|
|
9
|
+
name,
|
|
10
|
+
codename,
|
|
11
|
+
scopes,
|
|
12
|
+
steps,
|
|
13
|
+
published_step,
|
|
14
|
+
archived_step,
|
|
15
|
+
};
|
|
16
|
+
try {
|
|
17
|
+
const response = await client.addWorkflow().withData(data).toPromise();
|
|
18
|
+
return createMcpToolSuccessResponse(response.rawData);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return handleMcpToolError(error, "Workflow Creation");
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -4,12 +4,10 @@ import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
|
4
4
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
5
|
export const registerTool = (server) => {
|
|
6
6
|
server.tool("change-variant-workflow-step-mapi", "Change Kontent.ai variant workflow step", {
|
|
7
|
-
itemId: z.guid().describe("Content item
|
|
8
|
-
languageId: z
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
workflowId: z.guid().describe("Workflow UUID"),
|
|
12
|
-
workflowStepId: z.guid().describe("Target workflow step UUID"),
|
|
7
|
+
itemId: z.guid().describe("Content item ID"),
|
|
8
|
+
languageId: z.guid().describe("Language variant ID"),
|
|
9
|
+
workflowId: z.guid().describe("Workflow ID"),
|
|
10
|
+
workflowStepId: z.guid().describe("Target workflow step ID"),
|
|
13
11
|
}, async ({ itemId, languageId, workflowId, workflowStepId }, { authInfo: { token, clientId } = {} }) => {
|
|
14
12
|
const client = createMapiClient(clientId, token);
|
|
15
13
|
try {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const pathBasedPatchGuide = `
|
|
2
|
+
# Patch Guide: Content Types & Snippets
|
|
3
|
+
|
|
4
|
+
## Addressing
|
|
5
|
+
Use JSON Pointer 'path' property with id:{uuid} format.
|
|
6
|
+
|
|
7
|
+
## Path Formats
|
|
8
|
+
- Element: /elements/id:{uuid}
|
|
9
|
+
- Element property: /elements/id:{uuid}/name
|
|
10
|
+
- Option: /elements/id:{uuid}/options/id:{uuid}
|
|
11
|
+
- Content group: /content_groups/id:{uuid}
|
|
12
|
+
- Array item: /elements/id:{uuid}/allowed_content_types/id:{uuid}
|
|
13
|
+
|
|
14
|
+
## Operations
|
|
15
|
+
|
|
16
|
+
**move** - Reorder elements/options/groups
|
|
17
|
+
\`\`\`json
|
|
18
|
+
{ "op": "move", "path": "/elements/id:{uuid}", "before": { "id": "{uuid}" } }
|
|
19
|
+
{ "op": "move", "path": "/elements/id:{uuid}", "after": { "id": "{uuid}" } }
|
|
20
|
+
\`\`\`
|
|
21
|
+
|
|
22
|
+
**addInto** - Add to arrays (elements, options, allowed_blocks, etc.)
|
|
23
|
+
\`\`\`json
|
|
24
|
+
{ "op": "addInto", "path": "/elements", "value": { "name": "Title", "type": "text", ... } }
|
|
25
|
+
{ "op": "addInto", "path": "/elements/id:{uuid}/allowed_content_types", "value": { "id": "{uuid}" } }
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
**remove** - Delete items
|
|
29
|
+
\`\`\`json
|
|
30
|
+
{ "op": "remove", "path": "/elements/id:{uuid}" }
|
|
31
|
+
{ "op": "remove", "path": "/elements/id:{uuid}/allowed_content_types/id:{uuid}" }
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
**replace** - Update primitives/objects
|
|
35
|
+
\`\`\`json
|
|
36
|
+
{ "op": "replace", "path": "/elements/id:{uuid}/name", "value": "New Name" }
|
|
37
|
+
{ "op": "replace", "path": "/elements/id:{uuid}/maximum_text_length", "value": { "value": 100, "applies_to": "characters" } }
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
- Use addInto/remove for arrays, replace for primitives/objects
|
|
42
|
+
- external_id and type cannot be modified after creation
|
|
43
|
+
- Empty arrays enable all options (allowed_blocks, allowed_formatting, etc.)
|
|
44
|
+
- 'unstyled' must be first when adding allowed_formatting
|
|
45
|
+
|
|
46
|
+
## Content Type Specifics
|
|
47
|
+
- Only one url_slug element allowed per content type
|
|
48
|
+
- To remove content groups: set ALL elements' content_group to null AND remove ALL groups in one request
|
|
49
|
+
- URL slug with snippet: add snippet element first, then url_slug with depends_on reference
|
|
50
|
+
|
|
51
|
+
## Snippet Specifics
|
|
52
|
+
- Cannot contain: content_groups, snippet, or url_slug elements
|
|
53
|
+
`;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const propertyBasedPatchGuide = `
|
|
2
|
+
# Patch Guide: Spaces & Languages
|
|
3
|
+
|
|
4
|
+
## Addressing
|
|
5
|
+
Use 'property_name' to specify which property to update. Only 'replace' operation is supported.
|
|
6
|
+
|
|
7
|
+
## Space Operations
|
|
8
|
+
|
|
9
|
+
**replace** - Update space properties
|
|
10
|
+
\`\`\`json
|
|
11
|
+
{ "op": "replace", "property_name": "name", "value": "New Space Name" }
|
|
12
|
+
{ "op": "replace", "property_name": "codename", "value": "new_codename" }
|
|
13
|
+
{ "op": "replace", "property_name": "collections", "value": [{ "id": "{uuid}" }, { "codename": "collection" }] }
|
|
14
|
+
\`\`\`
|
|
15
|
+
|
|
16
|
+
Available properties: name, codename, collections
|
|
17
|
+
|
|
18
|
+
## Language Operations
|
|
19
|
+
|
|
20
|
+
**replace** - Update language properties
|
|
21
|
+
\`\`\`json
|
|
22
|
+
{ "op": "replace", "property_name": "name", "value": "New Language Name" }
|
|
23
|
+
{ "op": "replace", "property_name": "codename", "value": "new_codename" }
|
|
24
|
+
{ "op": "replace", "property_name": "is_active", "value": true }
|
|
25
|
+
{ "op": "replace", "property_name": "fallback_language", "value": { "codename": "en-US" } }
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
Available properties: name, codename, is_active, fallback_language
|
|
29
|
+
|
|
30
|
+
## Critical Rule for Languages
|
|
31
|
+
If a language is deactivated, you must activate it first before making other changes:
|
|
32
|
+
\`\`\`json
|
|
33
|
+
[
|
|
34
|
+
{ "op": "replace", "property_name": "is_active", "value": true },
|
|
35
|
+
{ "op": "replace", "property_name": "name", "value": "New Name" }
|
|
36
|
+
]
|
|
37
|
+
\`\`\`
|
|
38
|
+
|
|
39
|
+
## General Rules
|
|
40
|
+
- external_id cannot be modified after creation
|
|
41
|
+
- Operations are applied in order
|
|
42
|
+
`;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export const referenceBasedPatchGuide = `
|
|
2
|
+
# Patch Guide: Taxonomy, Collections & Asset Folders
|
|
3
|
+
|
|
4
|
+
## Addressing
|
|
5
|
+
Use 'reference' objects: { id: "{uuid}" } or { codename: "codename" }
|
|
6
|
+
|
|
7
|
+
## Taxonomy Group Operations
|
|
8
|
+
|
|
9
|
+
**addInto** - Add terms
|
|
10
|
+
\`\`\`json
|
|
11
|
+
{ "op": "addInto", "value": { "name": "Term" } }
|
|
12
|
+
{ "op": "addInto", "reference": { "id": "{parent-uuid}" }, "value": { "name": "Child Term" } }
|
|
13
|
+
{ "op": "addInto", "value": { "name": "Term" }, "before": { "id": "{uuid}" } }
|
|
14
|
+
{ "op": "addInto", "value": { "name": "Term" }, "after": { "id": "{uuid}" } }
|
|
15
|
+
\`\`\`
|
|
16
|
+
|
|
17
|
+
**move** - Reorder or nest terms (before/after/under are mutually exclusive)
|
|
18
|
+
\`\`\`json
|
|
19
|
+
{ "op": "move", "reference": { "id": "{uuid}" }, "before": { "id": "{uuid}" } }
|
|
20
|
+
{ "op": "move", "reference": { "id": "{uuid}" }, "after": { "id": "{uuid}" } }
|
|
21
|
+
{ "op": "move", "reference": { "id": "{uuid}" }, "under": { "id": "{parent-uuid}" } }
|
|
22
|
+
\`\`\`
|
|
23
|
+
|
|
24
|
+
**remove** - Delete terms
|
|
25
|
+
\`\`\`json
|
|
26
|
+
{ "op": "remove", "reference": { "id": "{uuid}" } }
|
|
27
|
+
\`\`\`
|
|
28
|
+
|
|
29
|
+
**replace** - Update properties
|
|
30
|
+
\`\`\`json
|
|
31
|
+
{ "op": "replace", "property_name": "name", "value": "New Group Name" }
|
|
32
|
+
{ "op": "replace", "reference": { "id": "{uuid}" }, "property_name": "name", "value": "New Term Name" }
|
|
33
|
+
{ "op": "replace", "reference": { "id": "{uuid}" }, "property_name": "terms", "value": [] }
|
|
34
|
+
\`\`\`
|
|
35
|
+
|
|
36
|
+
## Collection Operations
|
|
37
|
+
|
|
38
|
+
**addInto** - Add collections
|
|
39
|
+
\`\`\`json
|
|
40
|
+
{ "op": "addInto", "value": { "name": "Collection", "codename": "collection" } }
|
|
41
|
+
{ "op": "addInto", "value": { "name": "Collection" }, "before": { "id": "{uuid}" } }
|
|
42
|
+
{ "op": "addInto", "value": { "name": "Collection" }, "after": { "id": "{uuid}" } }
|
|
43
|
+
\`\`\`
|
|
44
|
+
|
|
45
|
+
**move** - Reorder collections
|
|
46
|
+
\`\`\`json
|
|
47
|
+
{ "op": "move", "reference": { "id": "{uuid}" }, "before": { "id": "{uuid}" } }
|
|
48
|
+
{ "op": "move", "reference": { "id": "{uuid}" }, "after": { "id": "{uuid}" } }
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
**remove** - Delete empty collections only
|
|
52
|
+
\`\`\`json
|
|
53
|
+
{ "op": "remove", "reference": { "id": "{uuid}" } }
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
**replace** - Rename collections
|
|
57
|
+
\`\`\`json
|
|
58
|
+
{ "op": "replace", "reference": { "id": "{uuid}" }, "property_name": "name", "value": "New Name" }
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
## Asset Folder Operations
|
|
62
|
+
|
|
63
|
+
**addInto** - Add folders
|
|
64
|
+
\`\`\`json
|
|
65
|
+
{ "op": "addInto", "value": { "name": "Folder" } }
|
|
66
|
+
{ "op": "addInto", "reference": { "id": "{parent-uuid}" }, "value": { "name": "Subfolder" } }
|
|
67
|
+
{ "op": "addInto", "value": { "name": "Folder" }, "before": { "id": "{uuid}" } }
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
**rename** - Rename folders (not 'replace')
|
|
71
|
+
\`\`\`json
|
|
72
|
+
{ "op": "rename", "reference": { "id": "{uuid}" }, "value": "New Folder Name" }
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
**remove** - Delete folders
|
|
76
|
+
\`\`\`json
|
|
77
|
+
{ "op": "remove", "reference": { "id": "{uuid}" } }
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
Note: Asset folders do not support 'move' operation.
|
|
81
|
+
|
|
82
|
+
## General Rules
|
|
83
|
+
- Always fetch the entity first to get current IDs
|
|
84
|
+
- external_id cannot be modified after creation
|
|
85
|
+
- Operations are applied in order
|
|
86
|
+
`;
|
|
@@ -0,0 +1,20 @@
|
|
|
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-space-mapi", "Delete Kontent.ai space by ID", {
|
|
7
|
+
id: z.guid(),
|
|
8
|
+
}, async ({ id }, { authInfo: { token, clientId } = {} }) => {
|
|
9
|
+
const client = createMapiClient(clientId, token);
|
|
10
|
+
try {
|
|
11
|
+
await client.deleteSpace().bySpaceId(id).toPromise();
|
|
12
|
+
return createMcpToolSuccessResponse({
|
|
13
|
+
message: `Space '${id}' deleted successfully`,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return handleMcpToolError(error, "Space Deletion");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
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-taxonomy-group-mapi", "Delete Kontent.ai taxonomy group by ID", {
|
|
7
|
+
id: z.guid(),
|
|
8
|
+
}, async ({ id }, { authInfo: { token, clientId } = {} }) => {
|
|
9
|
+
const client = createMapiClient(clientId, token);
|
|
10
|
+
try {
|
|
11
|
+
await client.deleteTaxonomy().byTaxonomyId(id).toPromise();
|
|
12
|
+
return createMcpToolSuccessResponse({
|
|
13
|
+
message: `Taxonomy group '${id}' deleted successfully`,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return handleMcpToolError(error, "Taxonomy Group Deletion");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
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-type-snippet-mapi", "Delete Kontent.ai content type snippet by codename", {
|
|
7
|
+
codename: z.string(),
|
|
8
|
+
}, async ({ codename }, { authInfo: { token, clientId } = {} }) => {
|
|
9
|
+
const client = createMapiClient(clientId, token);
|
|
10
|
+
try {
|
|
11
|
+
await client
|
|
12
|
+
.deleteContentTypeSnippet()
|
|
13
|
+
.byTypeCodename(codename)
|
|
14
|
+
.toPromise();
|
|
15
|
+
return createMcpToolSuccessResponse({
|
|
16
|
+
message: `Content type snippet '${codename}' deleted successfully`,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return handleMcpToolError(error, "Content Type Snippet Deletion");
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
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-workflow-mapi", {
|
|
7
|
+
id: z.guid().describe("Workflow ID"),
|
|
8
|
+
}, async ({ id }, { authInfo: { token, clientId } = {} }) => {
|
|
9
|
+
const client = createMapiClient(clientId, token);
|
|
10
|
+
try {
|
|
11
|
+
await client.deleteWorkflow().byWorkflowId(id).toPromise();
|
|
12
|
+
return createMcpToolSuccessResponse({
|
|
13
|
+
message: `Workflow '${id}' deleted successfully`,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return handleMcpToolError(error, "Workflow Deletion");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -1,9 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
2
|
-
import {
|
|
3
|
+
import { pathBasedPatchGuide } from "./context/patch-guide-path-based.js";
|
|
4
|
+
import { propertyBasedPatchGuide } from "./context/patch-guide-property-based.js";
|
|
5
|
+
import { referenceBasedPatchGuide } from "./context/patch-guide-reference-based.js";
|
|
6
|
+
const entityTypeSchema = z.enum([
|
|
7
|
+
"content-type",
|
|
8
|
+
"snippet",
|
|
9
|
+
"taxonomy",
|
|
10
|
+
"collection",
|
|
11
|
+
"asset-folder",
|
|
12
|
+
"space",
|
|
13
|
+
"language",
|
|
14
|
+
]);
|
|
15
|
+
const getGuideForEntity = (entityType) => {
|
|
16
|
+
switch (entityType) {
|
|
17
|
+
case "content-type":
|
|
18
|
+
case "snippet":
|
|
19
|
+
return pathBasedPatchGuide;
|
|
20
|
+
case "taxonomy":
|
|
21
|
+
case "collection":
|
|
22
|
+
case "asset-folder":
|
|
23
|
+
return referenceBasedPatchGuide;
|
|
24
|
+
case "space":
|
|
25
|
+
case "language":
|
|
26
|
+
return propertyBasedPatchGuide;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
3
29
|
export const registerTool = (server) => {
|
|
4
|
-
server.tool("get-patch-guide", "REQUIRED before any patch operation. Get
|
|
30
|
+
server.tool("get-patch-guide", "REQUIRED before any patch operation. Get patch operations guide for Kontent.ai Management API.", {
|
|
31
|
+
entityType: entityTypeSchema.describe("Entity type to get patch guide for: content-type, snippet, taxonomy, collection, asset-folder, space, language"),
|
|
32
|
+
}, async ({ entityType }) => {
|
|
5
33
|
try {
|
|
6
|
-
return createMcpToolSuccessResponse(
|
|
34
|
+
return createMcpToolSuccessResponse(getGuideForEntity(entityType));
|
|
7
35
|
}
|
|
8
36
|
catch (error) {
|
|
9
37
|
throw new Error(`Failed to read patch guide: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -3,8 +3,8 @@ 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("get-taxonomy-group-mapi", "Get Kontent.ai taxonomy group.
|
|
7
|
-
id: z.
|
|
6
|
+
server.tool("get-taxonomy-group-mapi", "Get Kontent.ai taxonomy group. Taxonomy groups are hierarchical with tree-structured terms that can be nested to any depth for flexible content categorization.", {
|
|
7
|
+
id: z.guid(),
|
|
8
8
|
}, async ({ id }, { authInfo: { token, clientId } = {} }) => {
|
|
9
9
|
const client = createMapiClient(clientId, token);
|
|
10
10
|
try {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
3
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
4
|
+
export const registerTool = (server) => {
|
|
5
|
+
server.tool("list-asset-folders-mapi", "List all Kontent.ai asset folders", {}, async (_params, { authInfo: { token, clientId } = {} }) => {
|
|
6
|
+
const client = createMapiClient(clientId, token);
|
|
7
|
+
try {
|
|
8
|
+
const response = await client.listAssetFolders().toPromise();
|
|
9
|
+
return createMcpToolSuccessResponse(response.rawData);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
return handleMcpToolError(error, "Asset Folders Listing");
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
3
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
4
|
+
export const registerTool = (server) => {
|
|
5
|
+
server.tool("list-roles-mapi", "Get all Kontent.ai roles", {}, async (_, { authInfo: { token, clientId } = {} }) => {
|
|
6
|
+
const client = createMapiClient(clientId, token);
|
|
7
|
+
try {
|
|
8
|
+
const response = await client.listRoles().toPromise();
|
|
9
|
+
return createMcpToolSuccessResponse(response.rawData.roles);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
return handleMcpToolError(error, "Roles Listing");
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
@@ -2,7 +2,7 @@ import { createMapiClient } from "../clients/kontentClients.js";
|
|
|
2
2
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
3
3
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
4
4
|
export const registerTool = (server) => {
|
|
5
|
-
server.tool("list-spaces-mapi", "
|
|
5
|
+
server.tool("list-spaces-mapi", "List all Kontent.ai spaces. Spaces provide channel-specific context for managing multiple websites/channels. Each space has its own domain and preview URLs; collections connect to spaces to organize content per channel.", {}, async (_, { authInfo: { token, clientId } = {} }) => {
|
|
6
6
|
const client = createMapiClient(clientId, token);
|
|
7
7
|
try {
|
|
8
8
|
const response = await client.listSpaces().toPromise();
|
|
@@ -3,7 +3,7 @@ import { listTaxonomyGroupsSchema } from "../schemas/listSchemas.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("list-taxonomy-groups-mapi", "
|
|
6
|
+
server.tool("list-taxonomy-groups-mapi", "List all Kontent.ai taxonomy groups (paginated). Taxonomy groups are hierarchical with tree-structured terms that can be nested to any depth for flexible content categorization.", listTaxonomyGroupsSchema.shape, async ({ continuation_token }, { authInfo: { token, clientId } = {} }) => {
|
|
7
7
|
const client = createMapiClient(clientId, token);
|
|
8
8
|
try {
|
|
9
9
|
const query = client.listTaxonomies();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
|
+
import { assetFolderPatchOperationsSchema } from "../schemas/assetFolderSchemas.js";
|
|
3
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
4
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
|
+
export const registerTool = (server) => {
|
|
6
|
+
server.tool("patch-asset-folders-mapi", "Modify Kontent.ai asset folders using patch operations (addInto, rename, remove). Call get-patch-guide first for operations reference.", {
|
|
7
|
+
operations: assetFolderPatchOperationsSchema,
|
|
8
|
+
}, async ({ operations }, { authInfo: { token, clientId } = {} }) => {
|
|
9
|
+
const client = createMapiClient(clientId, token);
|
|
10
|
+
try {
|
|
11
|
+
const response = await client
|
|
12
|
+
.modifyAssetFolders()
|
|
13
|
+
.withData(operations)
|
|
14
|
+
.toPromise();
|
|
15
|
+
return createMcpToolSuccessResponse({
|
|
16
|
+
message: `Asset folders modified with ${operations.length} operation(s)`,
|
|
17
|
+
folders: response.rawData,
|
|
18
|
+
appliedOperations: operations,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return handleMcpToolError(error, "Asset Folders Modification");
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
};
|
|
@@ -4,20 +4,24 @@ import { patchOperationsSchema } from "../schemas/patchSchemas/contentTypePatchS
|
|
|
4
4
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
5
5
|
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
6
6
|
export const registerTool = (server) => {
|
|
7
|
-
server.tool("patch-content-type-mapi", "Update Kontent.ai content type using
|
|
8
|
-
|
|
9
|
-
operations: patchOperationsSchema.describe(
|
|
10
|
-
|
|
7
|
+
server.tool("patch-content-type-mapi", "Update Kontent.ai content type using patch operations. Call get-patch-guide first for operations reference.", {
|
|
8
|
+
id: z.guid(),
|
|
9
|
+
operations: patchOperationsSchema.describe(`Patch operations array. CRITICAL: Always call get-type-mapi first.
|
|
10
|
+
- Use addInto/remove for arrays, replace for primitives/objects
|
|
11
|
+
- Only one url_slug element allowed per content type
|
|
12
|
+
- To remove content groups: set ALL elements' content_group to null AND remove ALL groups in one request
|
|
13
|
+
- URL slug with snippet: add snippet element first, then url_slug with depends_on reference`),
|
|
14
|
+
}, async ({ id, operations }, { authInfo: { token, clientId } = {} }) => {
|
|
11
15
|
const client = createMapiClient(clientId, token);
|
|
12
16
|
try {
|
|
13
17
|
// Apply patch operations using the modifyContentType method
|
|
14
18
|
const response = await client
|
|
15
19
|
.modifyContentType()
|
|
16
|
-
.
|
|
20
|
+
.byTypeId(id)
|
|
17
21
|
.withData(operations)
|
|
18
22
|
.toPromise();
|
|
19
23
|
return createMcpToolSuccessResponse({
|
|
20
|
-
message: `Content type
|
|
24
|
+
message: `Content type updated successfully with ${operations.length} operation(s)`,
|
|
21
25
|
contentType: response.rawData,
|
|
22
26
|
appliedOperations: operations,
|
|
23
27
|
});
|