@kontent-ai/mcp-server 0.4.2 → 0.5.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.
@@ -1,36 +1,38 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
3
- import { snippetElementSchema, contentGroupSchema } from '../schemas/contentTypeSchemas.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { snippetElementSchema } from "../schemas/contentTypeSchemas.js";
4
+ import { handleMcpToolError } from "../utils/errorHandler.js";
5
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
4
6
  export const registerTool = (server) => {
5
7
  server.tool("add-content-type-snippet-mapi", "Add a new content type snippet via Management API", {
6
8
  name: z.string().describe("Display name of the content type snippet"),
7
- codename: z.string().optional().describe("Codename of the content type snippet (optional, will be generated if not provided)"),
8
- external_id: z.string().optional().describe("External ID of the content type snippet (optional)"),
9
- elements: z.array(snippetElementSchema).describe("Array of elements that define the structure of the content type snippet"),
10
- content_groups: z.array(contentGroupSchema).optional().describe("Array of content groups (optional)"),
11
- }, async ({ name, codename, external_id, elements, content_groups }) => {
9
+ codename: z
10
+ .string()
11
+ .optional()
12
+ .describe("Codename of the content type snippet (optional, will be generated if not provided)"),
13
+ external_id: z
14
+ .string()
15
+ .optional()
16
+ .describe("External ID of the content type snippet (optional)"),
17
+ elements: z
18
+ .array(snippetElementSchema)
19
+ .describe("Array of elements that define the structure of the content type snippet"),
20
+ }, async ({ name, codename, external_id, elements }) => {
12
21
  const client = createMapiClient();
13
- const response = await client
14
- .addContentTypeSnippet()
15
- .withData(() => ({
16
- name,
17
- codename,
18
- external_id,
19
- elements,
20
- content_groups: content_groups?.map(group => ({
21
- name: group.name,
22
- external_id: group.external_id,
23
- codename: group.codename
24
- })),
25
- }))
26
- .toPromise();
27
- return {
28
- content: [
29
- {
30
- type: "text",
31
- text: JSON.stringify(response.rawData),
32
- },
33
- ],
34
- };
22
+ try {
23
+ const response = await client
24
+ .addContentTypeSnippet()
25
+ .withData(() => ({
26
+ name,
27
+ codename,
28
+ external_id,
29
+ elements,
30
+ }))
31
+ .toPromise();
32
+ return createMcpToolSuccessResponse(response.rawData);
33
+ }
34
+ catch (error) {
35
+ return handleMcpToolError(error, "Content Type Snippet Creation");
36
+ }
35
37
  });
36
38
  };
@@ -1,19 +1,19 @@
1
- import { createMapiClient } from '../clients/kontentClients.js';
2
- import { taxonomyGroupSchemas } from '../schemas/taxonomySchemas.js';
1
+ import { createMapiClient } from "../clients/kontentClients.js";
2
+ import { taxonomyGroupSchemas } from "../schemas/taxonomySchemas.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("add-taxonomy-group-mapi", "Add a new taxonomy group via Management API", taxonomyGroupSchemas, async (taxonomyGroup) => {
5
7
  const client = createMapiClient();
6
- const response = await client
7
- .addTaxonomy()
8
- .withData(taxonomyGroup)
9
- .toPromise();
10
- return {
11
- content: [
12
- {
13
- type: "text",
14
- text: JSON.stringify(response.data),
15
- },
16
- ],
17
- };
8
+ try {
9
+ const response = await client
10
+ .addTaxonomy()
11
+ .withData(taxonomyGroup)
12
+ .toPromise();
13
+ return createMcpToolSuccessResponse(response.data);
14
+ }
15
+ catch (error) {
16
+ return handleMcpToolError(error, "Taxonomy Group Creation");
17
+ }
18
18
  });
19
19
  };
@@ -1,21 +1,21 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-asset-mapi", "Get a specific asset by codename from Management API", {
5
- assetCodename: z.string().describe("Codename of the asset to retrieve")
7
+ assetCodename: z.string().describe("Codename of the asset to retrieve"),
6
8
  }, async ({ assetCodename }) => {
7
9
  const client = createMapiClient();
8
- const response = await client
9
- .viewAsset()
10
- .byAssetCodename(assetCodename)
11
- .toPromise();
12
- return {
13
- content: [
14
- {
15
- type: "text",
16
- text: JSON.stringify(response.data),
17
- },
18
- ],
19
- };
10
+ try {
11
+ const response = await client
12
+ .viewAsset()
13
+ .byAssetCodename(assetCodename)
14
+ .toPromise();
15
+ return createMcpToolSuccessResponse(response.data);
16
+ }
17
+ catch (error) {
18
+ return handleMcpToolError(error, "Asset Retrieval");
19
+ }
20
20
  });
