@kontent-ai/mcp-server 0.21.10 → 0.22.1
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 +65 -22
- package/build/schemas/collectionSchemas.js +37 -0
- package/build/schemas/languageSchemas.js +43 -0
- package/build/schemas/listSchemas.js +16 -0
- package/build/schemas/taxonomySchemas.js +5 -2
- package/build/server.js +24 -2
- package/build/test/utils/responseHelper.spec.js +584 -0
- package/build/tools/add-language-mapi.js +25 -0
- package/build/tools/context/initial-context.js +46 -1
- package/build/tools/filter-variants-mapi.js +2 -2
- package/build/tools/{get-variant-mapi.js → get-latest-variant-mapi.js} +4 -4
- package/build/tools/get-published-variant-mapi.js +24 -0
- package/build/tools/list-collections-mapi.js +15 -0
- package/build/tools/list-spaces-mapi.js +15 -0
- package/build/tools/list-variants-collection-mapi.js +26 -0
- package/build/tools/list-variants-components-type-mapi.js +26 -0
- package/build/tools/list-variants-item-mapi.js +21 -0
- package/build/tools/list-variants-space-mapi.js +24 -0
- package/build/tools/list-variants-type-mapi.js +26 -0
- package/build/tools/patch-collections-mapi.js +25 -0
- package/build/tools/patch-language-mapi.js +24 -0
- package/build/tools/search-variants-mapi.js +2 -2
- package/build/tools/upsert-language-variant-mapi.js +2 -2
- package/build/utils/responseHelper.js +115 -5
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ Kontent.ai MCP Server implements the Model Context Protocol to connect your Kont
|
|
|
23
23
|
- [🔌 Quickstart](#-quickstart)
|
|
24
24
|
- [🛠️ Available Tools](#️-available-tools)
|
|
25
25
|
- [⚙️ Configuration](#️-configuration)
|
|
26
|
+
- [🔧 Response Optimization](#-response-optimization)
|
|
26
27
|
- [🚀 Transport Options](#-transport-options)
|
|
27
28
|
- [💻 Development](#-development)
|
|
28
29
|
- [🛠 Local Installation](#-local-installation)
|
|
@@ -88,7 +89,13 @@ npx @kontent-ai/mcp-server@latest shttp
|
|
|
88
89
|
|
|
89
90
|
* **get-item-mapi** – Get Kontent.ai item by internal ID from Management API
|
|
90
91
|
* **get-item-dapi** – Get Kontent.ai item by codename from Delivery API
|
|
91
|
-
* **get-variant-mapi** – Get Kontent.ai language variant
|
|
92
|
+
* **get-latest-variant-mapi** – Get latest version of Kontent.ai language variant from Management API
|
|
93
|
+
* **get-published-variant-mapi** – Get published version of Kontent.ai language variant from Management API
|
|
94
|
+
* **list-variants-item-mapi** – List all Kontent.ai language variants of a content item from Management API
|
|
95
|
+
* **list-variants-collection-mapi** – List Kontent.ai language variants by collection from Management API (paginated)
|
|
96
|
+
* **list-variants-type-mapi** – List Kontent.ai language variants by content type from Management API (paginated)
|
|
97
|
+
* **list-variants-components-type-mapi** – List Kontent.ai language variants containing components of a specific content type from Management API (paginated)
|
|
98
|
+
* **list-variants-space-mapi** – List Kontent.ai language variants by space from Management API (paginated)
|
|
92
99
|
* **add-content-item-mapi** – Add new Kontent.ai content item via Management API. This creates the content item structure but does not add content to language variants. Use upsert-language-variant-mapi to add content to the item
|
|
93
100
|
* **update-content-item-mapi** – Update existing Kontent.ai content item by internal ID via Management API. The content item must already exist - this tool will not create new items
|
|
94
101
|
* **delete-content-item-mapi** – Delete Kontent.ai content item by internal ID from Management API
|
|
@@ -106,6 +113,17 @@ npx @kontent-ai/mcp-server@latest shttp
|
|
|
106
113
|
### Language Management
|
|
107
114
|
|
|
108
115
|
* **list-languages-mapi** – Get all Kontent.ai languages from Management API
|
|
116
|
+
* **add-language-mapi** – Add new Kontent.ai language via Management API
|
|
117
|
+
* **patch-language-mapi** – Update Kontent.ai language using replace operations via Management API
|
|
118
|
+
|
|
119
|
+
### Collection Management
|
|
120
|
+
|
|
121
|
+
* **list-collections-mapi** – Get all Kontent.ai collections from Management API. Collections set boundaries for content items in your environment and help organize content by team, brand, or project
|
|
122
|
+
* **patch-collections-mapi** – Update Kontent.ai collections using patch operations (addInto to add new collections, move to reorder, remove to delete empty collections, replace to rename)
|
|
123
|
+
|
|
124
|
+
### Space Management
|
|
125
|
+
|
|
126
|
+
* **list-spaces-mapi** – Get all Kontent.ai spaces from Management API
|
|
109
127
|
|
|
110
128
|
### Workflow Management
|
|
111
129
|
|
|
@@ -139,6 +157,34 @@ For multi-tenant mode (Streamable HTTP only), the server accepts:
|
|
|
139
157
|
|
|
140
158
|
This mode allows a single server instance to handle requests for multiple Kontent.ai environments securely without requiring environment variables.
|
|
141
159
|
|
|
160
|
+
## 🔧 Response Optimization
|
|
161
|
+
|
|
162
|
+
The MCP server implements automatic token optimization to reduce AI model costs and improve performance:
|
|
163
|
+
|
|
164
|
+
### Token Reduction Strategy
|
|
165
|
+
|
|
166
|
+
The server automatically removes empty/default values from responses to reduce token usage. This includes:
|
|
167
|
+
|
|
168
|
+
- Null and undefined values
|
|
169
|
+
- Empty strings (`""`)
|
|
170
|
+
- Empty arrays (`[]`)
|
|
171
|
+
- Empty objects (`{}`)
|
|
172
|
+
- Rich text placeholders (`"<p><br/></p>"`)
|
|
173
|
+
- Elements with only an ID after empty value removal
|
|
174
|
+
|
|
175
|
+
### Impact on AI Agents
|
|
176
|
+
|
|
177
|
+
**Important for AI implementations**: When consuming responses from this MCP server:
|
|
178
|
+
|
|
179
|
+
1. **Missing properties indicate default values**, not missing data
|
|
180
|
+
2. Missing elements in variants have their type-specific defaults:
|
|
181
|
+
- Text elements: `""` (empty string)
|
|
182
|
+
- Rich text: `"<p><br/></p>"` (empty placeholder)
|
|
183
|
+
- Number/Date: `null`
|
|
184
|
+
- Custom elements: `null` (for value and searchable_value)
|
|
185
|
+
- Arrays (assets, taxonomy, etc.): `[]`
|
|
186
|
+
3. When creating/updating content, always send complete data
|
|
187
|
+
|
|
142
188
|
## 🚀 Transport Options
|
|
143
189
|
|
|
144
190
|
### 📟 STDIO Transport
|
|
@@ -188,7 +234,8 @@ Then configure your MCP client:
|
|
|
188
234
|
|
|
189
235
|
No environment variables required. The server accepts requests for multiple environments using URL path parameters and Bearer authentication.
|
|
190
236
|
|
|
191
|
-
|
|
237
|
+
<details>
|
|
238
|
+
<summary><strong>VS Code</strong></summary>
|
|
192
239
|
|
|
193
240
|
Create a `.vscode/mcp.json` file in your workspace:
|
|
194
241
|
|
|
@@ -232,7 +279,10 @@ For secure configuration with input prompts:
|
|
|
232
279
|
}
|
|
233
280
|
```
|
|
234
281
|
|
|
235
|
-
|
|
282
|
+
</details>
|
|
283
|
+
|
|
284
|
+
<details>
|
|
285
|
+
<summary><strong>Claude Desktop</strong></summary>
|
|
236
286
|
|
|
237
287
|
Update your Claude Desktop configuration file:
|
|
238
288
|
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
@@ -257,32 +307,25 @@ Use `mcp-remote` as a proxy to add authentication headers:
|
|
|
257
307
|
}
|
|
258
308
|
```
|
|
259
309
|
|
|
260
|
-
|
|
310
|
+
</details>
|
|
261
311
|
|
|
262
|
-
|
|
312
|
+
<details>
|
|
313
|
+
<summary><strong>Claude Code</strong></summary>
|
|
314
|
+
|
|
315
|
+
Add the server using the CLI:
|
|
263
316
|
|
|
264
317
|
```bash
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
--
|
|
268
|
-
--header "Authorization: Bearer <management-api-key>" \
|
|
269
|
-
kontent-ai-multi
|
|
318
|
+
claude mcp add --transport http kontent-ai-multi \
|
|
319
|
+
"http://localhost:3001/<environment-id>/mcp" \
|
|
320
|
+
--header "Authorization: Bearer <management-api-key>"
|
|
270
321
|
```
|
|
271
322
|
|
|
272
|
-
|
|
323
|
+
> **Note**: You can also configure this in your Claude Code settings JSON with the `url` and `headers` properties.
|
|
273
324
|
|
|
274
|
-
|
|
275
|
-
{
|
|
276
|
-
"kontent-ai-multi": {
|
|
277
|
-
"url": "http://localhost:3001/<environment-id>/mcp",
|
|
278
|
-
"headers": {
|
|
279
|
-
"Authorization": "Bearer <management-api-key>"
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
```
|
|
325
|
+
</details>
|
|
284
326
|
|
|
285
|
-
|
|
327
|
+
> [!IMPORTANT]
|
|
328
|
+
> Replace `<environment-id>` with your Kontent.ai environment ID (GUID) and `<management-api-key>` with your Management API key.
|
|
286
329
|
|
|
287
330
|
## 💻 Development
|
|
288
331
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { referenceObjectSchema } from "./referenceObjectSchema.js";
|
|
3
|
+
const addIntoOperationSchema = z.object({
|
|
4
|
+
op: z.literal("addInto"),
|
|
5
|
+
value: z.object({
|
|
6
|
+
name: z.string(),
|
|
7
|
+
codename: z.string().optional(),
|
|
8
|
+
external_id: z.string().optional(),
|
|
9
|
+
}),
|
|
10
|
+
before: referenceObjectSchema.optional(),
|
|
11
|
+
after: referenceObjectSchema.optional(),
|
|
12
|
+
});
|
|
13
|
+
const moveOperationSchema = z.object({
|
|
14
|
+
op: z.literal("move"),
|
|
15
|
+
reference: referenceObjectSchema,
|
|
16
|
+
before: referenceObjectSchema.optional(),
|
|
17
|
+
after: referenceObjectSchema.optional(),
|
|
18
|
+
});
|
|
19
|
+
const removeOperationSchema = z.object({
|
|
20
|
+
op: z.literal("remove"),
|
|
21
|
+
reference: referenceObjectSchema,
|
|
22
|
+
});
|
|
23
|
+
const replaceOperationSchema = z.object({
|
|
24
|
+
op: z.literal("replace"),
|
|
25
|
+
reference: referenceObjectSchema,
|
|
26
|
+
property_name: z.enum(["name"]),
|
|
27
|
+
value: z.string(),
|
|
28
|
+
});
|
|
29
|
+
export const collectionPatchOperationSchema = z.discriminatedUnion("op", [
|
|
30
|
+
addIntoOperationSchema,
|
|
31
|
+
moveOperationSchema,
|
|
32
|
+
removeOperationSchema,
|
|
33
|
+
replaceOperationSchema,
|
|
34
|
+
]);
|
|
35
|
+
export const collectionPatchOperationsSchema = z
|
|
36
|
+
.array(collectionPatchOperationSchema)
|
|
37
|
+
.min(1);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { referenceObjectSchema } from "./referenceObjectSchema.js";
|
|
3
|
+
export const addLanguageSchema = z.object({
|
|
4
|
+
name: z.string().describe("Display name of the language"),
|
|
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
|
+
fallback_language: referenceObjectSchema
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Reference to fallback language (by id, codename, or external_id)"),
|
|
13
|
+
external_id: z.string().optional().describe("External ID for the language"),
|
|
14
|
+
});
|
|
15
|
+
const languageReplaceOperationSchema = z.discriminatedUnion("property_name", [
|
|
16
|
+
z.object({
|
|
17
|
+
op: z.literal("replace"),
|
|
18
|
+
property_name: z.literal("codename"),
|
|
19
|
+
value: z.string(),
|
|
20
|
+
}),
|
|
21
|
+
z.object({
|
|
22
|
+
op: z.literal("replace"),
|
|
23
|
+
property_name: z.literal("name"),
|
|
24
|
+
value: z.string(),
|
|
25
|
+
}),
|
|
26
|
+
z.object({
|
|
27
|
+
op: z.literal("replace"),
|
|
28
|
+
property_name: z.literal("is_active"),
|
|
29
|
+
value: z.boolean(),
|
|
30
|
+
}),
|
|
31
|
+
z.object({
|
|
32
|
+
op: z.literal("replace"),
|
|
33
|
+
property_name: z.literal("fallback_language"),
|
|
34
|
+
value: referenceObjectSchema,
|
|
35
|
+
}),
|
|
36
|
+
]);
|
|
37
|
+
export const patchLanguageSchema = z.object({
|
|
38
|
+
languageId: z.string().describe("Language ID to modify"),
|
|
39
|
+
operations: z
|
|
40
|
+
.array(languageReplaceOperationSchema)
|
|
41
|
+
.min(1)
|
|
42
|
+
.describe("Array of replace operations for codename, name, is_active, or fallback_language. Note: Only active languages can be modified - if language is deactivated, is_active: true must be first operation."),
|
|
43
|
+
});
|
|
@@ -24,3 +24,19 @@ export const listContentTypeSnippetsSchema = z.object({
|
|
|
24
24
|
export const listAssetsSchema = z.object({
|
|
25
25
|
continuation_token: continuationTokenField,
|
|
26
26
|
});
|
|
27
|
+
export const listVariantsCollectionSchema = z.object({
|
|
28
|
+
collectionId: z.string().describe("Collection ID"),
|
|
29
|
+
continuation_token: continuationTokenField,
|
|
30
|
+
});
|
|
31
|
+
export const listVariantsTypeSchema = z.object({
|
|
32
|
+
contentTypeId: z.string().describe("Content type ID"),
|
|
33
|
+
continuation_token: continuationTokenField,
|
|
34
|
+
});
|
|
35
|
+
export const listVariantsComponentsTypeSchema = z.object({
|
|
36
|
+
contentTypeId: z.string().describe("Content type ID"),
|
|
37
|
+
continuation_token: continuationTokenField,
|
|
38
|
+
});
|
|
39
|
+
export const listVariantsSpaceSchema = z.object({
|
|
40
|
+
spaceId: z.string().describe("Space ID"),
|
|
41
|
+
continuation_token: continuationTokenField,
|
|
42
|
+
});
|
|
@@ -4,7 +4,7 @@ const taxonomyTermSchema = z.object({
|
|
|
4
4
|
name: z.string(),
|
|
5
5
|
codename: z.string().optional(),
|
|
6
6
|
external_id: z.string().optional(),
|
|
7
|
-
terms: z.lazy(() => z.array(taxonomyTermSchema)),
|
|
7
|
+
terms: z.lazy(() => z.array(taxonomyTermSchema)).optional(),
|
|
8
8
|
});
|
|
9
9
|
// Schema for a taxonomy group
|
|
10
10
|
export const taxonomyGroupSchemas = {
|
|
@@ -14,5 +14,8 @@ export const taxonomyGroupSchemas = {
|
|
|
14
14
|
.optional()
|
|
15
15
|
.describe("Codename (auto-generated if omitted)"),
|
|
16
16
|
external_id: z.string().optional().describe("External ID"),
|
|
17
|
-
terms: z
|
|
17
|
+
terms: z
|
|
18
|
+
.array(taxonomyTermSchema)
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Taxonomy terms hierarchy"),
|
|
18
21
|
};
|
package/build/server.js
CHANGED
|
@@ -3,6 +3,7 @@ import packageJson from "../package.json" with { type: "json" };
|
|
|
3
3
|
import { registerTool as registerAddContentItemMapi } from "./tools/add-content-item-mapi.js";
|
|
4
4
|
import { registerTool as registerAddContentTypeMapi } from "./tools/add-content-type-mapi.js";
|
|
5
5
|
import { registerTool as registerAddContentTypeSnippetMapi } from "./tools/add-content-type-snippet-mapi.js";
|
|
6
|
+
import { registerTool as registerAddLanguageMapi } from "./tools/add-language-mapi.js";
|
|
6
7
|
import { registerTool as registerAddTaxonomyGroupMapi } from "./tools/add-taxonomy-group-mapi.js";
|
|
7
8
|
import { registerTool as registerChangeVariantWorkflowStepMapi } from "./tools/change-variant-workflow-step-mapi.js";
|
|
8
9
|
import { registerTool as registerCreateVariantVersionMapi } from "./tools/create-variant-version-mapi.js";
|
|
@@ -13,17 +14,27 @@ import { registerTool as registerFilterVariantsMapi } from "./tools/filter-varia
|
|
|
13
14
|
import { registerTool as registerGetAssetMapi } from "./tools/get-asset-mapi.js";
|
|
14
15
|
import { registerTool as registerGetInitialContext } from "./tools/get-initial-context.js";
|
|
15
16
|
import { registerTool as registerGetItemMapi } from "./tools/get-item-mapi.js";
|
|
17
|
+
import { registerTool as registerGetLatestVariantMapi } from "./tools/get-latest-variant-mapi.js";
|
|
18
|
+
import { registerTool as registerGetPublishedVariantMapi } from "./tools/get-published-variant-mapi.js";
|
|
16
19
|
import { registerTool as registerGetTaxonomyGroupMapi } from "./tools/get-taxonomy-group-mapi.js";
|
|
17
20
|
import { registerTool as registerGetTypeMapi } from "./tools/get-type-mapi.js";
|
|
18
21
|
import { registerTool as registerGetTypeSnippetMapi } from "./tools/get-type-snippet-mapi.js";
|
|
19
|
-
import { registerTool as registerGetVariantMapi } from "./tools/get-variant-mapi.js";
|
|
20
22
|
import { registerTool as registerListAssetsMapi } from "./tools/list-assets-mapi.js";
|
|
23
|
+
import { registerTool as registerListCollectionsMapi } from "./tools/list-collections-mapi.js";
|
|
21
24
|
import { registerTool as registerListContentTypeSnippetsMapi } from "./tools/list-content-type-snippets-mapi.js";
|
|
22
25
|
import { registerTool as registerListContentTypesMapi } from "./tools/list-content-types-mapi.js";
|
|
23
26
|
import { registerTool as registerListLanguagesMapi } from "./tools/list-languages-mapi.js";
|
|
27
|
+
import { registerTool as registerListSpacesMapi } from "./tools/list-spaces-mapi.js";
|
|
24
28
|
import { registerTool as registerListTaxonomyGroupsMapi } from "./tools/list-taxonomy-groups-mapi.js";
|
|
29
|
+
import { registerTool as registerListVariantsCollectionMapi } from "./tools/list-variants-collection-mapi.js";
|
|
30
|
+
import { registerTool as registerListVariantsComponentsTypeMapi } from "./tools/list-variants-components-type-mapi.js";
|
|
31
|
+
import { registerTool as registerListVariantsItemMapi } from "./tools/list-variants-item-mapi.js";
|
|
32
|
+
import { registerTool as registerListVariantsSpaceMapi } from "./tools/list-variants-space-mapi.js";
|
|
33
|
+
import { registerTool as registerListVariantsTypeMapi } from "./tools/list-variants-type-mapi.js";
|
|
25
34
|
import { registerTool as registerListWorkflowsMapi } from "./tools/list-workflows-mapi.js";
|
|
35
|
+
import { registerTool as registerPatchCollectionsMapi } from "./tools/patch-collections-mapi.js";
|
|
26
36
|
import { registerTool as registerPatchContentTypeMapi } from "./tools/patch-content-type-mapi.js";
|
|
37
|
+
import { registerTool as registerPatchLanguageMapi } from "./tools/patch-language-mapi.js";
|
|
27
38
|
import { registerTool as registerPublishVariantMapi } from "./tools/publish-variant-mapi.js";
|
|
28
39
|
import { registerTool as registerSearchVariantsMapi } from "./tools/search-variants-mapi.js";
|
|
29
40
|
import { registerTool as registerUnpublishVariantMapi } from "./tools/unpublish-variant-mapi.js";
|
|
@@ -42,11 +53,22 @@ export const createServer = () => {
|
|
|
42
53
|
// Register all tools
|
|
43
54
|
registerGetInitialContext(server);
|
|
44
55
|
registerGetItemMapi(server);
|
|
45
|
-
|
|
56
|
+
registerGetLatestVariantMapi(server);
|
|
57
|
+
registerGetPublishedVariantMapi(server);
|
|
58
|
+
registerListVariantsItemMapi(server);
|
|
59
|
+
registerListVariantsCollectionMapi(server);
|
|
60
|
+
registerListVariantsTypeMapi(server);
|
|
61
|
+
registerListVariantsComponentsTypeMapi(server);
|
|
62
|
+
registerListVariantsSpaceMapi(server);
|
|
46
63
|
registerGetTypeMapi(server);
|
|
47
64
|
registerListContentTypesMapi(server);
|
|
48
65
|
registerDeleteContentTypeMapi(server);
|
|
49
66
|
registerListLanguagesMapi(server);
|
|
67
|
+
registerAddLanguageMapi(server);
|
|
68
|
+
registerPatchLanguageMapi(server);
|
|
69
|
+
registerListCollectionsMapi(server);
|
|
70
|
+
registerPatchCollectionsMapi(server);
|
|
71
|
+
registerListSpacesMapi(server);
|
|
50
72
|
registerGetAssetMapi(server);
|
|
51
73
|
registerListAssetsMapi(server);
|
|
52
74
|
registerAddContentTypeMapi(server);
|