@kontent-ai/mcp-server 0.24.0 → 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 +7 -0
- package/build/schemas/searchOperationSchemas.js +5 -5
- package/build/schemas/workflowSchemas.js +74 -76
- package/build/server.js +8 -0
- package/build/tools/add-workflow-mapi.js +24 -0
- package/build/tools/change-variant-workflow-step-mapi.js +4 -6
- package/build/tools/delete-workflow-mapi.js +20 -0
- package/build/tools/list-roles-mapi.js +15 -0
- package/build/tools/update-workflow-mapi.js +32 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,9 +137,16 @@ npx @kontent-ai/mcp-server@latest shttp
|
|
|
137
137
|
* **patch-space-mapi** – Patch Kontent.ai space using replace operations
|
|
138
138
|
* **delete-space-mapi** – Delete Kontent.ai space
|
|
139
139
|
|
|
140
|
+
### Role Management
|
|
141
|
+
|
|
142
|
+
* **list-roles-mapi** – Get all Kontent.ai roles from Management API. Requires Enterprise or Flex plan with "Manage custom roles" permission
|
|
143
|
+
|
|
140
144
|
### Workflow Management
|
|
141
145
|
|
|
142
146
|
* **list-workflows-mapi** – Get all Kontent.ai workflows from Management API. Workflows define the content lifecycle stages and transitions between them
|
|
147
|
+
* **add-workflow-mapi** – Create a new Kontent.ai workflow via Management API. Define custom workflow steps, transitions, scopes (content types and collections), and role permissions
|
|
148
|
+
* **update-workflow-mapi** – Update an existing Kontent.ai workflow by ID via Management API. Modify steps, transitions, scopes, and role permissions. Cannot remove steps that are in use
|
|
149
|
+
* **delete-workflow-mapi** – Delete a Kontent.ai workflow by ID via Management API. The workflow must not be in use by any content items
|
|
143
150
|
* **change-variant-workflow-step-mapi** – Change the workflow step of a language variant in Kontent.ai. This operation moves a language variant to a different step in the workflow, enabling content lifecycle management such as moving content from draft to review, review to published, etc.
|
|
144
151
|
* **publish-variant-mapi** – Publish or schedule a language variant of a content item in Kontent.ai. This operation can either immediately publish the variant or schedule it for publication at a specific future date and time with optional timezone specification
|
|
145
152
|
* **unpublish-variant-mapi** – Unpublish or schedule unpublishing of a language variant of a content item in Kontent.ai. This operation can either immediately unpublish the variant (making it unavailable through the Delivery API) or schedule it for unpublishing at a specific future date and time with optional timezone specification
|
|
@@ -3,9 +3,9 @@ export const searchOperationSchema = z.object({
|
|
|
3
3
|
searchPhrase: z
|
|
4
4
|
.string()
|
|
5
5
|
.describe("Search phrase for AI-powered semantic search. Uses vector database to find content by meaning and similarity, not just exact keyword matching"),
|
|
6
|
-
filter: z
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
filter: z.object({
|
|
7
|
+
variantId: z
|
|
8
|
+
.guid()
|
|
9
|
+
.describe("Language ID from list-languages-mapi. Use default language (is_default=true) if not specified by user."),
|
|
10
|
+
}),
|
|
11
11
|
});
|
|
@@ -1,98 +1,96 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { referenceObjectSchema } from "./referenceObjectSchema.js";
|
|
3
|
+
// Step color options (matching SDK WorkflowColor type)
|
|
4
|
+
const workflowStepColorSchema = z
|
|
5
|
+
.enum([
|
|
6
|
+
"gray",
|
|
7
|
+
"red",
|
|
8
|
+
"rose",
|
|
9
|
+
"light-purple",
|
|
10
|
+
"dark-purple",
|
|
11
|
+
"dark-blue",
|
|
12
|
+
"light-blue",
|
|
13
|
+
"sky-blue",
|
|
14
|
+
"mint-green",
|
|
15
|
+
"persian-green",
|
|
16
|
+
"dark-green",
|
|
17
|
+
"light-green",
|
|
18
|
+
"yellow",
|
|
19
|
+
"pink",
|
|
20
|
+
"orange",
|
|
21
|
+
"brown",
|
|
22
|
+
])
|
|
23
|
+
.describe("Color of the workflow step displayed in the UI");
|
|
24
|
+
// Transition reference schema (step codename reference)
|
|
25
|
+
const transitionToStepSchema = z.object({
|
|
26
|
+
codename: z.string().optional().describe("Target step codename"),
|
|
27
|
+
id: z.guid().optional().describe("Target step ID (for update operations)"),
|
|
28
|
+
});
|
|
29
|
+
const transitionToSchema = z.object({
|
|
30
|
+
step: transitionToStepSchema.describe("Reference to the target step"),
|
|
31
|
+
});
|
|
32
|
+
// Workflow step input schema (for creating/updating workflows)
|
|
33
|
+
const workflowStepInputSchema = z.object({
|
|
34
|
+
name: z.string().describe("Human-readable name of the workflow step"),
|
|
8
35
|
codename: z
|
|
9
36
|
.string()
|
|
10
|
-
.describe("
|
|
37
|
+
.describe("Codename of the workflow step. Must be unique across all workflows - usually prepended with the workflow codename."),
|
|
38
|
+
id: z
|
|
39
|
+
.guid()
|
|
40
|
+
.optional()
|
|
41
|
+
.readonly()
|
|
42
|
+
.describe("Read-only workflow step ID (useful to reference a step when updating its codename)"),
|
|
43
|
+
color: workflowStepColorSchema,
|
|
11
44
|
transitions_to: z
|
|
12
|
-
.array(
|
|
13
|
-
.
|
|
14
|
-
.
|
|
45
|
+
.array(transitionToSchema)
|
|
46
|
+
.min(1)
|
|
47
|
+
.describe("Array of step references this step can transition to."),
|
|
15
48
|
role_ids: z
|
|
16
49
|
.array(z.guid())
|
|
17
|
-
.
|
|
18
|
-
.
|
|
50
|
+
.min(1)
|
|
51
|
+
.describe("Array of role IDs that have permissions for this step."),
|
|
19
52
|
});
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
id: z
|
|
23
|
-
.guid()
|
|
24
|
-
.describe("The unique identifier of the published step in UUID format"),
|
|
25
|
-
name: z
|
|
26
|
-
.string()
|
|
27
|
-
.describe("The name of the published step - typically 'Published'"),
|
|
28
|
-
codename: z
|
|
29
|
-
.string()
|
|
30
|
-
.describe("The codename of the published step - typically 'published'"),
|
|
53
|
+
// Published step input schema
|
|
54
|
+
const publishedStepInputSchema = z.object({
|
|
31
55
|
unpublish_role_ids: z
|
|
32
56
|
.array(z.guid())
|
|
33
|
-
.
|
|
34
|
-
.
|
|
57
|
+
.min(1)
|
|
58
|
+
.describe("Array of role IDs that can unpublish content."),
|
|
35
59
|
create_new_version_role_ids: z
|
|
36
60
|
.array(z.guid())
|
|
37
|
-
.
|
|
38
|
-
.
|
|
61
|
+
.min(1)
|
|
62
|
+
.describe("Array of role IDs that can create new versions."),
|
|
39
63
|
});
|
|
40
|
-
//
|
|
41
|
-
const
|
|
42
|
-
id: z
|
|
43
|
-
.guid()
|
|
44
|
-
.describe("The unique identifier of the scheduled step in UUID format"),
|
|
45
|
-
name: z
|
|
46
|
-
.string()
|
|
47
|
-
.describe("The name of the scheduled step - typically 'Scheduled'"),
|
|
48
|
-
codename: z
|
|
49
|
-
.string()
|
|
50
|
-
.describe("The codename of the scheduled step - typically 'scheduled'"),
|
|
51
|
-
});
|
|
52
|
-
// Schema for the archived step
|
|
53
|
-
const archivedStepSchema = z.object({
|
|
54
|
-
id: z
|
|
55
|
-
.guid()
|
|
56
|
-
.describe("The unique identifier of the archived step in UUID format"),
|
|
57
|
-
name: z
|
|
58
|
-
.string()
|
|
59
|
-
.describe("The name of the archived step - typically 'Archived'"),
|
|
60
|
-
codename: z
|
|
61
|
-
.string()
|
|
62
|
-
.describe("The codename of the archived step - typically 'archived'"),
|
|
64
|
+
// Archived step input schema
|
|
65
|
+
const archivedStepInputSchema = z.object({
|
|
63
66
|
role_ids: z
|
|
64
67
|
.array(z.guid())
|
|
65
|
-
.
|
|
66
|
-
.
|
|
68
|
+
.min(1)
|
|
69
|
+
.describe("Array of role IDs that can restore archived content."),
|
|
67
70
|
});
|
|
68
|
-
//
|
|
69
|
-
const
|
|
71
|
+
// Workflow scope input schema
|
|
72
|
+
const workflowScopeInputSchema = z.object({
|
|
70
73
|
content_types: z
|
|
71
|
-
.array(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.describe("
|
|
74
|
+
.array(referenceObjectSchema)
|
|
75
|
+
.describe("Content types this workflow applies to"),
|
|
76
|
+
collections: z
|
|
77
|
+
.array(referenceObjectSchema)
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("Collections this workflow applies to"),
|
|
77
80
|
});
|
|
78
|
-
// Main workflow schema
|
|
79
|
-
export const
|
|
80
|
-
|
|
81
|
-
name: z.string().describe("The human-readable name of the workflow"),
|
|
81
|
+
// Main add/update workflow schema
|
|
82
|
+
export const workflowInputSchema = z.object({
|
|
83
|
+
name: z.string().describe("Human-readable name of the workflow"),
|
|
82
84
|
codename: z
|
|
83
85
|
.string()
|
|
84
|
-
.
|
|
86
|
+
.optional()
|
|
87
|
+
.describe("Codename for API operations (auto-generated if omitted)"),
|
|
85
88
|
scopes: z
|
|
86
|
-
.array(
|
|
87
|
-
.describe("Array of scopes defining which content types
|
|
89
|
+
.array(workflowScopeInputSchema)
|
|
90
|
+
.describe("Array of scopes defining which combinations of content types and collections this workflow applies to. If both content types and collections are empty, the workflow can be used for any type of content in collection that isn't limited to any other workflow."),
|
|
88
91
|
steps: z
|
|
89
|
-
.array(
|
|
90
|
-
.describe("Array of custom workflow steps
|
|
91
|
-
published_step:
|
|
92
|
-
|
|
93
|
-
archived_step: archivedStepSchema.describe("The archived step configuration of the workflow"),
|
|
92
|
+
.array(workflowStepInputSchema)
|
|
93
|
+
.describe("Array of custom workflow steps"),
|
|
94
|
+
published_step: publishedStepInputSchema.describe("Configuration for the published step"),
|
|
95
|
+
archived_step: archivedStepInputSchema.describe("Configuration for the archived step"),
|
|
94
96
|
});
|
|
95
|
-
// Schema for the list workflows response
|
|
96
|
-
export const listWorkflowsResponseSchema = z
|
|
97
|
-
.array(workflowSchema)
|
|
98
|
-
.describe("Array of workflows in the project");
|
package/build/server.js
CHANGED
|
@@ -6,6 +6,7 @@ import { registerTool as registerAddContentTypeSnippetMapi } from "./tools/add-c
|
|
|
6
6
|
import { registerTool as registerAddLanguageMapi } from "./tools/add-language-mapi.js";
|
|
7
7
|
import { registerTool as registerAddSpaceMapi } from "./tools/add-space-mapi.js";
|
|
8
8
|
import { registerTool as registerAddTaxonomyGroupMapi } from "./tools/add-taxonomy-group-mapi.js";
|
|
9
|
+
import { registerTool as registerAddWorkflowMapi } from "./tools/add-workflow-mapi.js";
|
|
9
10
|
import { registerTool as registerChangeVariantWorkflowStepMapi } from "./tools/change-variant-workflow-step-mapi.js";
|
|
10
11
|
import { registerTool as registerCreateVariantVersionMapi } from "./tools/create-variant-version-mapi.js";
|
|
11
12
|
import { registerTool as registerDeleteContentItemMapi } from "./tools/delete-content-item-mapi.js";
|
|
@@ -14,6 +15,7 @@ import { registerTool as registerDeleteLanguageVariantMapi } from "./tools/delet
|
|
|
14
15
|
import { registerTool as registerDeleteSpaceMapi } from "./tools/delete-space-mapi.js";
|
|
15
16
|
import { registerTool as registerDeleteTaxonomyGroupMapi } from "./tools/delete-taxonomy-group-mapi.js";
|
|
16
17
|
import { registerTool as registerDeleteTypeSnippetMapi } from "./tools/delete-type-snippet-mapi.js";
|
|
18
|
+
import { registerTool as registerDeleteWorkflowMapi } from "./tools/delete-workflow-mapi.js";
|
|
17
19
|
import { registerTool as registerFilterVariantsMapi } from "./tools/filter-variants-mapi.js";
|
|
18
20
|
import { registerTool as registerGetAssetMapi } from "./tools/get-asset-mapi.js";
|
|
19
21
|
import { registerTool as registerGetItemMapi } from "./tools/get-item-mapi.js";
|
|
@@ -29,6 +31,7 @@ import { registerTool as registerListCollectionsMapi } from "./tools/list-collec
|
|
|
29
31
|
import { registerTool as registerListContentTypeSnippetsMapi } from "./tools/list-content-type-snippets-mapi.js";
|
|
30
32
|
import { registerTool as registerListContentTypesMapi } from "./tools/list-content-types-mapi.js";
|
|
31
33
|
import { registerTool as registerListLanguagesMapi } from "./tools/list-languages-mapi.js";
|
|
34
|
+
import { registerTool as registerListRolesMapi } from "./tools/list-roles-mapi.js";
|
|
32
35
|
import { registerTool as registerListSpacesMapi } from "./tools/list-spaces-mapi.js";
|
|
33
36
|
import { registerTool as registerListTaxonomyGroupsMapi } from "./tools/list-taxonomy-groups-mapi.js";
|
|
34
37
|
import { registerTool as registerListVariantsCollectionMapi } from "./tools/list-variants-collection-mapi.js";
|
|
@@ -49,6 +52,7 @@ import { registerTool as registerSearchVariantsMapi } from "./tools/search-varia
|
|
|
49
52
|
import { registerTool as registerUnpublishVariantMapi } from "./tools/unpublish-variant-mapi.js";
|
|
50
53
|
import { registerTool as registerUpdateAssetMapi } from "./tools/update-asset-mapi.js";
|
|
51
54
|
import { registerTool as registerUpdateContentItemMapi } from "./tools/update-content-item-mapi.js";
|
|
55
|
+
import { registerTool as registerUpdateWorkflowMapi } from "./tools/update-workflow-mapi.js";
|
|
52
56
|
import { registerTool as registerUpsertLanguageVariantMapi } from "./tools/upsert-language-variant-mapi.js";
|
|
53
57
|
// Create server instance
|
|
54
58
|
export const createServer = () => {
|
|
@@ -78,6 +82,7 @@ export const createServer = () => {
|
|
|
78
82
|
registerAddSpaceMapi(server);
|
|
79
83
|
registerPatchSpaceMapi(server);
|
|
80
84
|
registerDeleteSpaceMapi(server);
|
|
85
|
+
registerListRolesMapi(server);
|
|
81
86
|
registerGetAssetMapi(server);
|
|
82
87
|
registerListAssetsMapi(server);
|
|
83
88
|
registerUpdateAssetMapi(server);
|
|
@@ -102,6 +107,9 @@ export const createServer = () => {
|
|
|
102
107
|
registerCreateVariantVersionMapi(server);
|
|
103
108
|
registerDeleteLanguageVariantMapi(server);
|
|
104
109
|
registerListWorkflowsMapi(server);
|
|
110
|
+
registerAddWorkflowMapi(server);
|
|
111
|
+
registerUpdateWorkflowMapi(server);
|
|
112
|
+
registerDeleteWorkflowMapi(server);
|
|
105
113
|
registerChangeVariantWorkflowStepMapi(server);
|
|
106
114
|
registerFilterVariantsMapi(server);
|
|
107
115
|
registerSearchVariantsMapi(server);
|
|
@@ -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,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
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
3
|
+
import { workflowInputSchema } from "../schemas/workflowSchemas.js";
|
|
4
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
5
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
6
|
+
export const registerTool = (server) => {
|
|
7
|
+
server.tool("update-workflow-mapi", "Update Kontent.ai workflow", {
|
|
8
|
+
id: z.guid().describe("Workflow ID"),
|
|
9
|
+
...workflowInputSchema.shape,
|
|
10
|
+
}, async ({ id, name, codename, scopes, steps, published_step, archived_step }, { authInfo: { token, clientId } = {} }) => {
|
|
11
|
+
const client = createMapiClient(clientId, token);
|
|
12
|
+
const data = {
|
|
13
|
+
name,
|
|
14
|
+
codename,
|
|
15
|
+
scopes,
|
|
16
|
+
steps,
|
|
17
|
+
published_step,
|
|
18
|
+
archived_step,
|
|
19
|
+
};
|
|
20
|
+
try {
|
|
21
|
+
const response = await client
|
|
22
|
+
.updateWorkflow()
|
|
23
|
+
.byWorkflowId(id)
|
|
24
|
+
.withData(data)
|
|
25
|
+
.toPromise();
|
|
26
|
+
return createMcpToolSuccessResponse(response.rawData);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return handleMcpToolError(error, "Workflow Update");
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|