21
21
  };
@@ -1,23 +1,23 @@
1
+ import { createDeliveryClient } from "@kontent-ai/delivery-sdk";
1
2
  import { z } from "zod";
2
- import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-item-dapi", "Get Kontent.ai item by codename from Delivery API", {
5
7
  codename: z.string().describe("Codename of the item to get"),
6
- environmentId: z.string().describe("Environment ID of the item's environment"),
8
+ environmentId: z
9
+ .string()
10
+ .describe("Environment ID of the item's environment"),
7
11
  }, async ({ codename, environmentId }) => {
8
12
  const client = createDeliveryClient({
9
13
  environmentId,
10
14
  });
11
- const response = await client
12
- .item(codename)
13
- .toPromise();
14
- return {
15
- content: [
16
- {
17
- type: "text",
18
- text: JSON.stringify(response.data.item),
19
- },
20
- ],
21
- };
15
+ try {
16
+ const response = await client.item(codename).toPromise();
17
+ return createMcpToolSuccessResponse(response.data.item);
18
+ }
19
+ catch (error) {
20
+ return handleMcpToolError(error, "Item Retrieval (Delivery API)");
21
+ }
22
22
  });
23
23
  };
@@ -1,21 +1,21 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-item-mapi", "Get Kontent.ai item by codename from Management API", {
5
- codename: z.string().describe("Codename of the item to get")
7
+ codename: z.string().describe("Codename of the item to get"),
6
8
  }, async ({ codename }) => {
7
9
  const client = createMapiClient();
8
- const response = await client
9
- .viewContentItem()
10
- .byItemCodename(codename)
11
- .toPromise();
12
- return {
13
- content: [
14
- {
15
- type: "text",
16
- text: JSON.stringify(response.data),
17
- },
18
- ],
19
- };
10
+ try {
11
+ const response = await client
12
+ .viewContentItem()
13
+ .byItemCodename(codename)
14
+ .toPromise();
15
+ return createMcpToolSuccessResponse(response.data);
16
+ }
17
+ catch (error) {
18
+ return handleMcpToolError(error, "Item Retrieval");
19
+ }
20
20
  });
21
21
  };
@@ -1,21 +1,21 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-taxonomy-group-mapi", "Get taxonomy group by codename from Management API", {
5
- codename: z.string().describe("Codename of the taxonomy group to get")
7
+ codename: z.string().describe("Codename of the taxonomy group to get"),
6
8
  }, async ({ codename }) => {
7
9
  const client = createMapiClient();
8
- const response = await client
9
- .getTaxonomy()
10
- .byTaxonomyCodename(codename)
11
- .toPromise();
12
- return {
13
- content: [
14
- {
15
- type: "text",
16
- text: JSON.stringify(response.data),
17
- },
18
- ],
19
- };
10
+ try {
11
+ const response = await client
12
+ .getTaxonomy()
13
+ .byTaxonomyCodename(codename)
14
+ .toPromise();
15
+ return createMcpToolSuccessResponse(response.data);
16
+ }
17
+ catch (error) {
18
+ return handleMcpToolError(error, "Taxonomy Group Retrieval");
19
+ }
20
20
  });
21
21
  };
@@ -1,21 +1,21 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-type-mapi", "Get content type by codename from Management API", {
5
- codename: z.string().describe("Codename of the content type to get")
7
+ codename: z.string().describe("Codename of the content type to get"),
6
8
  }, async ({ codename }) => {
7
9
  const client = createMapiClient();
8
- const response = await client
9
- .viewContentType()
10
- .byTypeCodename(codename)
11
- .toPromise();
12
- return {
13
- content: [
14
- {
15
- type: "text",
16
- text: JSON.stringify(response.data),
17
- },
18
- ],
19
- };
10
+ try {
11
+ const response = await client
12
+ .viewContentType()
13
+ .byTypeCodename(codename)
14
+ .toPromise();
15
+ return createMcpToolSuccessResponse(response.data);
16
+ }
17
+ catch (error) {
18
+ return handleMcpToolError(error, "Content Type Retrieval");
19
+ }
20
20
  });
21
21
  };
