@kontent-ai/mcp-server 0.31.0 → 0.33.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.
Files changed (119) hide show
  1. package/README.md +57 -61
  2. package/build/schemas/bulkGetItemsWithVariantsSchemas.js +1 -1
  3. package/build/schemas/contentItemSchemas.js +1 -1
  4. package/build/schemas/filterVariantSchemas.js +8 -3
  5. package/build/schemas/searchOperationSchemas.js +2 -1
  6. package/build/server.js +4 -112
  7. package/build/test/bm25/bm25.js +47 -0
  8. package/build/test/bm25/toolSearchBm25.spec.js +874 -0
  9. package/build/tools/bulk-get-content-item-variants.js +31 -0
  10. package/build/tools/change-content-item-variant-workflow-step.js +35 -0
  11. package/build/tools/create-content-item-variant.js +44 -0
  12. package/build/tools/create-content-item.js +47 -0
  13. package/build/tools/create-content-type-snippet.js +34 -0
  14. package/build/tools/create-content-type.js +37 -0
  15. package/build/tools/create-language.js +24 -0
  16. package/build/tools/create-new-content-item-variant-version.js +27 -0
  17. package/build/tools/create-space.js +22 -0
  18. package/build/tools/create-taxonomy-group.js +18 -0
  19. package/build/tools/create-workflow.js +23 -0
  20. package/build/tools/delete-content-item-variant.js +25 -0
  21. package/build/tools/delete-content-item.js +23 -0
  22. package/build/tools/delete-content-type-snippet.js +19 -0
  23. package/build/tools/delete-content-type.js +23 -0
  24. package/build/tools/delete-space.js +19 -0
  25. package/build/tools/delete-taxonomy-group.js +19 -0
  26. package/build/tools/delete-workflow.js +19 -0
  27. package/build/tools/get-asset.js +17 -0
  28. package/build/tools/get-content-item-translations.js +20 -0
  29. package/build/tools/get-content-item-variant.js +22 -0
  30. package/build/tools/get-content-item.js +17 -0
  31. package/build/tools/get-content-type-snippet.js +20 -0
  32. package/build/tools/get-content-type.js +17 -0
  33. package/build/tools/get-patch-guide.js +12 -12
  34. package/build/tools/get-published-content-item-variant-version.js +23 -0
  35. package/build/tools/get-taxonomy-group.js +17 -0
  36. package/build/tools/index.js +106 -0
  37. package/build/tools/list-asset-folders.js +14 -0
  38. package/build/tools/list-assets.js +23 -0
  39. package/build/tools/list-collections.js +14 -0
  40. package/build/tools/list-content-item-variants.js +50 -0
  41. package/build/tools/list-content-type-snippets.js +23 -0
  42. package/build/tools/list-content-types.js +23 -0
  43. package/build/tools/list-languages.js +24 -0
  44. package/build/tools/list-roles.js +14 -0
  45. package/build/tools/list-spaces.js +14 -0
  46. package/build/tools/list-taxonomy-groups.js +23 -0
  47. package/build/tools/list-workflows.js +14 -0
  48. package/build/tools/patch-asset-folders.js +25 -0
  49. package/build/tools/patch-collections.js +25 -0
  50. package/build/tools/patch-content-type-snippet.js +30 -0
  51. package/build/tools/patch-content-type.js +33 -0
  52. package/build/tools/patch-language.js +24 -0
  53. package/build/tools/patch-space.js +28 -0
  54. package/build/tools/patch-taxonomy-group.js +28 -0
  55. package/build/tools/publish-content-item-variant.js +72 -0
  56. package/build/tools/referencedToolNames.js +10 -0
  57. package/build/tools/search-content-item-variants.js +108 -0
  58. package/build/tools/toolDefinition.js +1 -0
  59. package/build/tools/unpublish-content-item-variant.js +72 -0
  60. package/build/tools/update-asset.js +23 -0
  61. package/build/tools/update-content-item-variant.js +36 -0
  62. package/build/tools/update-content-item.js +74 -0
  63. package/build/tools/update-workflow.js +31 -0
  64. package/package.json +18 -17
  65. package/build/tools/add-content-item-mapi.js +0 -47
  66. package/build/tools/add-content-type-mapi.js +0 -38
  67. package/build/tools/add-content-type-snippet-mapi.js +0 -35
  68. package/build/tools/add-language-mapi.js +0 -25
  69. package/build/tools/add-space-mapi.js +0 -23
  70. package/build/tools/add-taxonomy-group-mapi.js +0 -19
  71. package/build/tools/add-workflow-mapi.js +0 -24
  72. package/build/tools/bulk-get-items-variants-mapi.js +0 -31
  73. package/build/tools/change-variant-workflow-step-mapi.js +0 -36
  74. package/build/tools/create-language-variant-mapi.js +0 -44
  75. package/build/tools/create-variant-version-mapi.js +0 -28
  76. package/build/tools/delete-content-item-mapi.js +0 -24
  77. package/build/tools/delete-content-type-mapi.js +0 -24
  78. package/build/tools/delete-language-variant-mapi.js +0 -26
  79. package/build/tools/delete-space-mapi.js +0 -20
  80. package/build/tools/delete-taxonomy-group-mapi.js +0 -20
  81. package/build/tools/delete-type-snippet-mapi.js +0 -23
  82. package/build/tools/delete-workflow-mapi.js +0 -20
  83. package/build/tools/filter-variants-mapi.js +0 -49
  84. package/build/tools/get-asset-mapi.js +0 -21
  85. package/build/tools/get-item-mapi.js +0 -21
  86. package/build/tools/get-latest-variant-mapi.js +0 -23
  87. package/build/tools/get-published-variant-mapi.js +0 -24
  88. package/build/tools/get-taxonomy-group-mapi.js +0 -21
  89. package/build/tools/get-type-mapi.js +0 -21
  90. package/build/tools/get-type-snippet-mapi.js +0 -21
  91. package/build/tools/list-asset-folders-mapi.js +0 -15
  92. package/build/tools/list-assets-mapi.js +0 -24
  93. package/build/tools/list-collections-mapi.js +0 -15
  94. package/build/tools/list-content-type-snippets-mapi.js +0 -24
  95. package/build/tools/list-content-types-mapi.js +0 -24
  96. package/build/tools/list-languages-mapi.js +0 -24
  97. package/build/tools/list-roles-mapi.js +0 -15
  98. package/build/tools/list-spaces-mapi.js +0 -15
  99. package/build/tools/list-taxonomy-groups-mapi.js +0 -24
  100. package/build/tools/list-variants-collection-mapi.js +0 -26
  101. package/build/tools/list-variants-components-type-mapi.js +0 -26
  102. package/build/tools/list-variants-item-mapi.js +0 -21
  103. package/build/tools/list-variants-space-mapi.js +0 -24
  104. package/build/tools/list-variants-type-mapi.js +0 -26
  105. package/build/tools/list-workflows-mapi.js +0 -15
  106. package/build/tools/patch-asset-folders-mapi.js +0 -25
  107. package/build/tools/patch-collections-mapi.js +0 -25
  108. package/build/tools/patch-content-type-mapi.js +0 -33
  109. package/build/tools/patch-language-mapi.js +0 -24
  110. package/build/tools/patch-space-mapi.js +0 -28
  111. package/build/tools/patch-taxonomy-group-mapi.js +0 -28
  112. package/build/tools/patch-type-snippet-mapi.js +0 -30
  113. package/build/tools/publish-variant-mapi.js +0 -73
  114. package/build/tools/search-variants-mapi.js +0 -108
  115. package/build/tools/unpublish-variant-mapi.js +0 -73
  116. package/build/tools/update-asset-mapi.js +0 -24
  117. package/build/tools/update-content-item-mapi.js +0 -74
  118. package/build/tools/update-language-variant-mapi.js +0 -37
  119. package/build/tools/update-workflow-mapi.js +0 -32
