@kontent-ai/mcp-server 0.4.2 → 0.6.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 +127 -32
- package/build/bin.js +11 -7
- package/build/clients/kontentClients.js +12 -8
- package/build/schemas/contentItemSchemas.js +205 -0
- package/build/schemas/contentTypeSchemas.js +250 -127
- package/build/schemas/taxonomySchemas.js +11 -3
- package/build/server.js +22 -11
- package/build/tools/add-content-item-mapi.js +54 -0
- package/build/tools/add-content-type-mapi.js +35 -28
- package/build/tools/add-content-type-snippet-mapi.js +31 -29
- package/build/tools/add-taxonomy-group-mapi.js +14 -14
- package/build/tools/delete-content-item-mapi.js +24 -0
- package/build/tools/delete-language-variant-mapi.js +28 -0
- package/build/tools/get-asset-mapi.js +14 -14
- package/build/tools/get-item-dapi.js +13 -13
- package/build/tools/get-item-mapi.js +14 -14
- package/build/tools/get-taxonomy-group-mapi.js +14 -14
- package/build/tools/get-type-mapi.js +14 -14
- package/build/tools/get-type-snippet-mapi.js +16 -14
- package/build/tools/get-variant-mapi.js +17 -15
- package/build/tools/list-assets-mapi.js +10 -12
- package/build/tools/list-content-type-snippets-mapi.js +10 -12
- package/build/tools/list-content-types-mapi.js +10 -12
- package/build/tools/list-languages-mapi.js +10 -12
- package/build/tools/list-taxonomy-groups-mapi.js +11 -13
- package/build/tools/update-content-item-mapi.js +74 -0
- package/build/tools/upsert-language-variant-mapi.js +46 -0
- package/build/utils/errorHandler.js +87 -0
- package/build/utils/responseHelper.js +18 -0
- package/build/utils/throwError.js +3 -0
- package/package.json +13 -5
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
// Define a reusable reference object schema
|
|
3
|
-
const referenceObjectSchema = z
|
|
3
|
+
const referenceObjectSchema = z
|
|
4
|
+
.object({
|
|
4
5
|
id: z.string().optional(),
|
|
5
6
|
codename: z.string().optional(),
|
|
6
|
-
})
|
|
7
|
+
})
|
|
8
|
+
.describe("An object with an id or codename property referencing another item. Using codename is preferred for better readability.");
|
|
7
9
|
// Common property schemas
|
|
8
10
|
const baseElementSchema = {
|
|
9
11
|
codename: z.string().optional(),
|
|
10
12
|
external_id: z.string().optional(),
|
|
13
|
+
};
|
|
14
|
+
// Content group schema for content type elements only
|
|
15
|
+
const contentGroupElementSchema = {
|
|
11
16
|
content_group: referenceObjectSchema
|
|
12
17
|
.describe("An object with an id or codename property referencing a content group.")
|
|
13
18
|
.optional(),
|
|
@@ -20,174 +25,292 @@ const namedElementSchema = {
|
|
|
20
25
|
is_non_localizable: z.boolean().optional(),
|
|
21
26
|
};
|
|
22
27
|
// Limit schemas
|
|
23
|
-
const conditionEnum = z.enum([
|
|
24
|
-
const countLimitSchema = z
|
|
28
|
+
const conditionEnum = z.enum(["at_most", "exactly", "at_least"]);
|
|
29
|
+
const countLimitSchema = z
|
|
30
|
+
.object({
|
|
25
31
|
value: z.number(),
|
|
26
|
-
condition: conditionEnum
|
|
27
|
-
})
|
|
32
|
+
condition: conditionEnum,
|
|
33
|
+
})
|
|
34
|
+
.optional();
|
|
28
35
|
const imageLimitSchema = {
|
|
29
|
-
image_width_limit: z
|
|
36
|
+
image_width_limit: z
|
|
37
|
+
.object({
|
|
30
38
|
value: z.number(),
|
|
31
|
-
condition: conditionEnum
|
|
32
|
-
})
|
|
33
|
-
|
|
39
|
+
condition: conditionEnum,
|
|
40
|
+
})
|
|
41
|
+
.optional(),
|
|
42
|
+
image_height_limit: z
|
|
43
|
+
.object({
|
|
34
44
|
value: z.number(),
|
|
35
|
-
condition: conditionEnum
|
|
36
|
-
})
|
|
45
|
+
condition: conditionEnum,
|
|
46
|
+
})
|
|
47
|
+
.optional(),
|
|
37
48
|
};
|
|
38
49
|
// Default value schemas
|
|
39
|
-
const arrayDefaultSchema =
|
|
50
|
+
const arrayDefaultSchema = z
|
|
51
|
+
.object({
|
|
40
52
|
global: z.object({
|
|
41
|
-
value: z.array(
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
|
|
53
|
+
value: z.array(referenceObjectSchema),
|
|
54
|
+
}),
|
|
55
|
+
})
|
|
56
|
+
.optional();
|
|
57
|
+
const stringDefaultSchema = z
|
|
58
|
+
.object({
|
|
45
59
|
global: z.object({
|
|
46
|
-
value: z.string()
|
|
47
|
-
})
|
|
48
|
-
})
|
|
49
|
-
|
|
60
|
+
value: z.string(),
|
|
61
|
+
}),
|
|
62
|
+
})
|
|
63
|
+
.optional();
|
|
64
|
+
const numberDefaultSchema = z
|
|
65
|
+
.object({
|
|
50
66
|
global: z.object({
|
|
51
|
-
value: z.number()
|
|
52
|
-
})
|
|
53
|
-
})
|
|
67
|
+
value: z.number(),
|
|
68
|
+
}),
|
|
69
|
+
})
|
|
70
|
+
.optional();
|
|
54
71
|
// Regex validation schema
|
|
55
|
-
const regexValidationSchema = z
|
|
72
|
+
const regexValidationSchema = z
|
|
73
|
+
.object({
|
|
56
74
|
is_active: z.boolean(),
|
|
57
75
|
regex: z.string(),
|
|
58
76
|
flags: z.string().optional(),
|
|
59
|
-
validation_message: z.string().optional()
|
|
60
|
-
})
|
|
77
|
+
validation_message: z.string().optional(),
|
|
78
|
+
})
|
|
79
|
+
.optional();
|
|
61
80
|
// Text length limit schema
|
|
62
|
-
const textLengthLimitSchema = z
|
|
81
|
+
const textLengthLimitSchema = z
|
|
82
|
+
.object({
|
|
63
83
|
value: z.number(),
|
|
64
|
-
applies_to: z.enum([
|
|
65
|
-
})
|
|
84
|
+
applies_to: z.enum(["words", "characters"]),
|
|
85
|
+
})
|
|
86
|
+
.optional();
|
|
66
87
|
// Individual element type schemas
|
|
67
|
-
const assetElementSchema =
|
|
68
|
-
type: z.literal(
|
|
88
|
+
const assetElementSchema = {
|
|
89
|
+
type: z.literal("asset"),
|
|
69
90
|
...namedElementSchema,
|
|
70
91
|
asset_count_limit: countLimitSchema,
|
|
71
92
|
maximum_file_size: z.number().optional(),
|
|
72
|
-
allowed_file_types: z.enum([
|
|
93
|
+
allowed_file_types: z.enum(["adjustable", "any"]).optional(),
|
|
73
94
|
...imageLimitSchema,
|
|
74
|
-
default: arrayDefaultSchema(),
|
|
75
|
-
}
|
|
76
|
-
const customElementSchema =
|
|
77
|
-
type: z.literal(
|
|
95
|
+
default: arrayDefaultSchema.describe("Default value of the asset element. Reference an existing asset by its id or codename."),
|
|
96
|
+
};
|
|
97
|
+
const customElementSchema = {
|
|
98
|
+
type: z.literal("custom"),
|
|
78
99
|
...namedElementSchema,
|
|
79
100
|
source_url: z.string(),
|
|
80
101
|
json_parameters: z.string().optional(),
|
|
81
|
-
allowed_elements: z
|
|
82
|
-
.describe("An object with an id or codename property referencing an element."))
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
102
|
+
allowed_elements: z
|
|
103
|
+
.array(referenceObjectSchema.describe("An object with an id or codename property referencing an element."))
|
|
104
|
+
.optional()
|
|
105
|
+
.describe("Specifies which elements from the content type can be used within this custom element."),
|
|
106
|
+
};
|
|
107
|
+
const dateTimeElementSchema = {
|
|
108
|
+
type: z.literal("date_time"),
|
|
86
109
|
...namedElementSchema,
|
|
87
110
|
default: stringDefaultSchema,
|
|
88
|
-
}
|
|
89
|
-
const guidelinesElementSchema =
|
|
90
|
-
type: z.literal(
|
|
91
|
-
guidelines: z.string(),
|
|
111
|
+
};
|
|
112
|
+
const guidelinesElementSchema = {
|
|
113
|
+
type: z.literal("guidelines"),
|
|
92
114
|
...baseElementSchema,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
guidelines: z
|
|
116
|
+
.string()
|
|
117
|
+
.describe("Value of the guidelines element. This is rich text and can include HTML formatting. Check the documentation here https://kontent.ai/learn/docs/apis/openapi/management-api-v2/#section/HTML5-elements-allowed-in-rich-text for the supported format, but keep in mind that content items and components are not supported in guidelines. Use empty `<p>` tag for empty guidelines."),
|
|
118
|
+
};
|
|
119
|
+
const modularContentElementSchema = {
|
|
120
|
+
type: z.literal("modular_content"),
|
|
96
121
|
...namedElementSchema,
|
|
97
|
-
allowed_content_types: z
|
|
98
|
-
.describe("An object with an id or codename property referencing a content type."))
|
|
122
|
+
allowed_content_types: z
|
|
123
|
+
.array(referenceObjectSchema.describe("An object with an id or codename property referencing a content type. Use an empty array to allow all content types."))
|
|
124
|
+
.optional(),
|
|
99
125
|
item_count_limit: countLimitSchema,
|
|
100
|
-
default: arrayDefaultSchema(),
|
|
101
|
-
}
|
|
102
|
-
const subpagesElementSchema =
|
|
103
|
-
type: z.literal(
|
|
126
|
+
default: arrayDefaultSchema.describe("Default value of the modular content element. Reference an existing content item by its id or codename."),
|
|
127
|
+
};
|
|
128
|
+
const subpagesElementSchema = {
|
|
129
|
+
type: z.literal("subpages"),
|
|
104
130
|
...namedElementSchema,
|
|
105
|
-
allowed_content_types: z
|
|
106
|
-
.describe("An object with an id or codename property referencing a content type."))
|
|
131
|
+
allowed_content_types: z
|
|
132
|
+
.array(referenceObjectSchema.describe("An object with an id or codename property referencing a content type. Use an empty array to allow all content types."))
|
|
133
|
+
.optional(),
|
|
107
134
|
item_count_limit: countLimitSchema,
|
|
108
|
-
}
|
|
109
|
-
const multipleChoiceElementSchema =
|
|
110
|
-
type: z.literal(
|
|
135
|
+
};
|
|
136
|
+
const multipleChoiceElementSchema = {
|
|
137
|
+
type: z.literal("multiple_choice"),
|
|
111
138
|
...namedElementSchema,
|
|
112
|
-
mode: z.enum([
|
|
139
|
+
mode: z.enum(["single", "multiple"]),
|
|
113
140
|
options: z.array(z.object({
|
|
114
141
|
name: z.string(),
|
|
115
142
|
codename: z.string().optional(),
|
|
116
143
|
external_id: z.string().optional(),
|
|
117
144
|
})),
|
|
118
|
-
default: arrayDefaultSchema(),
|
|
119
|
-
}
|
|
120
|
-
const numberElementSchema =
|
|
121
|
-
type: z.literal(
|
|
145
|
+
default: arrayDefaultSchema.describe("Default value of the multiple choice element. Reference one of the options by its codename."),
|
|
146
|
+
};
|
|
147
|
+
const numberElementSchema = {
|
|
148
|
+
type: z.literal("number"),
|
|
122
149
|
...namedElementSchema,
|
|
123
150
|
default: numberDefaultSchema,
|
|
124
|
-
}
|
|
125
|
-
const richTextElementSchema =
|
|
126
|
-
type: z.literal(
|
|
151
|
+
};
|
|
152
|
+
const richTextElementSchema = {
|
|
153
|
+
type: z.literal("rich_text"),
|
|
127
154
|
...namedElementSchema,
|
|
128
|
-
allowed_blocks: z
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
155
|
+
allowed_blocks: z
|
|
156
|
+
.array(z.enum(["images", "text", "tables", "components-and-items"]))
|
|
157
|
+
.optional()
|
|
158
|
+
.describe("Specifies allowed blocks. Use an empty array to allow all options."),
|
|
159
|
+
allowed_formatting: z
|
|
160
|
+
.array(z.enum([
|
|
161
|
+
"unstyled",
|
|
162
|
+
"bold",
|
|
163
|
+
"italic",
|
|
164
|
+
"code",
|
|
165
|
+
"link",
|
|
166
|
+
"subscript",
|
|
167
|
+
"superscript",
|
|
168
|
+
]))
|
|
169
|
+
.optional()
|
|
170
|
+
.describe("Specifies allowed formatting options. Use an empty array to allow all options."),
|
|
171
|
+
allowed_text_blocks: z
|
|
172
|
+
.array(z.enum([
|
|
173
|
+
"paragraph",
|
|
174
|
+
"heading-one",
|
|
175
|
+
"heading-two",
|
|
176
|
+
"heading-three",
|
|
177
|
+
"heading-four",
|
|
178
|
+
"heading-five",
|
|
179
|
+
"heading-six",
|
|
180
|
+
"ordered-list",
|
|
181
|
+
"unordered-list",
|
|
182
|
+
]))
|
|
183
|
+
.optional()
|
|
184
|
+
.describe("Specifies allowed text blocks. Use an empty array to allow all options."),
|
|
185
|
+
allowed_table_blocks: z
|
|
186
|
+
.array(z.enum(["images", "text"]))
|
|
187
|
+
.optional()
|
|
188
|
+
.describe("Specifies allowed table blocks. Use an empty array to allow all options."),
|
|
189
|
+
allowed_table_formatting: z
|
|
190
|
+
.array(z.enum([
|
|
191
|
+
"unstyled",
|
|
192
|
+
"bold",
|
|
193
|
+
"italic",
|
|
194
|
+
"code",
|
|
195
|
+
"link",
|
|
196
|
+
"subscript",
|
|
197
|
+
"superscript",
|
|
198
|
+
]))
|
|
199
|
+
.optional()
|
|
200
|
+
.describe("Specifies allowed table formatting options. Use an empty array to allow all options."),
|
|
201
|
+
allowed_table_text_blocks: z
|
|
202
|
+
.array(z.enum([
|
|
203
|
+
"paragraph",
|
|
204
|
+
"heading-one",
|
|
205
|
+
"heading-two",
|
|
206
|
+
"heading-three",
|
|
207
|
+
"heading-four",
|
|
208
|
+
"heading-five",
|
|
209
|
+
"heading-six",
|
|
210
|
+
"ordered-list",
|
|
211
|
+
"unordered-list",
|
|
212
|
+
]))
|
|
213
|
+
.optional()
|
|
214
|
+
.describe("Specifies allowed table text blocks. Use an empty array to allow all options."),
|
|
215
|
+
allowed_content_types: z
|
|
216
|
+
.array(referenceObjectSchema.describe("An object with an id or codename property referencing a content type."))
|
|
217
|
+
.optional()
|
|
218
|
+
.describe("Specifies allowed content types. Use an empty array to allow all content types."),
|
|
219
|
+
allowed_item_link_types: z
|
|
220
|
+
.array(referenceObjectSchema.describe("An object with an id or codename property referencing a content type."))
|
|
221
|
+
.optional()
|
|
222
|
+
.describe("Specifies allowed item link types. Use an empty array to allow all link types."),
|
|
138
223
|
...imageLimitSchema,
|
|
139
|
-
allowed_image_types: z.enum([
|
|
224
|
+
allowed_image_types: z.enum(["adjustable", "any"]).optional(),
|
|
140
225
|
maximum_image_size: z.number().optional(),
|
|
141
226
|
maximum_text_length: textLengthLimitSchema,
|
|
142
|
-
}
|
|
143
|
-
const snippetElement =
|
|
144
|
-
type: z.literal(
|
|
145
|
-
snippet: referenceObjectSchema
|
|
146
|
-
.describe("An object with an id or codename property referencing a snippet."),
|
|
227
|
+
};
|
|
228
|
+
const snippetElement = {
|
|
229
|
+
type: z.literal("snippet"),
|
|
230
|
+
snippet: referenceObjectSchema.describe("An object with an id or codename property referencing a snippet."),
|
|
147
231
|
...baseElementSchema,
|
|
148
|
-
}
|
|
149
|
-
const taxonomyElementSchema =
|
|
150
|
-
type: z.literal(
|
|
151
|
-
taxonomy_group: referenceObjectSchema
|
|
152
|
-
.describe("An object with an id or codename property referencing a taxonomy group."),
|
|
232
|
+
};
|
|
233
|
+
const taxonomyElementSchema = {
|
|
234
|
+
type: z.literal("taxonomy"),
|
|
235
|
+
taxonomy_group: referenceObjectSchema.describe("An object with an id or codename property referencing a taxonomy group."),
|
|
153
236
|
...namedElementSchema,
|
|
154
237
|
term_count_limit: countLimitSchema,
|
|
155
|
-
default: arrayDefaultSchema(),
|
|
156
|
-
}
|
|
157
|
-
const textElementSchema =
|
|
158
|
-
type: z.literal(
|
|
238
|
+
default: arrayDefaultSchema.describe("Default value of the taxonomy element. Reference one of the terms from the specified taxonomy group by its codename."),
|
|
239
|
+
};
|
|
240
|
+
const textElementSchema = {
|
|
241
|
+
type: z.literal("text"),
|
|
159
242
|
...namedElementSchema,
|
|
160
243
|
maximum_text_length: textLengthLimitSchema,
|
|
161
244
|
validation_regex: regexValidationSchema,
|
|
162
245
|
default: stringDefaultSchema,
|
|
163
|
-
}
|
|
164
|
-
const urlSlugElementSchema =
|
|
165
|
-
type: z.literal(
|
|
246
|
+
};
|
|
247
|
+
const urlSlugElementSchema = {
|
|
248
|
+
type: z.literal("url_slug"),
|
|
166
249
|
...namedElementSchema,
|
|
167
|
-
depends_on: z
|
|
168
|
-
|
|
169
|
-
|
|
250
|
+
depends_on: z
|
|
251
|
+
.object({
|
|
252
|
+
element: referenceObjectSchema.describe("An object with an id or codename property referencing an element."),
|
|
170
253
|
snippet: referenceObjectSchema
|
|
171
254
|
.describe("An object with an id or codename property referencing a content type snippet.")
|
|
172
255
|
.optional(),
|
|
173
|
-
})
|
|
256
|
+
})
|
|
257
|
+
.describe("The element the URL slug depends on. If this element is within a snippet, the snippet must also be specified."),
|
|
174
258
|
validation_regex: regexValidationSchema,
|
|
175
|
-
}
|
|
259
|
+
};
|
|
176
260
|
// Define a union type of all possible element types for content types
|
|
177
|
-
export const elementSchema = z.discriminatedUnion(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
261
|
+
export const elementSchema = z.discriminatedUnion("type", [
|
|
262
|
+
z.object({
|
|
263
|
+
...assetElementSchema,
|
|
264
|
+
...contentGroupElementSchema,
|
|
265
|
+
}),
|
|
266
|
+
z.object({
|
|
267
|
+
...customElementSchema,
|
|
268
|
+
...contentGroupElementSchema,
|
|
269
|
+
}),
|
|
270
|
+
z.object({
|
|
271
|
+
...dateTimeElementSchema,
|
|
272
|
+
...contentGroupElementSchema,
|
|
273
|
+
}),
|
|
274
|
+
z.object({
|
|
275
|
+
...guidelinesElementSchema,
|
|
276
|
+
...contentGroupElementSchema,
|
|
277
|
+
}),
|
|
278
|
+
z.object({
|
|
279
|
+
...modularContentElementSchema,
|
|
280
|
+
...contentGroupElementSchema,
|
|
281
|
+
}),
|
|
282
|
+
z.object({
|
|
283
|
+
...subpagesElementSchema,
|
|
284
|
+
...contentGroupElementSchema,
|
|
285
|
+
}),
|
|
286
|
+
z.object({
|
|
287
|
+
...multipleChoiceElementSchema,
|
|
288
|
+
...contentGroupElementSchema,
|
|
289
|
+
}),
|
|
290
|
+
z.object({
|
|
291
|
+
...numberElementSchema,
|
|
292
|
+
...contentGroupElementSchema,
|
|
293
|
+
}),
|
|
294
|
+
z.object({
|
|
295
|
+
...richTextElementSchema,
|
|
296
|
+
...contentGroupElementSchema,
|
|
297
|
+
}),
|
|
298
|
+
z.object({
|
|
299
|
+
...snippetElement,
|
|
300
|
+
...contentGroupElementSchema,
|
|
301
|
+
}),
|
|
302
|
+
z.object({
|
|
303
|
+
...taxonomyElementSchema,
|
|
304
|
+
...contentGroupElementSchema,
|
|
305
|
+
}),
|
|
306
|
+
z.object({
|
|
307
|
+
...textElementSchema,
|
|
308
|
+
...contentGroupElementSchema,
|
|
309
|
+
}),
|
|
310
|
+
z.object({
|
|
311
|
+
...urlSlugElementSchema,
|
|
312
|
+
...contentGroupElementSchema,
|
|
313
|
+
}),
|
|
191
314
|
]);
|
|
192
315
|
// Define schema for content groups
|
|
193
316
|
export const contentGroupSchema = z.object({
|
|
@@ -196,16 +319,16 @@ export const contentGroupSchema = z.object({
|
|
|
196
319
|
codename: z.string().optional(),
|
|
197
320
|
});
|
|
198
321
|
// Define a union type for snippet elements (excluding url_slug and snippet elements)
|
|
199
|
-
export const snippetElementSchema = z.discriminatedUnion(
|
|
200
|
-
assetElementSchema,
|
|
201
|
-
customElementSchema,
|
|
202
|
-
dateTimeElementSchema,
|
|
203
|
-
guidelinesElementSchema,
|
|
204
|
-
modularContentElementSchema,
|
|
205
|
-
subpagesElementSchema,
|
|
206
|
-
multipleChoiceElementSchema,
|
|
207
|
-
numberElementSchema,
|
|
208
|
-
richTextElementSchema,
|
|
209
|
-
taxonomyElementSchema,
|
|
210
|
-
textElementSchema,
|
|
322
|
+
export const snippetElementSchema = z.discriminatedUnion("type", [
|
|
323
|
+
z.object(assetElementSchema),
|
|
324
|
+
z.object(customElementSchema),
|
|
325
|
+
z.object(dateTimeElementSchema),
|
|
326
|
+
z.object(guidelinesElementSchema),
|
|
327
|
+
z.object(modularContentElementSchema),
|
|
328
|
+
z.object(subpagesElementSchema),
|
|
329
|
+
z.object(multipleChoiceElementSchema),
|
|
330
|
+
z.object(numberElementSchema),
|
|
331
|
+
z.object(richTextElementSchema),
|
|
332
|
+
z.object(taxonomyElementSchema),
|
|
333
|
+
z.object(textElementSchema),
|
|
211
334
|
]);
|
|
@@ -9,7 +9,15 @@ const taxonomyTermSchema = z.object({
|
|
|
9
9
|
// Schema for a taxonomy group
|
|
10
10
|
export const taxonomyGroupSchemas = {
|
|
11
11
|
name: z.string().describe("Display name of the taxonomy group"),
|
|
12
|
-
codename: z
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
codename: z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Codename of the taxonomy group (optional, will be generated if not provided)"),
|
|
16
|
+
external_id: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("External ID of the taxonomy group (optional)"),
|
|
20
|
+
terms: z
|
|
21
|
+
.array(taxonomyTermSchema)
|
|
22
|
+
.describe("Hierarchical structure of taxonomy terms"),
|
|
15
23
|
};
|
package/build/server.js
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import
|
|
3
|
-
import { registerTool as
|
|
4
|
-
import { registerTool as registerGetVariantMapi } from "./tools/get-variant-mapi.js";
|
|
5
|
-
import { registerTool as registerGetTypeMapi } from "./tools/get-type-mapi.js";
|
|
6
|
-
import { registerTool as registerListContentTypesMapi } from "./tools/list-content-types-mapi.js";
|
|
7
|
-
import { registerTool as registerListLanguagesMapi } from "./tools/list-languages-mapi.js";
|
|
8
|
-
import { registerTool as registerGetAssetMapi } from "./tools/get-asset-mapi.js";
|
|
9
|
-
import { registerTool as registerListAssetsMapi } from "./tools/list-assets-mapi.js";
|
|
2
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
3
|
+
import { registerTool as registerAddContentItemMapi } from "./tools/add-content-item-mapi.js";
|
|
10
4
|
import { registerTool as registerAddContentTypeMapi } from "./tools/add-content-type-mapi.js";
|
|
11
5
|
import { registerTool as registerAddContentTypeSnippetMapi } from "./tools/add-content-type-snippet-mapi.js";
|
|
6
|
+
import { registerTool as registerAddTaxonomyGroupMapi } from "./tools/add-taxonomy-group-mapi.js";
|
|
7
|
+
import { registerTool as registerDeleteContentItemMapi } from "./tools/delete-content-item-mapi.js";
|
|
8
|
+
import { registerTool as registerDeleteLanguageVariantMapi } from "./tools/delete-language-variant-mapi.js";
|
|
9
|
+
import { registerTool as registerGetAssetMapi } from "./tools/get-asset-mapi.js";
|
|
10
|
+
import { registerTool as registerGetItemDapi } from "./tools/get-item-dapi.js";
|
|
11
|
+
import { registerTool as registerGetItemMapi } from "./tools/get-item-mapi.js";
|
|
12
|
+
import { registerTool as registerGetTaxonomyGroupMapi } from "./tools/get-taxonomy-group-mapi.js";
|
|
13
|
+
import { registerTool as registerGetTypeMapi } from "./tools/get-type-mapi.js";
|
|
12
14
|
import { registerTool as registerGetTypeSnippetMapi } from "./tools/get-type-snippet-mapi.js";
|
|
15
|
+
import { registerTool as registerGetVariantMapi } from "./tools/get-variant-mapi.js";
|
|
16
|
+
import { registerTool as registerListAssetsMapi } from "./tools/list-assets-mapi.js";
|
|
13
17
|
import { registerTool as registerListContentTypeSnippetsMapi } from "./tools/list-content-type-snippets-mapi.js";
|
|
14
|
-
import { registerTool as
|
|
18
|
+
import { registerTool as registerListContentTypesMapi } from "./tools/list-content-types-mapi.js";
|
|
19
|
+
import { registerTool as registerListLanguagesMapi } from "./tools/list-languages-mapi.js";
|
|
15
20
|
import { registerTool as registerListTaxonomyGroupsMapi } from "./tools/list-taxonomy-groups-mapi.js";
|
|
16
|
-
import { registerTool as
|
|
21
|
+
import { registerTool as registerUpdateContentItemMapi } from "./tools/update-content-item-mapi.js";
|
|
22
|
+
import { registerTool as registerUpsertLanguageVariantMapi } from "./tools/upsert-language-variant-mapi.js";
|
|
17
23
|
// Create server instance
|
|
18
24
|
export const createServer = () => {
|
|
19
25
|
const server = new McpServer({
|
|
20
26
|
name: "kontent-ai",
|
|
21
|
-
version:
|
|
27
|
+
version: packageJson.version,
|
|
22
28
|
capabilities: {
|
|
23
29
|
resources: {},
|
|
24
30
|
tools: {},
|
|
@@ -40,5 +46,10 @@ export const createServer = () => {
|
|
|
40
46
|
registerAddTaxonomyGroupMapi(server);
|
|
41
47
|
registerListTaxonomyGroupsMapi(server);
|
|
42
48
|
registerGetTaxonomyGroupMapi(server);
|
|
49
|
+
registerAddContentItemMapi(server);
|
|
50
|
+
registerUpdateContentItemMapi(server);
|
|
51
|
+
registerDeleteContentItemMapi(server);
|
|
52
|
+
registerUpsertLanguageVariantMapi(server);
|
|
53
|
+
registerDeleteLanguageVariantMapi(server);
|
|
43
54
|
return { server };
|
|
44
55
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
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("add-content-item-mapi", "Add a new 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.", {
|
|
7
|
+
name: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.max(200)
|
|
11
|
+
.describe("Display name of the content item (1-200 characters)"),
|
|
12
|
+
type: z
|
|
13
|
+
.object({
|
|
14
|
+
id: z.string().optional(),
|
|
15
|
+
codename: z.string().optional(),
|
|
16
|
+
external_id: z.string().optional(),
|
|
17
|
+
})
|
|
18
|
+
.describe("Reference to the content type by id, codename, or external_id. At least one property must be specified."),
|
|
19
|
+
codename: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Codename of the content item (optional, will be generated from name if not provided)"),
|
|
23
|
+
external_id: z
|
|
24
|
+
.string()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("External ID for the content item (optional, useful for external system integration)"),
|
|
27
|
+
collection: z
|
|
28
|
+
.object({
|
|
29
|
+
id: z.string().optional(),
|
|
30
|
+
codename: z.string().optional(),
|
|
31
|
+
external_id: z.string().optional(),
|
|
32
|
+
})
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("Reference to a collection by id, codename, or external_id (optional)"),
|
|
35
|
+
}, async ({ name, type, codename, external_id, collection }) => {
|
|
36
|
+
const client = createMapiClient();
|
|
37
|
+
try {
|
|
38
|
+
const response = await client
|
|
39
|
+
.addContentItem()
|
|
40
|
+
.withData({
|
|
41
|
+
name,
|
|
42
|
+
type,
|
|
43
|
+
codename,
|
|
44
|
+
external_id,
|
|
45
|
+
collection,
|
|
46
|
+
})
|
|
47
|
+
.toPromise();
|
|
48
|
+
return createMcpToolSuccessResponse(response.rawData);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return handleMcpToolError(error, "Content Item Creation");
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
@@ -1,36 +1,43 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { createMapiClient } from
|
|
3
|
-
import { elementSchema,
|
|
2
|
+
import { createMapiClient } from "../clients/kontentClients.js";
|
|
3
|
+
import { contentGroupSchema, elementSchema, } 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-mapi", "Add a new content type via Management API", {
|
|
6
8
|
name: z.string().describe("Display name of the content type"),
|
|
7
|
-
codename: z
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
codename: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Codename of the content type (optional, will be generated if not provided)"),
|
|
13
|
+
external_id: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("External ID of the content type (optional)"),
|
|
17
|
+
elements: z
|
|
18
|
+
.array(elementSchema)
|
|
19
|
+
.describe("Array of elements that define the structure of the content type"),
|
|
20
|
+
content_groups: z
|
|
21
|
+
.array(contentGroupSchema)
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Array of content groups (optional)"),
|
|
11
24
|
}, async ({ name, codename, external_id, elements, content_groups }) => {
|
|
12
25
|
const client = createMapiClient();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
type: "text",
|
|
31
|
-
text: JSON.stringify(response.rawData),
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
};
|
|
26
|
+
try {
|
|
27
|
+
const response = await client
|
|
28
|
+
.addContentType()
|
|
29
|
+
.withData(() => ({
|
|
30
|
+
name,
|
|
31
|
+
codename,
|
|
32
|
+
external_id,
|
|
33
|
+
elements,
|
|
34
|
+
content_groups,
|
|
35
|
+
}))
|
|
36
|
+
.toPromise();
|
|
37
|
+
return createMcpToolSuccessResponse(response.rawData);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return handleMcpToolError(error, "Content Type Creation");
|
|
41
|
+
}
|
|
35
42
|
});
|
|
36
43
|
};
|