@@ -1,21 +1,23 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-type-snippet-mapi", "Get content type snippet by codename from Management API", {
5
- codename: z.string().describe("Codename of the content type snippet to get")
7
+ codename: z
8
+ .string()
9
+ .describe("Codename of the content type snippet to get"),
6
10
  }, async ({ codename }) => {
7
11
  const client = createMapiClient();
8
- const response = await client
9
- .viewContentTypeSnippet()
10
- .byTypeCodename(codename)
11
- .toPromise();
12
- return {
13
- content: [
14
- {
15
- type: "text",
16
- text: JSON.stringify(response.data),
17
- },
18
- ],
19
- };
12
+ try {
13
+ const response = await client
14
+ .viewContentTypeSnippet()
15
+ .byTypeCodename(codename)
16
+ .toPromise();
17
+ return createMcpToolSuccessResponse(response.data);
18
+ }
19
+ catch (error) {
20
+ return handleMcpToolError(error, "Content Type Snippet Retrieval");
21
+ }
20
22
  });
21
23
  };
@@ -1,23 +1,25 @@
1
1
  import { z } from "zod";
2
- import { createMapiClient } from '../clients/kontentClients.js';
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { handleMcpToolError } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
3
5
  export const registerTool = (server) => {
4
6
  server.tool("get-variant-mapi", "Get language variant of a content item from Management API", {
5
7
  itemCodename: z.string().describe("Codename of the content item"),
6
- languageCodename: z.string().describe("Codename of the language variant to get")
8
+ languageCodename: z
9
+ .string()
10
+ .describe("Codename of the language variant to get"),
7
11
  }, async ({ itemCodename, languageCodename }) => {
8
12
  const client = createMapiClient();
9
- const response = await client
10
- .viewLanguageVariant()
11
- .byItemCodename(itemCodename)
12
- .byLanguageCodename(languageCodename)
13
- .toPromise();
14
- return {
15
- content: [
16
- {
17
- type: "text",
18
- text: JSON.stringify(response.data),
19
- },
20
- ],
21
- };
13
+ try {
14
+ const response = await client
15
+ .viewLanguageVariant()
16
+ .byItemCodename(itemCodename)
17
+ .byLanguageCodename(languageCodename)
18
+ .toPromise();
19
+ return createMcpToolSuccessResponse(response.data);
20
+ }
21
+ catch (error) {
22
+ return handleMcpToolError(error, "Language Variant Retrieval");
23
+ }
22
24
  });
23
25
  };
@@ -1,17 +1,15 @@
1
- import { createMapiClient } from '../clients/kontentClients.js';
1
+ import { createMapiClient } from "../clients/kontentClients.js";
2
+ import { handleMcpToolError } from "../utils/errorHandler.js";
3
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
2
4
  export const registerTool = (server) => {
3
5
  server.tool("list-assets-mapi", "Get all assets from Management API", {}, async () => {
4
6
  const client = createMapiClient();
5
- const response = await client
6
- .listAssets()
7
- .toAllPromise();
8
- return {
9
- content: [
10
- {
11
- type: "text",
12
- text: JSON.stringify(response.data),
13
- },
14
- ],
15
- };
7
+ try {
8
+ const response = await client.listAssets().toAllPromise();
9
+ return createMcpToolSuccessResponse(response.data);
10
+ }
11
+ catch (error) {
12
+ return handleMcpToolError(error, "Assets Listing");
13
+ }
16
14
  });
17
15
  };
@@ -1,17 +1,15 @@
1
- import { createMapiClient } from '../clients/kontentClients.js';
1
+ import { createMapiClient } from "../clients/kontentClients.js";
2
+ import { handleMcpToolError } from "../utils/errorHandler.js";
3
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
2
4
  export const registerTool = (server) => {
3
5
  server.tool("list-content-type-snippets-mapi", "Get all content type snippets from Management API", {}, async () => {
4
6
  const client = createMapiClient();
5
- const response = await client
6
- .listContentTypeSnippets()
7
- .toAllPromise();
8
- return {
9
- content: [
10
- {
11
- type: "text",
12
- text: JSON.stringify(response.data),
13
- },
14
- ],
15
- };
7
+ try {
8
+ const response = await client.listContentTypeSnippets().toAllPromise();
9
+ return createMcpToolSuccessResponse(response.data);
10
+ }
11
+ catch (error) {
12
+ return handleMcpToolError(error, "Content Type Snippets Listing");
13
+ }
16
14
  });
17
15
  };
@@ -1,17 +1,15 @@
1
- import { createMapiClient } from '../clients/kontentClients.js';
1
+ import { createMapiClient } from "../clients/kontentClients.js";
2
+ import { handleMcpToolError } from "../utils/errorHandler.js";
3
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
2
4
  export const registerTool = (server) => {
3
5
  server.tool("list-content-types-mapi", "Get all content types from Management API", {}, async () => {
4
6
  const client = createMapiClient();
5
- const response = await client
6
- .listContentTypes()
7
- .toAllPromise();
8
- return {
9
- content: [
10
- {
11
- type: "text",
12
- text: JSON.stringify(response.data),
13
- },
14
- ],
15
- };
7
+ try {
8
+ const response = await client.listContentTypes().toAllPromise();
9
+ return createMcpToolSuccessResponse(response.data);
10
+ }
11
+ catch (error) {
12
+ return handleMcpToolError(error, "Content Types Listing");
13
+ }
16
14
  });
17
15
  };
