@kontent-ai/mcp-server 0.25.0 → 0.27.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 +5 -4
- package/build/schemas/bulkGetItemsWithVariantsSchemas.js +14 -0
- package/build/schemas/contentItemSchemas.js +109 -48
- package/build/schemas/filterVariantSchemas.js +15 -4
- package/build/schemas/languageSchemas.js +1 -10
- package/build/server.js +2 -0
- package/build/tools/add-language-mapi.js +2 -2
- package/build/tools/bulk-get-items-variants-mapi.js +31 -0
- package/build/tools/context/patch-guide-property-based.js +5 -9
- package/build/tools/filter-variants-mapi.js +8 -6
- package/build/tools/list-languages-mapi.js +1 -1
- package/build/tools/patch-language-mapi.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -105,7 +105,8 @@ npx @kontent-ai/mcp-server@latest shttp
|
|
|
105
105
|
* **upsert-language-variant-mapi** – Create or update Kontent.ai language variant of a content item via Management API. Element values must fulfill limitations and guidelines defined in content type. When updating, only provided elements will be modified
|
|
106
106
|
* **create-variant-version-mapi** – Create new version of Kontent.ai language variant via Management API. This operation creates a new version of an existing language variant, useful for content versioning and creating new drafts from published content
|
|
107
107
|
* **delete-language-variant-mapi** – Delete Kontent.ai language variant from Management API
|
|
108
|
-
* **filter-variants-mapi** – Filter Kontent.ai
|
|
108
|
+
* **filter-variants-mapi** – Filter Kontent.ai items with variants returning references (item ID + language ID). Use for exact keyword matching and finding specific terms in content. Supports full filtering capabilities (content types, workflow steps, taxonomies, spaces, collections, publishing states, etc.). Returns paginated results with continuation token for fetching subsequent pages. Use bulk-get-items-variants-mapi to retrieve full content for matched items
|
|
109
|
+
* **bulk-get-items-variants-mapi** – Bulk get Kontent.ai content items with their language variants by item and language reference pairs. Use after filter-variants-mapi to retrieve full content data for specific item+language pairs. Items without a variant in the requested language return the item without the variant property. Returns paginated results with continuation token
|
|
109
110
|
* **search-variants-mapi** – AI-powered semantic search for finding content by meaning and concepts in a specific language variant. Use for: conceptual searches when you don't know exact keywords. Limited filtering options (variant ID only)
|
|
110
111
|
|
|
111
112
|
### Asset Management
|
|
@@ -121,9 +122,9 @@ npx @kontent-ai/mcp-server@latest shttp
|
|
|
121
122
|
|
|
122
123
|
### Language Management
|
|
123
124
|
|
|
124
|
-
* **list-languages-mapi** – Get all Kontent.ai languages from Management API
|
|
125
|
-
* **add-language-mapi** – Add new Kontent.ai language via Management API
|
|
126
|
-
* **patch-language-mapi** – Update Kontent.ai language using replace operations via Management API
|
|
125
|
+
* **list-languages-mapi** – Get all Kontent.ai languages from Management API (includes both active and inactive - check is_active property)
|
|
126
|
+
* **add-language-mapi** – Add new Kontent.ai language via Management API (languages are always created as active)
|
|
127
|
+
* **patch-language-mapi** – Update Kontent.ai language using replace operations via Management API (only active languages can be modified - to activate/deactivate, use the Kontent.ai web UI)
|
|
127
128
|
|
|
128
129
|
### Collection Management
|
|
129
130
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { continuationTokenField } from "./listSchemas.js";
|
|
3
|
+
import { referenceObjectSchema } from "./referenceObjectSchema.js";
|
|
4
|
+
export const bulkGetItemsWithVariantsSchema = z.object({
|
|
5
|
+
variants: z
|
|
6
|
+
.array(z.object({
|
|
7
|
+
item: referenceObjectSchema.describe("Reference to a content item by its id, codename, or external id"),
|
|
8
|
+
language: referenceObjectSchema.describe("Reference to a language by its id, codename, or external id"),
|
|
9
|
+
}))
|
|
10
|
+
.min(1)
|
|
11
|
+
.max(100)
|
|
12
|
+
.describe("Array of item and language reference pairs to retrieve (max 100). Use filter-variants-mapi to get item and language references first."),
|
|
13
|
+
continuation_token: continuationTokenField,
|
|
14
|
+
});
|
|
@@ -1,67 +1,128 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { referenceObjectSchema } from "./referenceObjectSchema.js";
|
|
3
|
-
//
|
|
4
|
-
const
|
|
3
|
+
// Element schemas with descriptions based on Kontent.ai Management API documentation
|
|
4
|
+
const assetInVariantElementSchema = z
|
|
5
|
+
.object({
|
|
5
6
|
element: referenceObjectSchema,
|
|
6
|
-
value: z
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}));
|
|
15
|
-
const assetInVariantElementSchema = z.object({
|
|
7
|
+
value: z
|
|
8
|
+
.array(referenceObjectSchema)
|
|
9
|
+
.nullable()
|
|
10
|
+
.describe("Array of Reference objects, each representing a single asset. Every asset can be referenced only once."),
|
|
11
|
+
})
|
|
12
|
+
.describe("Asset element - references to assets (images, documents). Supports renditions for image-specific editions.");
|
|
13
|
+
const customElementInVariantElementSchema = z
|
|
14
|
+
.object({
|
|
16
15
|
element: referenceObjectSchema,
|
|
17
|
-
value: z
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
value: z
|
|
17
|
+
.string()
|
|
18
|
+
.max(200000)
|
|
19
|
+
.nullable()
|
|
20
|
+
.describe("Custom-formatted data depending on the specific custom element implementation."),
|
|
21
|
+
searchable_value: z
|
|
22
|
+
.string()
|
|
23
|
+
.max(200000)
|
|
24
|
+
.nullable()
|
|
25
|
+
.describe("Plain text for search functionality in content item lists."),
|
|
26
|
+
})
|
|
27
|
+
.describe("Custom element - stores custom-formatted data with optional searchable plain text representation.");
|
|
28
|
+
const dateTimeInVariantElementSchema = z
|
|
29
|
+
.object({
|
|
20
30
|
element: referenceObjectSchema,
|
|
21
|
-
value: z.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
value: z.iso.datetime().nullable(),
|
|
32
|
+
display_timezone: z
|
|
33
|
+
.string()
|
|
34
|
+
.nullable()
|
|
35
|
+
.describe("IANA time zone name affecting UI display without modifying stored value. Defaults to null (local time zone)."),
|
|
36
|
+
})
|
|
37
|
+
.describe("Date & time element - stores date and time values in UTC with optional display timezone.");
|
|
38
|
+
const linkedItemsInVariantElementSchema = z
|
|
39
|
+
.object({
|
|
25
40
|
element: referenceObjectSchema,
|
|
26
|
-
value: z
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
value: z
|
|
42
|
+
.array(referenceObjectSchema)
|
|
43
|
+
.nullable()
|
|
44
|
+
.describe("Array of Reference objects. Each reference represents a single content item (each item referenced only once)."),
|
|
45
|
+
})
|
|
46
|
+
.describe("Linked items element - references to other content items for modular content.");
|
|
47
|
+
const multipleChoiceInVariantElementSchema = z
|
|
48
|
+
.object({
|
|
30
49
|
element: referenceObjectSchema,
|
|
31
|
-
value: z
|
|
32
|
-
|
|
33
|
-
|
|
50
|
+
value: z
|
|
51
|
+
.array(referenceObjectSchema)
|
|
52
|
+
.nullable()
|
|
53
|
+
.describe("Array of Reference objects. Each reference represents one of the multiple choice options defined in content type."),
|
|
54
|
+
})
|
|
55
|
+
.describe("Multiple choice element - references to selected choice options. Single-option mode requires exactly one reference.");
|
|
56
|
+
const numberInVariantElementSchema = z
|
|
57
|
+
.object({
|
|
34
58
|
element: referenceObjectSchema,
|
|
35
|
-
value: z.
|
|
36
|
-
})
|
|
37
|
-
|
|
59
|
+
value: z.number().nullable().describe("Floating-point number."),
|
|
60
|
+
})
|
|
61
|
+
.describe("Number element - stores numeric floating-point values.");
|
|
62
|
+
const taxonomyInVariantElementSchema = z
|
|
63
|
+
.object({
|
|
38
64
|
element: referenceObjectSchema,
|
|
39
|
-
value: z
|
|
40
|
-
|
|
41
|
-
|
|
65
|
+
value: z
|
|
66
|
+
.array(referenceObjectSchema)
|
|
67
|
+
.nullable()
|
|
68
|
+
.describe("Array of Reference objects. Each reference represents a taxonomy term (each term referenced only once)."),
|
|
69
|
+
})
|
|
70
|
+
.describe("Taxonomy element - references to taxonomy terms from a taxonomy group.");
|
|
71
|
+
const textInVariantElementSchema = z
|
|
72
|
+
.object({
|
|
42
73
|
element: referenceObjectSchema,
|
|
43
|
-
value: z.string().nullable(),
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
74
|
+
value: z.string().max(100000).nullable().describe("Plain text content."),
|
|
75
|
+
})
|
|
76
|
+
.describe("Text element - stores plain text content.");
|
|
77
|
+
const urlSlugInVariantElementSchema = z
|
|
78
|
+
.object({
|
|
47
79
|
element: referenceObjectSchema,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
80
|
+
mode: z
|
|
81
|
+
.enum(["autogenerated", "custom"])
|
|
82
|
+
.describe("'autogenerated' (system-generated based on dependent text element) or 'custom' (manual). Switches to custom when value is directly modified."),
|
|
83
|
+
value: z.string().nullable().describe("URL-friendly slug value for SEO."),
|
|
84
|
+
})
|
|
85
|
+
.describe("URL slug element - URL-friendly slug for SEO. Can be auto-generated from dependent text element or custom.");
|
|
86
|
+
// Rich text component schema - uses lazy to handle circular reference
|
|
87
|
+
const richTextComponentSchema = z.lazy(() => z
|
|
88
|
+
.object({
|
|
89
|
+
id: z
|
|
90
|
+
.string()
|
|
91
|
+
.describe("Unique identifier of the component within the rich text element."),
|
|
92
|
+
type: referenceObjectSchema.describe("Reference to the content type defining the component structure."),
|
|
93
|
+
elements: z
|
|
94
|
+
.array(elementInComponentSchema)
|
|
95
|
+
.nullable()
|
|
96
|
+
.describe("Array of element values within the component (supports up to 6 levels deep nesting)."),
|
|
97
|
+
})
|
|
98
|
+
.describe("Component embedded in rich text - a reusable content block defined by a content type."));
|
|
99
|
+
// Rich text element schema - references components which can contain any element type
|
|
100
|
+
const richTextInVariantElementSchema = z
|
|
101
|
+
.object({
|
|
51
102
|
element: referenceObjectSchema,
|
|
52
|
-
value: z
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
103
|
+
value: z
|
|
104
|
+
.string()
|
|
105
|
+
.max(100000)
|
|
106
|
+
.nullable()
|
|
107
|
+
.describe("Valid HTML5 fragment. Defaults to '<p><br/></p>' if empty."),
|
|
108
|
+
components: z
|
|
109
|
+
.array(richTextComponentSchema)
|
|
110
|
+
.nullable()
|
|
111
|
+
.describe("Array of nested component objects that can be embedded in the rich text content."),
|
|
112
|
+
})
|
|
113
|
+
.describe("Rich text element - formatted HTML content that can include embedded assets, components, content items, and links.");
|
|
114
|
+
// Union schema for elements within components
|
|
115
|
+
// Uses z.lazy() to handle circular reference with richTextComponentSchema
|
|
116
|
+
const elementInComponentSchema = z
|
|
117
|
+
.lazy(() => languageVariantElementSchema)
|
|
118
|
+
.describe("Element value within a component - same structure as top-level variant elements.");
|
|
119
|
+
// Top-level language variant element schema - discriminated by unique fields
|
|
59
120
|
export const languageVariantElementSchema = z.union([
|
|
60
121
|
// Most specific schemas first (with unique distinguishing fields)
|
|
61
122
|
urlSlugInVariantElementSchema, // has unique required 'mode' field
|
|
62
|
-
richTextInVariantElementSchema, // has unique
|
|
123
|
+
richTextInVariantElementSchema, // has unique 'components' field
|
|
63
124
|
dateTimeInVariantElementSchema, // has unique nullable 'display_timezone' field
|
|
64
|
-
customElementInVariantElementSchema, // has unique
|
|
125
|
+
customElementInVariantElementSchema, // has unique 'searchable_value' field
|
|
65
126
|
numberInVariantElementSchema, // has unique value type (number)
|
|
66
127
|
// Medium specificity (array value types)
|
|
67
128
|
assetInVariantElementSchema, // value: array of references
|
|
@@ -68,6 +68,21 @@ export const filterVariantsSchema = z.object({
|
|
|
68
68
|
.min(1)
|
|
69
69
|
.optional()
|
|
70
70
|
.describe("Array of taxonomy groups with taxonomy terms"),
|
|
71
|
+
spaces: z
|
|
72
|
+
.array(referenceObjectSchema)
|
|
73
|
+
.min(1)
|
|
74
|
+
.optional()
|
|
75
|
+
.describe("Array of references to spaces by their id or codename (external_id is not supported for spaces)"),
|
|
76
|
+
collections: z
|
|
77
|
+
.array(referenceObjectSchema)
|
|
78
|
+
.min(1)
|
|
79
|
+
.optional()
|
|
80
|
+
.describe("Array of references to collections by their id, codename, or external id"),
|
|
81
|
+
publishing_states: z
|
|
82
|
+
.array(z.enum(["published", "unpublished", "not_published_yet"]))
|
|
83
|
+
.min(1)
|
|
84
|
+
.optional()
|
|
85
|
+
.describe("Array of publishing states to filter by. 'published' - variant is currently published, 'unpublished' - variant was published but is now unpublished, 'not_published_yet' - variant has never been published"),
|
|
71
86
|
order_by: z
|
|
72
87
|
.enum(["name", "due_date", "last_modified"])
|
|
73
88
|
.optional()
|
|
@@ -76,9 +91,5 @@ export const filterVariantsSchema = z.object({
|
|
|
76
91
|
.enum(["asc", "desc"])
|
|
77
92
|
.optional()
|
|
78
93
|
.describe("Order direction"),
|
|
79
|
-
include_content: z
|
|
80
|
-
.boolean()
|
|
81
|
-
.optional()
|
|
82
|
-
.describe("Whether to include the full content of language variants in the response"),
|
|
83
94
|
continuation_token: continuationTokenField,
|
|
84
95
|
});
|
|
@@ -3,10 +3,6 @@ import { referenceObjectSchema } from "./referenceObjectSchema.js";
|
|
|
3
3
|
export const addLanguageSchema = z.object({
|
|
4
4
|
name: z.string().describe("Display name of the language"),
|
|
5
5
|
codename: z.string().describe("Codename identifier for the language"),
|
|
6
|
-
is_active: z
|
|
7
|
-
.boolean()
|
|
8
|
-
.optional()
|
|
9
|
-
.describe("Whether the language is active (defaults to true)"),
|
|
10
6
|
fallback_language: referenceObjectSchema
|
|
11
7
|
.optional()
|
|
12
8
|
.describe("Reference to fallback language (by id, codename, or external_id)"),
|
|
@@ -23,11 +19,6 @@ const languageReplaceOperationSchema = z.discriminatedUnion("property_name", [
|
|
|
23
19
|
property_name: z.literal("name"),
|
|
24
20
|
value: z.string(),
|
|
25
21
|
}),
|
|
26
|
-
z.object({
|
|
27
|
-
op: z.literal("replace"),
|
|
28
|
-
property_name: z.literal("is_active"),
|
|
29
|
-
value: z.boolean(),
|
|
30
|
-
}),
|
|
31
22
|
z.object({
|
|
32
23
|
op: z.literal("replace"),
|
|
33
24
|
property_name: z.literal("fallback_language"),
|
|
@@ -39,5 +30,5 @@ export const patchLanguageSchema = z.object({
|
|
|
39
30
|
operations: z
|
|
40
31
|
.array(languageReplaceOperationSchema)
|
|
41
32
|
.min(1)
|
|
42
|
-
.describe("Array of replace operations for codename, name,
|
|
33
|
+
.describe("Array of replace operations for codename, name, or fallback_language. Note: Only active languages can be modified. To activate/deactivate languages, use the Kontent.ai web UI."),
|
|
43
34
|
});
|
package/build/server.js
CHANGED
|
@@ -7,6 +7,7 @@ import { registerTool as registerAddLanguageMapi } from "./tools/add-language-ma
|
|
|
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
9
|
import { registerTool as registerAddWorkflowMapi } from "./tools/add-workflow-mapi.js";
|
|
10
|
+
import { registerTool as registerBulkGetItemsVariantsMapi } from "./tools/bulk-get-items-variants-mapi.js";
|
|
10
11
|
import { registerTool as registerChangeVariantWorkflowStepMapi } from "./tools/change-variant-workflow-step-mapi.js";
|
|
11
12
|
import { registerTool as registerCreateVariantVersionMapi } from "./tools/create-variant-version-mapi.js";
|
|
12
13
|
import { registerTool as registerDeleteContentItemMapi } from "./tools/delete-content-item-mapi.js";
|
|
@@ -112,6 +113,7 @@ export const createServer = () => {
|
|
|
112
113
|
registerDeleteWorkflowMapi(server);
|
|
113
114
|
registerChangeVariantWorkflowStepMapi(server);
|
|
114
115
|
registerFilterVariantsMapi(server);
|
|
116
|
+
registerBulkGetItemsVariantsMapi(server);
|
|
115
117
|
registerSearchVariantsMapi(server);
|
|
116
118
|
registerPublishVariantMapi(server);
|
|
117
119
|
registerUnpublishVariantMapi(server);
|
|
@@ -3,7 +3,7 @@ import { addLanguageSchema } from "../schemas/languageSchemas.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("add-language-mapi", "Add new Kontent.ai language via Management API", addLanguageSchema.shape, async ({ name, codename,
|
|
6
|
+
server.tool("add-language-mapi", "Add new Kontent.ai language via Management API. Languages are always created as active.", addLanguageSchema.shape, async ({ name, codename, fallback_language, external_id }, { authInfo: { token, clientId } = {} }) => {
|
|
7
7
|
const client = createMapiClient(clientId, token);
|
|
8
8
|
try {
|
|
9
9
|
const response = await client
|
|
@@ -11,7 +11,7 @@ export const registerTool = (server) => {
|
|
|
11
11
|
.withData({
|
|
12
12
|
name,
|
|
13
13
|
codename,
|
|
14
|
-
is_active,
|
|
14
|
+
is_active: true,
|
|
15
15
|
fallback_language,
|
|
16
16
|
external_id,
|
|
17
17
|
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
|
+
import { bulkGetItemsWithVariantsSchema } from "../schemas/bulkGetItemsWithVariantsSchemas.js";
|
|
3
|
+
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
4
|
+
import { createVariantMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
|
+
import { throwError } from "../utils/throwError.js";
|
|
6
|
+
export const registerTool = (server) => {
|
|
7
|
+
server.tool("bulk-get-items-variants-mapi", "Bulk get Kontent.ai content items with their language variants by item and language reference pairs. Items without a variant in the requested language return the item without the variant property.", bulkGetItemsWithVariantsSchema.shape, async ({ variants, continuation_token }, { authInfo: { token, clientId } = {} }) => {
|
|
8
|
+
try {
|
|
9
|
+
const environmentId = clientId ?? process.env.KONTENT_ENVIRONMENT_ID;
|
|
10
|
+
if (!environmentId) {
|
|
11
|
+
throwError("Missing required environment ID");
|
|
12
|
+
}
|
|
13
|
+
const client = createMapiClient(environmentId, token);
|
|
14
|
+
const query = client.bulkGetItemsWithVariants().withData({
|
|
15
|
+
variants,
|
|
16
|
+
});
|
|
17
|
+
const response = await (continuation_token
|
|
18
|
+
? query.xContinuationToken(continuation_token)
|
|
19
|
+
: query).toPromise();
|
|
20
|
+
return createVariantMcpToolSuccessResponse({
|
|
21
|
+
data: response.rawData.data,
|
|
22
|
+
pagination: {
|
|
23
|
+
continuation_token: response.data.pagination.continuationToken,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return handleMcpToolError(error, "Bulk Get Items With Variants");
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
};
|
|
@@ -21,20 +21,16 @@ Available properties: name, codename, collections
|
|
|
21
21
|
\`\`\`json
|
|
22
22
|
{ "op": "replace", "property_name": "name", "value": "New Language Name" }
|
|
23
23
|
{ "op": "replace", "property_name": "codename", "value": "new_codename" }
|
|
24
|
-
{ "op": "replace", "property_name": "is_active", "value": true }
|
|
25
24
|
{ "op": "replace", "property_name": "fallback_language", "value": { "codename": "en-US" } }
|
|
26
25
|
\`\`\`
|
|
27
26
|
|
|
28
|
-
Available properties: name, codename,
|
|
27
|
+
Available properties: name, codename, fallback_language
|
|
29
28
|
|
|
30
29
|
## Critical Rule for Languages
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
{ "op": "replace", "property_name": "name", "value": "New Name" }
|
|
36
|
-
]
|
|
37
|
-
\`\`\`
|
|
30
|
+
|
|
31
|
+
**Only active languages can be modified.** To activate or deactivate a language, the user must use the Kontent.ai web UI - this is a critical operation that cannot be performed via API tools.
|
|
32
|
+
|
|
33
|
+
When user asks to update "all languages": only update active languages (is_active: true). If they need to modify inactive languages, inform them they must first activate those languages in the Kontent.ai web UI.
|
|
38
34
|
|
|
39
35
|
## General Rules
|
|
40
36
|
- external_id cannot be modified after creation
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createMapiClient } from "../clients/kontentClients.js";
|
|
2
2
|
import { filterVariantsSchema } from "../schemas/filterVariantSchemas.js";
|
|
3
3
|
import { handleMcpToolError } from "../utils/errorHandler.js";
|
|
4
|
-
import {
|
|
4
|
+
import { createMcpToolSuccessResponse } from "../utils/responseHelper.js";
|
|
5
5
|
import { throwError } from "../utils/throwError.js";
|
|
6
6
|
export const registerTool = (server) => {
|
|
7
|
-
server.tool("filter-variants-mapi", "Filter Kontent.ai variants. For EXACT keyword matching and compliance (terms use OR). Use search-variants-mapi for semantic/topic search.", filterVariantsSchema.shape, async ({ search_phrase, content_types, contributors, has_no_contributors, completion_statuses, language, workflow_steps, taxonomy_groups, order_by, order_direction,
|
|
7
|
+
server.tool("filter-variants-mapi", "Filter Kontent.ai items with variants returning references (item ID + language ID). For EXACT keyword matching and compliance (terms use OR). Use bulk-get-items-variants-mapi to retrieve full content for matched items. Use search-variants-mapi for semantic/topic search.", filterVariantsSchema.shape, async ({ search_phrase, content_types, contributors, has_no_contributors, completion_statuses, language, workflow_steps, taxonomy_groups, spaces, collections, publishing_states, order_by, order_direction, continuation_token, }, { authInfo: { token, clientId } = {} }) => {
|
|
8
8
|
try {
|
|
9
9
|
const environmentId = clientId ?? process.env.KONTENT_ENVIRONMENT_ID;
|
|
10
10
|
if (!environmentId) {
|
|
11
11
|
throwError("Missing required environment ID");
|
|
12
12
|
}
|
|
13
13
|
const client = createMapiClient(environmentId, token);
|
|
14
|
-
const query = client.
|
|
14
|
+
const query = client.filterItemsWithVariants().withData({
|
|
15
15
|
filters: {
|
|
16
16
|
search_phrase,
|
|
17
17
|
content_types,
|
|
@@ -21,6 +21,9 @@ export const registerTool = (server) => {
|
|
|
21
21
|
language,
|
|
22
22
|
workflow_steps,
|
|
23
23
|
taxonomy_groups,
|
|
24
|
+
spaces,
|
|
25
|
+
collections,
|
|
26
|
+
publishing_states,
|
|
24
27
|
},
|
|
25
28
|
order: order_by
|
|
26
29
|
? {
|
|
@@ -28,13 +31,12 @@ export const registerTool = (server) => {
|
|
|
28
31
|
direction: order_direction || "asc",
|
|
29
32
|
}
|
|
30
33
|
: undefined,
|
|
31
|
-
include_content: include_content ?? false,
|
|
32
34
|
});
|
|
33
35
|
const response = await (continuation_token
|
|
34
36
|
? query.xContinuationToken(continuation_token)
|
|
35
37
|
: query).toPromise();
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
+
return createMcpToolSuccessResponse({
|
|
39
|
+
variants: response.rawData.variants,
|
|
38
40
|
pagination: {
|
|
39
41
|
continuation_token: response.data.pagination.continuationToken,
|
|
40
42
|
},
|
|
@@ -3,7 +3,7 @@ import { listLanguagesSchema } 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-languages-mapi", "Get all Kontent.ai languages (paginated). Languages define available locales; each can have fallback language for content inheritance.", listLanguagesSchema.shape, async ({ continuation_token }, { authInfo: { token, clientId } = {} }) => {
|
|
6
|
+
server.tool("list-languages-mapi", "Get all Kontent.ai languages (paginated), including inactive ones - check is_active property. Languages define available locales; each can have fallback language for content inheritance.", listLanguagesSchema.shape, async ({ continuation_token }, { authInfo: { token, clientId } = {} }) => {
|
|
7
7
|
const client = createMapiClient(clientId, token);
|
|
8
8
|
try {
|
|
9
9
|
const query = client.listLanguages();
|
|
@@ -3,7 +3,7 @@ import { patchLanguageSchema } from "../schemas/languageSchemas.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("patch-language-mapi", "Update Kontent.ai language using replace operations. Call get-patch-guide first.
|
|
6
|
+
server.tool("patch-language-mapi", "Update Kontent.ai language using replace operations. Call get-patch-guide first. Only active languages can be modified - to activate/deactivate, use the Kontent.ai web UI.", patchLanguageSchema.shape, async ({ languageId, operations }, { authInfo: { token, clientId } = {} }) => {
|
|
7
7
|
const client = createMapiClient(clientId, token);
|
|
8
8
|
try {
|
|
9
9
|
const response = await client
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontent-ai/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"mcpName": "io.github.kontent-ai/mcp-server",
|
|
6
6
|
"repository": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"author": "Jiri Lojda",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@kontent-ai/management-sdk": "^8.
|
|
33
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
32
|
+
"@kontent-ai/management-sdk": "^8.3.0",
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
34
34
|
"applicationinsights": "^2.9.8",
|
|
35
35
|
"dotenv": "^17.2.3",
|
|
36
36
|
"express": "^5.2.1",
|