@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 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
- .object({
8
- variantId: z.guid().describe("UUID of the language variant to filter by"),
9
- })
10
- .describe("Mandatory content item variant filter to restrict search scope. Must specify a valid variant UUID"),
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
- // Schema for a workflow step
3
- const workflowStepSchema = z.object({
4
- id: z
5
- .guid()
6
- .describe("The unique identifier of the workflow step in UUID format"),
7
- name: z.string().describe("The human-readable name of the workflow step"),
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("The codename of the workflow step used for API operations"),
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(z.guid())
13
- .describe("Array of workflow step IDs that this step can transition to")
14
- .optional(),
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
- .describe("Array of role IDs that have permissions for this workflow step")
18
- .optional(),
50
+ .min(1)
51
+ .describe("Array of role IDs that have permissions for this step."),
19
52
  });
20
- // Schema for the published step
21
- const publishedStepSchema = z.object({
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
- .describe("Array of role IDs that can unpublish content from this step")
34
- .optional(),
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
- .describe("Array of role IDs that can create new versions of content in this step")
38
- .optional(),
61
+ .min(1)
62
+ .describe("Array of role IDs that can create new versions."),
39
63
  });
40
- // Schema for the scheduled step
41
- const scheduledStepSchema = z.object({
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
- .describe("Array of role IDs that can unarchive content from this step")
66
- .optional(),
68
+ .min(1)
69
+ .describe("Array of role IDs that can restore archived content."),
67
70
  });
68
- // Schema for workflow scope
69
- const workflowScopeSchema = z.object({
71
+ // Workflow scope input schema
72
+ const workflowScopeInputSchema = z.object({
70
73
  content_types: z
71
- .array(z.object({
72
- id: z
73
- .guid()
74
- .describe("The unique identifier of the content type in UUID format"),
75
- }))
76
- .describe("Array of content types that this workflow applies to"),
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 workflowSchema = z.object({
80
- id: z.guid().describe("The unique identifier of the workflow in UUID format"),
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
- .describe("The codename of the workflow used for API operations"),
86
+ .optional()
87
+ .describe("Codename for API operations (auto-generated if omitted)"),
85
88
  scopes: z
86
- .array(workflowScopeSchema)
87
- .describe("Array of scopes defining which content types use this workflow"),
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(workflowStepSchema)
90
- .describe("Array of custom workflow steps between draft and published states"),
91
- published_step: publishedStepSchema.describe("The published step configuration of the workflow"),
92
- scheduled_step: scheduledStepSchema.describe("The scheduled step configuration of the workflow"),
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 UUID"),
8
- languageId: z
9
- .guid()
10
- .describe("Language variant UUID (default: 00000000-0000-0000-0000-000000000000)"),
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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontent-ai/mcp-server",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "type": "module",
5
5
  "mcpName": "io.github.kontent-ai/mcp-server",
6
6
  "repository": {