@@ -1,17 +1,15 @@
1
- import { createMapiClient } from '../clients/kontentClients.js';
1
+ import { createMapiClient } from "../clients/kontentClients.js";
2
+ import { handleMcpToolError } from "../utils/errorHandler.js";
3
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
2
4
  export const registerTool = (server) => {
3
5
  server.tool("list-languages-mapi", "Get all languages from Management API", {}, async () => {
4
6
  const client = createMapiClient();
5
- const response = await client
6
- .listLanguages()
7
- .toAllPromise();
8
- return {
9
- content: [
10
- {
11
- type: "text",
12
- text: JSON.stringify(response.data),
13
- },
14
- ],
15
- };
7
+ try {
8
+ const response = await client.listLanguages().toAllPromise();
9
+ return createMcpToolSuccessResponse(response.data);
10
+ }
11
+ catch (error) {
12
+ return handleMcpToolError(error, "Languages Listing");
13
+ }
16
14
  });
17
15
  };
@@ -1,17 +1,15 @@
1
- import { createMapiClient } from '../clients/kontentClients.js';
1
+ import { createMapiClient } from "../clients/kontentClients.js";
2
+ import { handleMcpToolError } from "../utils/errorHandler.js";
3
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
2
4
  export const registerTool = (server) => {
3
- server.tool("list-taxonomy-groups-mapi", "Get all taxonomy groups from Management API", {}, async () => {
5
+ server.tool("list-taxonomy-groups-mapi", "Get all taxonomy groups from Management API", {}, {}, async () => {
4
6
  const client = createMapiClient();
5
- const response = await client
6
- .listTaxonomies()
7
- .toPromise();
8
- return {
9
- content: [
10
- {
11
- type: "text",
12
- text: JSON.stringify(response.data),
13
- },
14
- ],
15
- };
7
+ try {
8
+ const response = await client.listTaxonomies().toPromise();
9
+ return createMcpToolSuccessResponse(response.data);
10
+ }
11
+ catch (error) {
12
+ return handleMcpToolError(error, "Taxonomy Groups Listing");
13
+ }
16
14
  });
17
15
  };
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ import { createMapiClient } from "../clients/kontentClients.js";
3
+ import { createValidationErrorResponse, handleMcpToolError, } from "../utils/errorHandler.js";
4
+ import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
5
+ export const registerTool = (server) => {
6
+ server.tool("upsert-language-variant-mapi", "Create or update a language variant of a content item via Management API. This adds actual content to the content item elements. Elements should be provided as JSON string in the format expected by the SDK.", {
7
+ itemCodename: z.string().describe("Codename of the content item"),
8
+ languageCodename: z
9
+ .string()
10
+ .describe("Codename of the language variant (e.g., 'default', 'en-US', 'es-ES')"),
11
+ elements: z
12
+ .string()
13
+ .describe('JSON string representing an array of element objects. Each element should have an "element" object with "codename" property and a "value" property. Example: \'[{"element": {"codename": "title"}, "value": "My Title"}, {"element": {"codename": "content"}, "value": "<p>My content</p>"}]\''),
14
+ workflow_step_codename: z
15
+ .string()
16
+ .optional()
17
+ .describe("Codename of the workflow step (optional)"),
18
+ }, async ({ itemCodename, languageCodename, elements, workflow_step_codename, }) => {
19
+ const client = createMapiClient();
20
+ let parsedElements;
21
+ try {
22
+ parsedElements = JSON.parse(elements);
23
+ }
24
+ catch (error) {
25
+ return createValidationErrorResponse(`Invalid JSON format in elements parameter. ${error instanceof Error ? error.message : "Unknown JSON parsing error"}`, "JSON Parsing Error");
26
+ }
27
+ const data = {
28
+ elements: parsedElements,
29
+ };
30
+ if (workflow_step_codename) {
31
+ data.workflow_step = { codename: workflow_step_codename };
32
+ }
33
+ try {
34
+ const response = await client
35
+ .upsertLanguageVariant()
36
+ .byItemCodename(itemCodename)
37
+ .byLanguageCodename(languageCodename)
38
+ .withData(() => data)
39
+ .toPromise();
40
+ return createMcpToolSuccessResponse(response.rawData);
41
+ }
42
+ catch (error) {
43
+ return handleMcpToolError(error, "Language Variant Upsert");
44
+ }
45
+ });
46
+ };