@@ -1,108 +0,0 @@
1
- import pRetry, { AbortError } from "p-retry";
2
- import { createMapiClient } from "../clients/kontentClients.js";
3
- import { searchOperationSchema } from "../schemas/searchOperationSchemas.js";
4
- import { handleMcpToolError } from "../utils/errorHandler.js";
5
- import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
6
- import { throwError } from "../utils/throwError.js";
7
- class OperationResultIncompleteError extends Error {
8
- constructor() {
9
- super("AI operation result is incomplete");
10
- this.name = "OperationResultIncompleteError";
11
- }
12
- }
13
- const isSearchResponseWrapper = (value) => typeof value === "object" && value !== null && "searchResults" in value;
14
- const extractSearchResults = (response) => {
15
- const value = response.result?.value;
16
- if (!value) {
17
- return {};
18
- }
19
- const parsed = JSON.parse(value);
20
- if (isSearchResponseWrapper(parsed)) {
21
- return JSON.parse(parsed.searchResults);
22
- }
23
- return parsed;
24
- };
25
- export const registerTool = (server) => {
26
- server.tool("search-variants-mapi", "AI semantic search for Kontent.ai content by topic/theme (max 50 results). Use filter-variants-mapi for exact keywords. May be unavailable.", searchOperationSchema.shape, async ({ searchPhrase, filter }, { authInfo: { token, clientId } = {} }) => {
27
- try {
28
- const environmentId = clientId ?? process.env.KONTENT_ENVIRONMENT_ID;
29
- if (!environmentId) {
30
- throwError("Missing required environment ID");
31
- }
32
- const client = createMapiClient(environmentId, token);
33
- // Step 1: Initiate the AI search operation
34
- const searchPayload = {
35
- actionName: "Search",
36
- type: "multiple-inputs-request-v1",
37
- inputs: {
38
- searchPhrase: {
39
- type: "string",
40
- value: searchPhrase,
41
- },
42
- filter: {
43
- type: "content-item-variant-filter",
44
- value: filter,
45
- },
46
- },
47
- trackingData: {
48
- type: "empty-operation-tracking-data-v1",
49
- },
50
- };
51
- let searchResponse;
52
- try {
53
- searchResponse = await client
54
- .post()
55
- .withAction(`projects/${environmentId}/early-access/ai-operation`)
56
- .withData(searchPayload)
57
- .toPromise();
58
- }
59
- catch (error) {
60
- if (error?.response?.status === 403 &&
61
- error?.response?.data?.message?.includes("AI Feature Not Available")) {
62
- return createMcpToolSuccessResponse({
63
- status: "unavailable",
64
- result: `AI search feature is not available for environment ${clientId}`,
65
- });
66
- }
67
- throw error;
68
- }
69
- const operationData = searchResponse.data;
70
- const operationId = operationData.operationId;
71
- // Step 2: Poll for results with exponential backoff
72
- const resultData = await pRetry(async () => {
73
- try {
74
- const pollResponse = await client
75
- .get()
76
- .withAction(`projects/${environmentId}/early-access/ai-operation-result/${operationId}`)
77
- .toPromise();
78
- const [response] = pollResponse.data;
79
- if (response.type === "cumulated-result-v1" &&
80
- !response.result?.isFinished) {
81
- throw new OperationResultIncompleteError();
82
- }
83
- return response;
84
- }
85
- catch (error) {
86
- if (error?.response?.status === 404 ||
87
- error instanceof OperationResultIncompleteError) {
88
- throw error;
89
- }
90
- throw new AbortError(error);
91
- }
92
- }, {
93
- // Worst-case retry time: ~1 minute
94
- retries: 10,
95
- minTimeout: 1000,
96
- maxTimeout: 10000,
97
- factor: 1.5,
98
- });
99
- const searchResults = extractSearchResults(resultData);
100
- return createMcpToolSuccessResponse({
101
- result: searchResults,
102
- });
103
- }
104
- catch (error) {
105
- return handleMcpToolError(error, "AI-powered Variant Search");
106
- }
107
- });
108
- };
@@ -1,73 +0,0 @@
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("unpublish-variant-mapi", "Unpublish or schedule unpublishing Kontent.ai variant. For scheduling, verify current UTC time before using scheduledTo.", {
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
- scheduledTo: z.iso
12
- .datetime({ offset: true })
13
- .optional()
14
- .describe("ISO 8601 datetime for scheduled unpublish (omit for immediate)"),
15
- displayTimezone: z
16
- .string()
17
- .optional()
18
- .describe("Timezone for UI display (e.g., America/New_York, UTC)"),
19
- }, async ({ itemId, languageId, scheduledTo, displayTimezone }, { authInfo: { token, clientId } = {} }) => {
20
- const client = createMapiClient(clientId, token);
21
- try {
22
- // Validate that displayTimezone can only be used with scheduledTo
23
- if (displayTimezone && !scheduledTo) {
24
- throw new Error("The 'displayTimezone' parameter can only be used in combination with 'scheduledTo' parameter for scheduled unpublishing.");
25
- }
26
- let action;
27
- let message;
28
- if (scheduledTo) {
29
- // Scheduled unpublishing
30
- const requestData = {
31
- scheduled_to: scheduledTo,
32
- };
33
- // Add display_timezone if provided
34
- if (displayTimezone) {
35
- requestData.display_timezone = displayTimezone;
36
- }
37
- await client
38
- .unpublishLanguageVariant()
39
- .byItemId(itemId)
40
- .byLanguageId(languageId)
41
- .withData(requestData)
42
- .toPromise();
43
- action = "scheduled for unpublishing";
44
- message = `Successfully scheduled language variant '${languageId}' for content item '${itemId}' to be unpublished at '${scheduledTo}'${displayTimezone ? ` (timezone: ${displayTimezone})` : ""}. The content will be removed from Delivery API at the scheduled time.`;
45
- }
46
- else {
47
- // Immediate unpublishing
48
- await client
49
- .unpublishLanguageVariant()
50
- .byItemId(itemId)
51
- .byLanguageId(languageId)
52
- .withoutData()
53
- .toPromise();
54
- action = "unpublished";
55
- message = `Successfully unpublished language variant '${languageId}' for content item '${itemId}'. The content has been moved to Archived and is no longer available through Delivery API.`;
56
- }
57
- return createMcpToolSuccessResponse({
58
- message,
59
- result: {
60
- itemId,
61
- languageId,
62
- scheduledTo: scheduledTo || null,
63
- displayTimezone: displayTimezone || null,
64
- action,
65
- timestamp: new Date().toISOString(),
66
- },
67
- });
68
- }
69
- catch (error) {
70
- return handleMcpToolError(error, "Unpublish/Schedule Unpublishing Language Variant");
71
- }
72
- });
73
- };
@@ -1,24 +0,0 @@
1
- import { z } from "zod";
2
- import { createMapiClient } from "../clients/kontentClients.js";
3
- import { updateAssetDataSchema } from "../schemas/assetSchemas.js";
4
- import { handleMcpToolError } from "../utils/errorHandler.js";
5
- import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
6
- export const registerTool = (server) => {
7
- server.tool("update-asset-mapi", "Update Kontent.ai asset by ID", {
8
- id: z.guid(),
9
- data: updateAssetDataSchema,
10
- }, async ({ id, data }, { authInfo: { token, clientId } = {} }) => {
11
- const client = createMapiClient(clientId, token);
12
- try {
13
- const response = await client
14
- .upsertAsset()
15
- .byAssetId(id)
16
- .withData(() => data)
17
- .toPromise();
18
- return createMcpToolSuccessResponse(response.rawData);
19
- }
20
- catch (error) {
21
- return handleMcpToolError(error, "Asset Update");
22
- }
23
- });
24
- };
@@ -1,74 +0,0 @@
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 Kontent.ai content item", {
7
- id: z.string().describe("Content item ID"),
8
- name: z
9
- .string()
10
- .min(1)
11
- .max(200)
12
- .optional()
13
- .describe("New name (1-200 chars)"),
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("Collection reference"),
22
- }, async ({ id, name, collection }, { authInfo: { token, clientId } = {} }) => {
23
- const client = createMapiClient(clientId, token);
24
- try {
25
- // First, verify the item exists by trying to get it
26
- await client.viewContentItem().byItemId(id).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
- .byItemId(id)
50
- .withData(updateData)
51
- .toPromise();
52
- return createMcpToolSuccessResponse({
53
- message: `Content item '${id}' 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 ID '${id}' 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
- };
@@ -1,37 +0,0 @@
1
- import { z } from "zod";
2
- import { createMapiClient } from "../clients/kontentClients.js";
3
- import { languageVariantElementSchema } from "../schemas/contentItemSchemas.js";
4
- import { handleMcpToolError } from "../utils/errorHandler.js";
5
- import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
6
- export const registerTool = (server) => {
7
- server.tool("update-language-variant-mapi", "Update Kontent.ai variant. Element values must fulfill limitations and guidelines defined in content type.", {
8
- itemId: z.string().describe("Content item ID"),
9
- languageId: z
10
- .string()
11
- .describe("Language variant ID (default: 00000000-0000-0000-0000-000000000000)"),
12
- elements: z
13
- .array(languageVariantElementSchema)
14
- .describe("Content elements array"),
15
- workflow_step_id: z.string().optional().describe("Workflow step ID"),
16
- }, async ({ itemId, languageId, elements, workflow_step_id }, { authInfo: { token, clientId } = {} }) => {
17
- const client = createMapiClient(clientId, token);
18
- const data = {
19
- elements,
20
- };
21
- if (workflow_step_id) {
22
- data.workflow_step = { id: workflow_step_id };
23
- }
24
- try {
25
- const response = await client
26
- .upsertLanguageVariant()
27
- .byItemId(itemId)
28
- .byLanguageId(languageId)
29
- .withData(() => data)
30
- .toPromise();
31
- return createMcpToolSuccessResponse(response.rawData);
32
- }
33
- catch (error) {
34
- return handleMcpToolError(error, "Language Variant Update");
35
- }
36
- });
37
- };
@@ -1,32 +0,0 @@
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
- };