@contentful/mcp-tools 0.1.0-dev-20251118T1827-8c57ea9.0 → 0.1.0-dev-20251118T1840-2e759f9.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/dist/index.js ADDED
@@ -0,0 +1,4448 @@
1
+ // src/tools/ai-actions/createAiAction.ts
2
+ import { z as z5 } from "zod";
3
+
4
+ // src/utils/formatters.ts
5
+ import { XMLBuilder } from "fast-xml-parser";
6
+ function formatResponse(message, object = {}) {
7
+ const formattedObject = {};
8
+ for (const [key, value] of Object.entries(object)) {
9
+ if (!value) continue;
10
+ formattedObject[key] = value;
11
+ }
12
+ const builder = new XMLBuilder({
13
+ format: true,
14
+ indentBy: " ",
15
+ suppressEmptyNode: true,
16
+ ignoreAttributes: false,
17
+ processEntities: false
18
+ });
19
+ const contextString = builder.build(formattedObject);
20
+ return `${message}:
21
+ ${contextString}
22
+ `;
23
+ }
24
+
25
+ // src/utils/response.ts
26
+ function createSuccessResponse(message, data) {
27
+ const text = data ? formatResponse(message, data) : message;
28
+ return {
29
+ content: [
30
+ {
31
+ type: "text",
32
+ text
33
+ }
34
+ ]
35
+ };
36
+ }
37
+ function withErrorHandling(handler, errorPrefix = "Error") {
38
+ return async (params, extra) => {
39
+ try {
40
+ return await handler(params, extra);
41
+ } catch (error) {
42
+ const errorMessage = error instanceof Error ? error.message : String(error);
43
+ return {
44
+ isError: true,
45
+ content: [
46
+ {
47
+ type: "text",
48
+ text: `${errorPrefix}: ${errorMessage}`
49
+ }
50
+ ]
51
+ };
52
+ }
53
+ };
54
+ }
55
+
56
+ // src/utils/tools.ts
57
+ import ctfl from "contentful-management";
58
+
59
+ // src/config/env.ts
60
+ import dotenv from "dotenv";
61
+ import { z } from "zod";
62
+ dotenv.config();
63
+ var EnvSchema = z.object({
64
+ CONTENTFUL_MANAGEMENT_ACCESS_TOKEN: z.string().describe("Contentful CMA token"),
65
+ CONTENTFUL_HOST: z.string().optional().default("api.contentful.com").describe("Contentful API host"),
66
+ APP_ID: z.string().optional().describe("Contentful App ID"),
67
+ SPACE_ID: z.string().optional().describe("Contentful Space ID"),
68
+ ENVIRONMENT_ID: z.string().optional().default("master").describe("Contentful environment ID"),
69
+ ORGANIZATION_ID: z.string().optional().describe("Contentful organization ID")
70
+ });
71
+ var env = EnvSchema.safeParse(process.env);
72
+ if (!env.success && process.env["TEST_TYPE"] !== "unit") {
73
+ console.error("Invalid environment variables", env.error.format());
74
+ process.exit(1);
75
+ }
76
+
77
+ // src/utils/getVersion.ts
78
+ import { readFileSync, existsSync } from "fs";
79
+ import { join } from "path";
80
+ import { fileURLToPath } from "url";
81
+ import { dirname } from "path";
82
+ var getVersion = () => {
83
+ const __filename2 = fileURLToPath(import.meta.url);
84
+ const __dirname2 = dirname(__filename2);
85
+ const possiblePaths = [
86
+ join(__dirname2, "../package.json"),
87
+ // For bundled code (dist/index.js -> package.json)
88
+ join(__dirname2, "../../package.json")
89
+ // For source code (src/utils/getVersion.ts -> package.json)
90
+ ];
91
+ for (const packageJsonPath of possiblePaths) {
92
+ if (existsSync(packageJsonPath)) {
93
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
94
+ return packageJson.version;
95
+ }
96
+ }
97
+ throw new Error("Could not find package.json");
98
+ };
99
+
100
+ // src/config/contentful.ts
101
+ function getDefaultClientConfig() {
102
+ if (!env.success && process.env["TEST_TYPE"] !== "unit") {
103
+ throw new Error("Environment variables are not properly configured");
104
+ }
105
+ if (!env.data) {
106
+ throw new Error("Environment data is not available");
107
+ }
108
+ const clientConfig = {
109
+ accessToken: env.data.CONTENTFUL_MANAGEMENT_ACCESS_TOKEN,
110
+ host: env.data.CONTENTFUL_HOST,
111
+ space: env.data.SPACE_ID,
112
+ headers: {
113
+ "X-Contentful-User-Agent-Tool": `contentful-mcp/${getVersion()}`
114
+ //Include user agent header for telemetry tracking
115
+ }
116
+ };
117
+ return clientConfig;
118
+ }
119
+
120
+ // src/utils/tools.ts
121
+ import { z as z2 } from "zod";
122
+ var BaseToolSchema = z2.object({
123
+ spaceId: z2.string().describe("The ID of the Contentful space"),
124
+ environmentId: z2.string().describe("The ID of the Contentful environment")
125
+ });
126
+ function createToolClient(params) {
127
+ const clientConfig = getDefaultClientConfig();
128
+ if (params.spaceId) {
129
+ clientConfig.space = params.spaceId;
130
+ }
131
+ return ctfl.createClient(clientConfig, { type: "plain" });
132
+ }
133
+
134
+ // src/utils/ai-actions.ts
135
+ import { z as z3 } from "zod";
136
+ var VariableType = /* @__PURE__ */ ((VariableType2) => {
137
+ VariableType2["RESOURCE_LINK"] = "ResourceLink";
138
+ VariableType2["TEXT"] = "Text";
139
+ VariableType2["STANDARD_INPUT"] = "StandardInput";
140
+ VariableType2["LOCALE"] = "Locale";
141
+ VariableType2["MEDIA_REFERENCE"] = "MediaReference";
142
+ VariableType2["REFERENCE"] = "Reference";
143
+ VariableType2["SMART_CONTEXT"] = "SmartContext";
144
+ return VariableType2;
145
+ })(VariableType || {});
146
+ var EntityType = /* @__PURE__ */ ((EntityType2) => {
147
+ EntityType2["ENTRY"] = "Entry";
148
+ EntityType2["ASSET"] = "Asset";
149
+ EntityType2["RESOURCE_LINK"] = "ResourceLink";
150
+ return EntityType2;
151
+ })(EntityType || {});
152
+ var VariableValue = z3.union([
153
+ z3.object({
154
+ id: z3.string(),
155
+ value: z3.string()
156
+ }),
157
+ z3.object({
158
+ id: z3.string(),
159
+ value: z3.object({
160
+ entityType: z3.nativeEnum(EntityType),
161
+ entityId: z3.string(),
162
+ entityPath: z3.string()
163
+ })
164
+ }),
165
+ z3.object({
166
+ id: z3.string(),
167
+ value: z3.object({
168
+ entityType: z3.literal("Entry" /* ENTRY */),
169
+ entityId: z3.string(),
170
+ entityPaths: z3.array(z3.string())
171
+ })
172
+ })
173
+ ]);
174
+ var OutputFormat = /* @__PURE__ */ ((OutputFormat2) => {
175
+ OutputFormat2["RICH_TEXT"] = "RichText";
176
+ OutputFormat2["MARKDOWN"] = "Markdown";
177
+ OutputFormat2["PLAIN_TEXT"] = "PlainText";
178
+ return OutputFormat2;
179
+ })(OutputFormat || {});
180
+
181
+ // src/types/aiActionTestCaseSchema.ts
182
+ import { z as z4 } from "zod";
183
+ var TextTestCase = z4.object({
184
+ type: z4.literal("Text").optional(),
185
+ value: z4.string().optional()
186
+ });
187
+ var ReferenceTestCase = z4.object({
188
+ type: z4.literal("Reference").optional(),
189
+ value: z4.object({
190
+ entityPath: z4.string().optional(),
191
+ entityType: z4.literal("Entry").optional(),
192
+ entityId: z4.string().optional()
193
+ }).optional()
194
+ });
195
+ var AiActionTestCaseSchema = z4.union([
196
+ TextTestCase,
197
+ ReferenceTestCase
198
+ ]);
199
+
200
+ // src/tools/ai-actions/createAiAction.ts
201
+ var CreateAiActionToolParams = BaseToolSchema.extend({
202
+ name: z5.string().describe("The name of the AI action"),
203
+ description: z5.string().describe("The description of the AI action"),
204
+ instruction: z5.object({
205
+ template: z5.string().describe("The template for the AI action"),
206
+ variables: z5.array(
207
+ z5.object({
208
+ id: z5.string().describe("The id of the variable"),
209
+ name: z5.string().optional().describe("The name of the variable"),
210
+ type: z5.nativeEnum(VariableType).describe("The type of the variable"),
211
+ description: z5.string().optional().describe("The description of the variable")
212
+ })
213
+ ).describe("Array of variables for the AI action")
214
+ }).describe("The instruction for the AI action"),
215
+ configuration: z5.object({
216
+ modelType: z5.string().describe("The type of model to use"),
217
+ modelTemperature: z5.number().describe("The temperature for the model")
218
+ }).describe("The configuration for the AI action"),
219
+ testCases: z5.array(AiActionTestCaseSchema).optional().describe("Test cases for the AI action")
220
+ });
221
+ async function tool(args) {
222
+ const params = {
223
+ spaceId: args.spaceId,
224
+ environmentId: args.environmentId || "master"
225
+ };
226
+ const contentfulClient = createToolClient({
227
+ ...args,
228
+ environmentId: args.environmentId || "master"
229
+ });
230
+ const aiAction = await contentfulClient.aiAction.create(params, {
231
+ name: args.name,
232
+ description: args.description,
233
+ instruction: args.instruction,
234
+ configuration: args.configuration,
235
+ testCases: args.testCases
236
+ });
237
+ return createSuccessResponse("AI action created successfully", { aiAction });
238
+ }
239
+ var createAiActionTool = withErrorHandling(
240
+ tool,
241
+ "Error creating AI action"
242
+ );
243
+
244
+ // src/tools/ai-actions/invokeAiAction.ts
245
+ import { z as z6 } from "zod";
246
+ var InvokeAiActionToolParams = BaseToolSchema.extend({
247
+ aiActionId: z6.string().describe("The ID of the AI action to invoke"),
248
+ fields: z6.array(
249
+ z6.object({
250
+ outputFormat: z6.nativeEnum(OutputFormat).describe("The output format of the AI action"),
251
+ variables: z6.array(VariableValue).describe("The variable assignments within the AI action invocation")
252
+ })
253
+ )
254
+ });
255
+ async function pollForCompletion(contentfulClient, params, aiActions, pollInterval = 3e4, maxAttempts = 10) {
256
+ const completedActions = /* @__PURE__ */ new Map();
257
+ for (let attempt = 0; attempt < maxAttempts && completedActions.size < aiActions.length; attempt++) {
258
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
259
+ await Promise.allSettled(
260
+ aiActions.filter((action) => !completedActions.has(action.sys.id)).map(async (action) => {
261
+ try {
262
+ const invocationStatus = await contentfulClient.aiActionInvocation.get({
263
+ ...params,
264
+ invocationId: action.sys.id
265
+ });
266
+ const status = invocationStatus.sys.status;
267
+ if (status === "COMPLETED" && invocationStatus.result) {
268
+ completedActions.set(
269
+ action.sys.id,
270
+ invocationStatus.result.content
271
+ );
272
+ } else if (status === "FAILED" || status === "CANCELLED") {
273
+ throw new Error(
274
+ `AI action ${action.sys.id} failed with status ${status}`
275
+ );
276
+ }
277
+ } catch (error) {
278
+ console.warn(
279
+ `Error checking status for invocation ${action.sys.id}:`,
280
+ error
281
+ );
282
+ }
283
+ })
284
+ );
285
+ }
286
+ if (completedActions.size < aiActions.length) {
287
+ throw new Error(
288
+ `Polling timeout: ${completedActions.size}/${aiActions.length} actions completed after ${maxAttempts} attempts`
289
+ );
290
+ }
291
+ return Array.from(completedActions.entries()).map(([actionId, content]) => ({
292
+ actionId,
293
+ content
294
+ }));
295
+ }
296
+ async function tool2(args) {
297
+ const params = {
298
+ spaceId: args.spaceId,
299
+ environmentId: args.environmentId
300
+ };
301
+ const contentfulClient = createToolClient(args);
302
+ const aiActions = [];
303
+ for (const field of args.fields) {
304
+ const aiAction = await contentfulClient.aiAction.invoke(
305
+ {
306
+ ...params,
307
+ aiActionId: args.aiActionId
308
+ },
309
+ {
310
+ outputFormat: field.outputFormat,
311
+ variables: field.variables
312
+ }
313
+ );
314
+ aiActions.push(aiAction);
315
+ }
316
+ const completedActions = await pollForCompletion(
317
+ contentfulClient,
318
+ { ...params, aiActionId: args.aiActionId },
319
+ aiActions
320
+ );
321
+ return createSuccessResponse("AI action invoked and completed successfully", {
322
+ aiActions: completedActions,
323
+ nextStepsGuidance: `Required next step: Now that the invocation is complete, you will take the next step to complete the workflow. This will involve a CRUD operation that will take action on each of the action returned in the aiActions variable. You will need to use the appropriate tool to do this, choose a tool depending on the type of entity the action was executed on and the description of the Ai Action.`
324
+ });
325
+ }
326
+ var invokeAiActionTool = withErrorHandling(
327
+ tool2,
328
+ "Error invoking AI action"
329
+ );
330
+
331
+ // src/tools/ai-actions/getAiActionInvocation.ts
332
+ import { z as z7 } from "zod";
333
+ var GetAiActionInvocationToolParams = BaseToolSchema.extend({
334
+ aiActionId: z7.string().describe("The ID of the AI action"),
335
+ invocationId: z7.string().describe("The ID of the invocation to retrieve")
336
+ });
337
+ async function tool3(args) {
338
+ const params = {
339
+ spaceId: args.spaceId,
340
+ environmentId: args.environmentId,
341
+ aiActionId: args.aiActionId,
342
+ invocationId: args.invocationId
343
+ };
344
+ const contentfulClient = createToolClient(args);
345
+ const aiActionInvocation = await contentfulClient.aiActionInvocation.get(params);
346
+ return createSuccessResponse("AI action invocation retrieved successfully", {
347
+ aiActionInvocation
348
+ });
349
+ }
350
+ var getAiActionInvocationTool = withErrorHandling(
351
+ tool3,
352
+ "Error retrieving AI action invocation"
353
+ );
354
+
355
+ // src/tools/ai-actions/deleteAiAction.ts
356
+ import { z as z8 } from "zod";
357
+ var DeleteAiActionToolParams = BaseToolSchema.extend({
358
+ aiActionId: z8.string().describe("The ID of the AI action to delete")
359
+ });
360
+ async function tool4(args) {
361
+ const params = {
362
+ spaceId: args.spaceId,
363
+ environmentId: args.environmentId,
364
+ aiActionId: args.aiActionId
365
+ };
366
+ const contentfulClient = createToolClient(args);
367
+ const aiAction = await contentfulClient.aiAction.get(params);
368
+ await contentfulClient.aiAction.delete(params);
369
+ return createSuccessResponse("AI action deleted successfully", { aiAction });
370
+ }
371
+ var deleteAiActionTool = withErrorHandling(
372
+ tool4,
373
+ "Error deleting AI action"
374
+ );
375
+
376
+ // src/tools/ai-actions/getAiAction.ts
377
+ import { z as z9 } from "zod";
378
+ var GetAiActionToolParams = BaseToolSchema.extend({
379
+ aiActionId: z9.string().describe("The ID of the AI action to retrieve")
380
+ });
381
+ async function tool5(args) {
382
+ const params = {
383
+ spaceId: args.spaceId,
384
+ environmentId: args.environmentId,
385
+ aiActionId: args.aiActionId
386
+ };
387
+ const contentfulClient = createToolClient(args);
388
+ const aiAction = await contentfulClient.aiAction.get(params);
389
+ return createSuccessResponse("AI action retrieved successfully", {
390
+ aiAction
391
+ });
392
+ }
393
+ var getAiActionTool = withErrorHandling(
394
+ tool5,
395
+ "Error retrieving AI action"
396
+ );
397
+
398
+ // src/tools/ai-actions/listAiActions.ts
399
+ import { z as z10 } from "zod";
400
+
401
+ // src/utils/summarizer.ts
402
+ var summarizeData = (data, options = {}) => {
403
+ const {
404
+ maxItems = 3,
405
+ remainingMessage = "To see more items, please ask me to retrieve the next page."
406
+ } = options;
407
+ if (data && typeof data === "object" && "items" in data && "total" in data) {
408
+ const items = data.items;
409
+ const total = data.total;
410
+ if (!Array.isArray(items) || typeof total !== "number") {
411
+ return data;
412
+ }
413
+ if (items.length <= maxItems) {
414
+ return data;
415
+ }
416
+ return {
417
+ items: items.slice(0, maxItems),
418
+ total,
419
+ showing: maxItems,
420
+ remaining: total - maxItems,
421
+ message: remainingMessage,
422
+ skip: maxItems
423
+ // Add skip value for next page
424
+ };
425
+ }
426
+ if (Array.isArray(data)) {
427
+ if (data.length <= maxItems) {
428
+ return data;
429
+ }
430
+ return {
431
+ items: data.slice(0, maxItems),
432
+ total: data.length,
433
+ showing: maxItems,
434
+ remaining: data.length - maxItems,
435
+ message: remainingMessage,
436
+ skip: maxItems
437
+ // Add skip value for next page
438
+ };
439
+ }
440
+ return data;
441
+ };
442
+
443
+ // src/tools/ai-actions/listAiActions.ts
444
+ var ListAiActionToolParams = BaseToolSchema.extend({
445
+ limit: z10.number().optional().describe("Maximum number of AI actions to return (max 3)"),
446
+ skip: z10.number().optional().describe("Skip this many AI actions for pagination"),
447
+ select: z10.string().optional().describe("Comma-separated list of fields to return"),
448
+ include: z10.number().optional().describe("Include this many levels of linked entries"),
449
+ order: z10.string().optional().describe("Order AI actions by this field")
450
+ });
451
+ async function tool6(args) {
452
+ const params = {
453
+ spaceId: args.spaceId,
454
+ environmentId: args.environmentId
455
+ };
456
+ const contentfulClient = createToolClient(args);
457
+ const aiActions = await contentfulClient.aiAction.getMany({
458
+ ...params,
459
+ query: {
460
+ limit: Math.min(args.limit || 3, 3),
461
+ skip: args.skip || 0,
462
+ ...args.select && { select: args.select },
463
+ ...args.include && { include: args.include },
464
+ ...args.order && { order: args.order }
465
+ }
466
+ });
467
+ const summarizedAiActions = aiActions.items.map((aiAction) => ({
468
+ id: aiAction.sys.id,
469
+ name: aiAction.name || "Untitled",
470
+ description: aiAction.description || null,
471
+ instruction: aiAction.instruction || null,
472
+ configuration: aiAction.configuration || null,
473
+ testCases: aiAction.testCases || null,
474
+ createdAt: aiAction.sys.createdAt,
475
+ updatedAt: aiAction.sys.updatedAt,
476
+ publishedVersion: aiAction.sys.publishedVersion
477
+ }));
478
+ const summarized = summarizeData(
479
+ {
480
+ ...aiActions,
481
+ items: summarizedAiActions
482
+ },
483
+ {
484
+ maxItems: 3,
485
+ remainingMessage: "To see more AI actions, please ask me to retrieve the next page using the skip parameter."
486
+ }
487
+ );
488
+ return createSuccessResponse("AI actions retrieved successfully", {
489
+ aiActions: summarized,
490
+ total: aiActions.total,
491
+ limit: aiActions.limit,
492
+ skip: aiActions.skip
493
+ });
494
+ }
495
+ var listAiActionTool = withErrorHandling(
496
+ tool6,
497
+ "Error listing AI actions"
498
+ );
499
+
500
+ // src/tools/ai-actions/publishAiAction.ts
501
+ import { z as z11 } from "zod";
502
+ var PublishAiActionToolParams = BaseToolSchema.extend({
503
+ aiActionId: z11.string().describe("The ID of the AI action to publish")
504
+ });
505
+ async function tool7(args) {
506
+ const params = {
507
+ spaceId: args.spaceId,
508
+ environmentId: args.environmentId,
509
+ aiActionId: args.aiActionId
510
+ };
511
+ const contentfulClient = createToolClient(args);
512
+ try {
513
+ const aiAction = await contentfulClient.aiAction.get(params);
514
+ const publishedAiAction = await contentfulClient.aiAction.publish(
515
+ {
516
+ ...params,
517
+ version: aiAction.sys.version
518
+ },
519
+ aiAction
520
+ );
521
+ return createSuccessResponse("AI action published successfully", {
522
+ version: publishedAiAction.sys.publishedVersion,
523
+ aiActionId: args.aiActionId
524
+ });
525
+ } catch (error) {
526
+ return createSuccessResponse("AI action publish failed", {
527
+ status: error,
528
+ aiActionId: args.aiActionId
529
+ });
530
+ }
531
+ }
532
+ var publishAiActionTool = withErrorHandling(
533
+ tool7,
534
+ "Error publishing AI action"
535
+ );
536
+
537
+ // src/tools/ai-actions/unpublishAiAction.ts
538
+ import { z as z12 } from "zod";
539
+ var UnpublishAiActionToolParams = BaseToolSchema.extend({
540
+ aiActionId: z12.string().describe("The ID of the AI action to unpublish")
541
+ });
542
+ async function tool8(args) {
543
+ const params = {
544
+ spaceId: args.spaceId,
545
+ environmentId: args.environmentId,
546
+ aiActionId: args.aiActionId
547
+ };
548
+ const contentfulClient = createToolClient(args);
549
+ try {
550
+ await contentfulClient.aiAction.unpublish(params);
551
+ return createSuccessResponse("AI action unpublished successfully", {
552
+ aiActionId: args.aiActionId
553
+ });
554
+ } catch (error) {
555
+ return createSuccessResponse("AI action unpublish failed", {
556
+ status: error,
557
+ aiActionId: args.aiActionId
558
+ });
559
+ }
560
+ }
561
+ var unpublishAiActionTool = withErrorHandling(
562
+ tool8,
563
+ "Error unpublishing AI action"
564
+ );
565
+
566
+ // src/tools/ai-actions/updateAiAction.ts
567
+ import { z as z13 } from "zod";
568
+ var UpdateAiActionToolParams = BaseToolSchema.extend({
569
+ aiActionId: z13.string().describe("The ID of the AI action to update"),
570
+ name: z13.string().optional().describe("The name of the AI action"),
571
+ description: z13.string().optional().describe("The description of the AI action"),
572
+ instruction: z13.object({
573
+ template: z13.string().describe("The template for the AI action"),
574
+ variables: z13.array(
575
+ z13.object({
576
+ id: z13.string().describe("The id of the variable"),
577
+ name: z13.string().optional().describe("The name of the variable"),
578
+ type: z13.nativeEnum(VariableType).describe("The type of the variable"),
579
+ description: z13.string().optional().describe("The description of the variable")
580
+ })
581
+ ).describe("Array of variables for the AI action")
582
+ }).optional().describe("The instruction for the AI action"),
583
+ configuration: z13.object({
584
+ modelType: z13.string().describe("The type of model to use"),
585
+ modelTemperature: z13.number().describe("The temperature for the model")
586
+ }).optional().describe("The configuration for the AI action"),
587
+ testCases: z13.array(AiActionTestCaseSchema).optional().describe("Test cases for the AI action")
588
+ });
589
+ async function tool9(args) {
590
+ const params = {
591
+ spaceId: args.spaceId,
592
+ environmentId: args.environmentId,
593
+ aiActionId: args.aiActionId
594
+ };
595
+ const contentfulClient = createToolClient(args);
596
+ const existingAiAction = await contentfulClient.aiAction.get(params);
597
+ const updatedAiAction = await contentfulClient.aiAction.update(params, {
598
+ ...existingAiAction,
599
+ ...args.name && { name: args.name },
600
+ ...args.description && { description: args.description },
601
+ ...args.instruction && { instruction: args.instruction },
602
+ ...args.configuration && { configuration: args.configuration },
603
+ ...args.testCases && { testCases: args.testCases }
604
+ });
605
+ return createSuccessResponse("AI action updated successfully", {
606
+ updatedAiAction
607
+ });
608
+ }
609
+ var updateAiActionTool = withErrorHandling(
610
+ tool9,
611
+ "Error updating AI action"
612
+ );
613
+
614
+ // src/tools/ai-actions/register.ts
615
+ var aiActionTools = {
616
+ createAiAction: {
617
+ title: "create_ai_action",
618
+ description: `Create a new AI action with clear instructions and well-defined variables. Best practices: (1) Use descriptive names that indicate the action's purpose, (2) Write specific, actionable instructions in the template, (3) Define meaningful variables with clear names like "sourceContent", "targetLocale", "entryId", or "contentType", (4) Embed variables into the template using the format {{var.{variableId}}}, (5) Consider the content editor's workflow and make the action intuitive to use. Example variables: content fields to process, locales for translation, reference entries, formatting preferences, or validation rules.`,
619
+ inputParams: CreateAiActionToolParams.shape,
620
+ annotations: {
621
+ readOnlyHint: false,
622
+ destructiveHint: false,
623
+ idempotentHint: false,
624
+ openWorldHint: false
625
+ },
626
+ tool: createAiActionTool
627
+ },
628
+ invokeAiAction: {
629
+ title: "invoke_ai_action",
630
+ description: 'Invoke an AI action with variables. MANDATORY BULK OPERATIONS: You MUST ALWAYS use bulk operations when processing multiple content pieces by adding multiple items to the fields array - never make separate calls. VARIABLES: Can be (1) String values for simple text input, or (2) Entity references to read from specific entry fields using {"entityId": "entryId", "entityPath": "fields.fieldName.locale", "entityType": "Entry"}. POLLING: Automatically polls every 3 seconds for up to 60 seconds. CRITICAL FOLLOW-UP: After invoking AI actions, you MUST immediately take the next step to complete the workflow. The tool response will provide specific guidance on required next steps - you must follow this guidance.',
631
+ inputParams: InvokeAiActionToolParams.shape,
632
+ annotations: {
633
+ readOnlyHint: false,
634
+ destructiveHint: false,
635
+ idempotentHint: false,
636
+ openWorldHint: true
637
+ // Interacts with external AI services
638
+ },
639
+ tool: invokeAiActionTool
640
+ },
641
+ getAiActionInvocation: {
642
+ title: "get_ai_action_invocation",
643
+ description: "Retrieve information about a specific AI action invocation by its ID.",
644
+ inputParams: GetAiActionInvocationToolParams.shape,
645
+ annotations: {
646
+ readOnlyHint: true,
647
+ openWorldHint: false
648
+ },
649
+ tool: getAiActionInvocationTool
650
+ },
651
+ deleteAiAction: {
652
+ title: "delete_ai_action",
653
+ description: "Delete a specific AI action from your Contentful space",
654
+ inputParams: DeleteAiActionToolParams.shape,
655
+ annotations: {
656
+ readOnlyHint: false,
657
+ destructiveHint: true,
658
+ idempotentHint: true,
659
+ // Deleting same item multiple times has same effect
660
+ openWorldHint: false
661
+ },
662
+ tool: deleteAiActionTool
663
+ },
664
+ getAiAction: {
665
+ title: "get_ai_action",
666
+ description: "Retrieve details about a specific AI action including its configuration, instructions, and defined variables",
667
+ inputParams: GetAiActionToolParams.shape,
668
+ annotations: {
669
+ readOnlyHint: true,
670
+ openWorldHint: false
671
+ },
672
+ tool: getAiActionTool
673
+ },
674
+ listAiActions: {
675
+ title: "list_ai_actions",
676
+ description: "List AI actions in a space. Returns a maximum of 3 items per request. Use skip parameter to paginate through results.",
677
+ inputParams: ListAiActionToolParams.shape,
678
+ annotations: {
679
+ readOnlyHint: true,
680
+ openWorldHint: false
681
+ },
682
+ tool: listAiActionTool
683
+ },
684
+ publishAiAction: {
685
+ title: "publish_ai_action",
686
+ description: "Publish an AI action to make it available for use in the Contentful web app",
687
+ inputParams: PublishAiActionToolParams.shape,
688
+ annotations: {
689
+ readOnlyHint: false,
690
+ destructiveHint: false,
691
+ idempotentHint: true,
692
+ // Publishing same item multiple times has same effect
693
+ openWorldHint: false
694
+ },
695
+ tool: publishAiActionTool
696
+ },
697
+ unpublishAiAction: {
698
+ title: "unpublish_ai_action",
699
+ description: "Unpublish an AI action to remove it from use in the Contentful web app",
700
+ inputParams: UnpublishAiActionToolParams.shape,
701
+ annotations: {
702
+ readOnlyHint: false,
703
+ destructiveHint: false,
704
+ idempotentHint: true,
705
+ // Unpublishing same item multiple times has same effect
706
+ openWorldHint: false
707
+ },
708
+ tool: unpublishAiActionTool
709
+ },
710
+ updateAiAction: {
711
+ title: "update_ai_action",
712
+ description: "Update an existing AI action. Your updates will be merged with the existing AI action data, so you only need to provide the fields you want to change.",
713
+ inputParams: UpdateAiActionToolParams.shape,
714
+ annotations: {
715
+ readOnlyHint: false,
716
+ destructiveHint: false,
717
+ idempotentHint: false,
718
+ openWorldHint: false
719
+ },
720
+ tool: updateAiActionTool
721
+ }
722
+ };
723
+
724
+ // src/tools/assets/uploadAsset.ts
725
+ import { z as z15 } from "zod";
726
+
727
+ // src/types/taxonomySchema.ts
728
+ import { z as z14 } from "zod";
729
+ var TaxonomyConceptValidationLinkSchema = z14.object({
730
+ sys: z14.object({
731
+ type: z14.literal("Link"),
732
+ linkType: z14.literal("TaxonomyConcept"),
733
+ id: z14.string().describe("The ID of the taxonomy concept")
734
+ }),
735
+ required: z14.boolean().optional()
736
+ });
737
+ var TaxonomyConceptSchemeValidationLinkSchema = z14.object({
738
+ sys: z14.object({
739
+ type: z14.literal("Link"),
740
+ linkType: z14.literal("TaxonomyConceptScheme"),
741
+ id: z14.string().describe("The ID of the taxonomy concept scheme")
742
+ }),
743
+ required: z14.boolean().optional()
744
+ });
745
+ var TaxonomyValidationLinkSchema = z14.union([
746
+ TaxonomyConceptValidationLinkSchema,
747
+ TaxonomyConceptSchemeValidationLinkSchema
748
+ ]);
749
+ var ContentTypeMetadataSchema = z14.object({
750
+ taxonomy: z14.array(TaxonomyValidationLinkSchema).optional()
751
+ }).optional();
752
+ var EntryMetadataSchema = z14.object({
753
+ tags: z14.array(
754
+ z14.object({
755
+ sys: z14.object({
756
+ type: z14.literal("Link"),
757
+ linkType: z14.literal("Tag"),
758
+ id: z14.string()
759
+ })
760
+ })
761
+ ),
762
+ concepts: z14.array(
763
+ z14.object({
764
+ sys: z14.object({
765
+ type: z14.literal("Link"),
766
+ linkType: z14.literal("TaxonomyConcept"),
767
+ id: z14.string()
768
+ })
769
+ })
770
+ ).optional()
771
+ }).optional();
772
+ var AssetMetadataSchema = z14.object({
773
+ tags: z14.array(
774
+ z14.object({
775
+ sys: z14.object({
776
+ type: z14.literal("Link"),
777
+ linkType: z14.literal("Tag"),
778
+ id: z14.string()
779
+ })
780
+ })
781
+ ),
782
+ concepts: z14.array(
783
+ z14.object({
784
+ sys: z14.object({
785
+ type: z14.literal("Link"),
786
+ linkType: z14.literal("TaxonomyConcept"),
787
+ id: z14.string()
788
+ })
789
+ })
790
+ ).optional()
791
+ }).optional();
792
+
793
+ // src/tools/assets/uploadAsset.ts
794
+ var FileSchema = z15.object({
795
+ fileName: z15.string().describe("The name of the file"),
796
+ contentType: z15.string().describe("The MIME type of the file"),
797
+ upload: z15.string().optional().describe("The upload URL or file data")
798
+ });
799
+ var UploadAssetToolParams = BaseToolSchema.extend({
800
+ title: z15.string().describe("The title of the asset"),
801
+ description: z15.string().optional().describe("The description of the asset"),
802
+ file: FileSchema.describe("The file information for the asset"),
803
+ metadata: AssetMetadataSchema
804
+ });
805
+ async function tool10(args) {
806
+ const params = {
807
+ spaceId: args.spaceId,
808
+ environmentId: args.environmentId
809
+ };
810
+ const contentfulClient = createToolClient(args);
811
+ const assetProps = {
812
+ fields: {
813
+ title: { "en-US": args.title },
814
+ description: args.description ? { "en-US": args.description } : void 0,
815
+ file: { "en-US": args.file }
816
+ },
817
+ metadata: args.metadata
818
+ };
819
+ const asset = await contentfulClient.asset.create(params, assetProps);
820
+ const processedAsset = await contentfulClient.asset.processForAllLocales(
821
+ params,
822
+ {
823
+ sys: asset.sys,
824
+ fields: asset.fields
825
+ },
826
+ {}
827
+ );
828
+ return createSuccessResponse("Asset uploaded successfully", {
829
+ asset: processedAsset
830
+ });
831
+ }
832
+ var uploadAssetTool = withErrorHandling(tool10, "Error uploading asset");
833
+
834
+ // src/tools/assets/listAssets.ts
835
+ import { z as z16 } from "zod";
836
+ var ListAssetsToolParams = BaseToolSchema.extend({
837
+ limit: z16.number().optional().describe("Maximum number of assets to return (max 3)"),
838
+ skip: z16.number().optional().describe("Skip this many assets for pagination"),
839
+ select: z16.string().optional().describe("Comma-separated list of fields to return"),
840
+ include: z16.number().optional().describe("Include this many levels of linked entries"),
841
+ order: z16.string().optional().describe("Order assets by this field"),
842
+ links_to_entry: z16.string().optional().describe("Find assets that link to the specified entry ID")
843
+ });
844
+ async function tool11(args) {
845
+ const params = {
846
+ spaceId: args.spaceId,
847
+ environmentId: args.environmentId
848
+ };
849
+ const contentfulClient = createToolClient(args);
850
+ const assets = await contentfulClient.asset.getMany({
851
+ ...params,
852
+ query: {
853
+ limit: Math.min(args.limit || 3, 3),
854
+ skip: args.skip || 0,
855
+ ...args.select && { select: args.select },
856
+ ...args.include && { include: args.include },
857
+ ...args.order && { order: args.order },
858
+ ...args.links_to_entry && { links_to_entry: args.links_to_entry }
859
+ }
860
+ });
861
+ const summarizedAssets = assets.items.map((asset) => ({
862
+ id: asset.sys.id,
863
+ title: asset.fields.title?.["en-US"] || "Untitled",
864
+ description: asset.fields.description?.["en-US"] || null,
865
+ fileName: asset.fields.file?.["en-US"]?.fileName || null,
866
+ contentType: asset.fields.file?.["en-US"]?.contentType || null,
867
+ url: asset.fields.file?.["en-US"]?.url || null,
868
+ size: asset.fields.file?.["en-US"]?.details?.["size"] || null,
869
+ createdAt: asset.sys.createdAt,
870
+ updatedAt: asset.sys.updatedAt,
871
+ publishedVersion: asset.sys.publishedVersion
872
+ }));
873
+ const summarized = summarizeData(
874
+ {
875
+ ...assets,
876
+ items: summarizedAssets
877
+ },
878
+ {
879
+ maxItems: 3,
880
+ remainingMessage: "To see more assets, please ask me to retrieve the next page using the skip parameter."
881
+ }
882
+ );
883
+ return createSuccessResponse("Assets retrieved successfully", {
884
+ assets: summarized,
885
+ total: assets.total,
886
+ limit: assets.limit,
887
+ skip: assets.skip
888
+ });
889
+ }
890
+ var listAssetsTool = withErrorHandling(tool11, "Error listing assets");
891
+
892
+ // src/tools/assets/getAsset.ts
893
+ import { z as z17 } from "zod";
894
+ var GetAssetToolParams = BaseToolSchema.extend({
895
+ assetId: z17.string().describe("The ID of the asset to retrieve")
896
+ });
897
+ async function tool12(args) {
898
+ const params = {
899
+ spaceId: args.spaceId,
900
+ environmentId: args.environmentId,
901
+ assetId: args.assetId
902
+ };
903
+ const contentfulClient = createToolClient(args);
904
+ const asset = await contentfulClient.asset.get(params);
905
+ return createSuccessResponse("Asset retrieved successfully", { asset });
906
+ }
907
+ var getAssetTool = withErrorHandling(tool12, "Error retrieving asset");
908
+
909
+ // src/tools/assets/updateAsset.ts
910
+ import { z as z18 } from "zod";
911
+ var UpdateAssetToolParams = BaseToolSchema.extend({
912
+ assetId: z18.string().describe("The ID of the asset to update"),
913
+ fields: z18.record(z18.any()).describe(
914
+ "The field values to update. Keys should be field IDs and values should be the field content. Will be merged with existing fields."
915
+ ),
916
+ metadata: AssetMetadataSchema
917
+ });
918
+ async function tool13(args) {
919
+ const params = {
920
+ spaceId: args.spaceId,
921
+ environmentId: args.environmentId,
922
+ assetId: args.assetId
923
+ };
924
+ const contentfulClient = createToolClient(args);
925
+ const existingAsset = await contentfulClient.asset.get(params);
926
+ const allTags = [
927
+ ...existingAsset.metadata?.tags || [],
928
+ ...args.metadata?.tags || []
929
+ ];
930
+ const allConcepts = [
931
+ ...existingAsset.metadata?.concepts || [],
932
+ ...args.metadata?.concepts || []
933
+ ];
934
+ const updatedAsset = await contentfulClient.asset.update(params, {
935
+ ...existingAsset,
936
+ fields: { ...existingAsset.fields, ...args.fields },
937
+ metadata: {
938
+ tags: allTags,
939
+ concepts: allConcepts
940
+ }
941
+ });
942
+ return createSuccessResponse("Asset updated successfully", { updatedAsset });
943
+ }
944
+ var updateAssetTool = withErrorHandling(tool13, "Error updating asset");
945
+
946
+ // src/tools/assets/deleteAsset.ts
947
+ import { z as z19 } from "zod";
948
+ var DeleteAssetToolParams = BaseToolSchema.extend({
949
+ assetId: z19.string().describe("The ID of the asset to delete")
950
+ });
951
+ async function tool14(args) {
952
+ const params = {
953
+ spaceId: args.spaceId,
954
+ environmentId: args.environmentId,
955
+ assetId: args.assetId
956
+ };
957
+ const contentfulClient = createToolClient(args);
958
+ const asset = await contentfulClient.asset.get(params);
959
+ await contentfulClient.asset.delete(params);
960
+ return createSuccessResponse("Asset deleted successfully", { asset });
961
+ }
962
+ var deleteAssetTool = withErrorHandling(tool14, "Error deleting asset");
963
+
964
+ // src/tools/assets/publishAsset.ts
965
+ import { z as z20 } from "zod";
966
+
967
+ // src/utils/bulkOperations.ts
968
+ async function waitForBulkActionCompletion(contentfulClient, baseParams, bulkActionId) {
969
+ let action = await contentfulClient.bulkAction.get({
970
+ ...baseParams,
971
+ bulkActionId
972
+ });
973
+ while (action.sys.status === "inProgress" || action.sys.status === "created") {
974
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
975
+ action = await contentfulClient.bulkAction.get({
976
+ ...baseParams,
977
+ bulkActionId
978
+ });
979
+ }
980
+ return action;
981
+ }
982
+ async function createEntryVersionedLinks(contentfulClient, baseParams, entryIds) {
983
+ return Promise.all(
984
+ entryIds.map(async (entryId) => {
985
+ const currentEntry = await contentfulClient.entry.get({
986
+ ...baseParams,
987
+ entryId
988
+ });
989
+ return {
990
+ sys: {
991
+ type: "Link",
992
+ linkType: "Entry",
993
+ id: entryId,
994
+ version: currentEntry.sys.version
995
+ }
996
+ };
997
+ })
998
+ );
999
+ }
1000
+ async function createEntryUnversionedLinks(contentfulClient, baseParams, entryIds) {
1001
+ await Promise.all(
1002
+ entryIds.map(async (entryId) => {
1003
+ await contentfulClient.entry.get({
1004
+ ...baseParams,
1005
+ entryId
1006
+ });
1007
+ })
1008
+ );
1009
+ return entryIds.map((entryId) => ({
1010
+ sys: {
1011
+ type: "Link",
1012
+ linkType: "Entry",
1013
+ id: entryId
1014
+ }
1015
+ }));
1016
+ }
1017
+ async function createAssetVersionedLinks(contentfulClient, baseParams, assetIds) {
1018
+ return Promise.all(
1019
+ assetIds.map(async (assetId) => {
1020
+ const currentAsset = await contentfulClient.asset.get({
1021
+ ...baseParams,
1022
+ assetId
1023
+ });
1024
+ return {
1025
+ sys: {
1026
+ type: "Link",
1027
+ linkType: "Asset",
1028
+ id: assetId,
1029
+ version: currentAsset.sys.version
1030
+ }
1031
+ };
1032
+ })
1033
+ );
1034
+ }
1035
+ async function createAssetUnversionedLinks(contentfulClient, baseParams, assetIds) {
1036
+ await Promise.all(
1037
+ assetIds.map(async (assetId) => {
1038
+ await contentfulClient.asset.get({
1039
+ ...baseParams,
1040
+ assetId
1041
+ });
1042
+ })
1043
+ );
1044
+ return assetIds.map((assetId) => ({
1045
+ sys: {
1046
+ type: "Link",
1047
+ linkType: "Asset",
1048
+ id: assetId
1049
+ }
1050
+ }));
1051
+ }
1052
+ function createEntitiesCollection(entities) {
1053
+ return {
1054
+ sys: {
1055
+ type: "Array"
1056
+ },
1057
+ items: entities
1058
+ };
1059
+ }
1060
+
1061
+ // src/tools/assets/publishAsset.ts
1062
+ var PublishAssetToolParams = BaseToolSchema.extend({
1063
+ assetId: z20.union([z20.string(), z20.array(z20.string()).max(100)]).describe(
1064
+ "The ID of the asset to publish (string) or an array of asset IDs (up to 100 assets)"
1065
+ )
1066
+ });
1067
+ async function tool15(args) {
1068
+ const baseParams = {
1069
+ spaceId: args.spaceId,
1070
+ environmentId: args.environmentId
1071
+ };
1072
+ const contentfulClient = createToolClient(args);
1073
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1074
+ if (assetIds.length === 1) {
1075
+ try {
1076
+ const assetId = assetIds[0];
1077
+ const params = {
1078
+ ...baseParams,
1079
+ assetId
1080
+ };
1081
+ const asset = await contentfulClient.asset.get(params);
1082
+ const publishedAsset = await contentfulClient.asset.publish(
1083
+ params,
1084
+ asset
1085
+ );
1086
+ return createSuccessResponse("Asset published successfully", {
1087
+ status: publishedAsset.sys.status,
1088
+ assetId
1089
+ });
1090
+ } catch (error) {
1091
+ return createSuccessResponse("Asset publish failed", {
1092
+ status: error,
1093
+ assetId: assetIds[0]
1094
+ });
1095
+ }
1096
+ }
1097
+ const entityVersions = await createAssetVersionedLinks(
1098
+ contentfulClient,
1099
+ baseParams,
1100
+ assetIds
1101
+ );
1102
+ const entitiesCollection = createEntitiesCollection(entityVersions);
1103
+ const bulkAction = await contentfulClient.bulkAction.publish(baseParams, {
1104
+ entities: entitiesCollection
1105
+ });
1106
+ const action = await waitForBulkActionCompletion(
1107
+ contentfulClient,
1108
+ baseParams,
1109
+ bulkAction.sys.id
1110
+ );
1111
+ return createSuccessResponse("Asset(s) published successfully", {
1112
+ status: action.sys.status,
1113
+ assetIds
1114
+ });
1115
+ }
1116
+ var publishAssetTool = withErrorHandling(
1117
+ tool15,
1118
+ "Error publishing asset"
1119
+ );
1120
+
1121
+ // src/tools/assets/unpublishAsset.ts
1122
+ import { z as z21 } from "zod";
1123
+ var UnpublishAssetToolParams = BaseToolSchema.extend({
1124
+ assetId: z21.union([z21.string(), z21.array(z21.string()).max(100)]).describe(
1125
+ "The ID of the asset to unpublish (string) or an array of asset IDs (up to 100 assets)"
1126
+ )
1127
+ });
1128
+ async function tool16(args) {
1129
+ const baseParams = {
1130
+ spaceId: args.spaceId,
1131
+ environmentId: args.environmentId
1132
+ };
1133
+ const contentfulClient = createToolClient(args);
1134
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1135
+ if (assetIds.length === 1) {
1136
+ try {
1137
+ const assetId = assetIds[0];
1138
+ const params = {
1139
+ ...baseParams,
1140
+ assetId
1141
+ };
1142
+ const asset = await contentfulClient.asset.get(params);
1143
+ const unpublishedAsset = await contentfulClient.asset.unpublish(
1144
+ params,
1145
+ asset
1146
+ );
1147
+ return createSuccessResponse("Asset unpublished successfully", {
1148
+ status: unpublishedAsset.sys.status,
1149
+ assetId
1150
+ });
1151
+ } catch (error) {
1152
+ return createSuccessResponse("Asset unpublish failed", {
1153
+ status: error,
1154
+ assetId: assetIds[0]
1155
+ });
1156
+ }
1157
+ }
1158
+ const assetLinks = await createAssetUnversionedLinks(
1159
+ contentfulClient,
1160
+ baseParams,
1161
+ assetIds
1162
+ );
1163
+ const entitiesCollection = createEntitiesCollection(assetLinks);
1164
+ const bulkAction = await contentfulClient.bulkAction.unpublish(baseParams, {
1165
+ entities: entitiesCollection
1166
+ });
1167
+ const action = await waitForBulkActionCompletion(
1168
+ contentfulClient,
1169
+ baseParams,
1170
+ bulkAction.sys.id
1171
+ );
1172
+ return createSuccessResponse("Asset(s) unpublished successfully", {
1173
+ status: action.sys.status,
1174
+ assetIds
1175
+ });
1176
+ }
1177
+ var unpublishAssetTool = withErrorHandling(
1178
+ tool16,
1179
+ "Error unpublishing asset"
1180
+ );
1181
+
1182
+ // src/tools/assets/archiveAsset.ts
1183
+ import { z as z22 } from "zod";
1184
+ var ArchiveAssetToolParams = BaseToolSchema.extend({
1185
+ assetId: z22.union([z22.string(), z22.array(z22.string()).max(100)]).describe(
1186
+ "The ID of the asset to archive (string) or an array of asset IDs (up to 100 assets)"
1187
+ )
1188
+ });
1189
+ async function tool17(args) {
1190
+ const baseParams = {
1191
+ spaceId: args.spaceId,
1192
+ environmentId: args.environmentId
1193
+ };
1194
+ const contentfulClient = createToolClient(args);
1195
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1196
+ const successfullyArchived = [];
1197
+ for (const assetId of assetIds) {
1198
+ try {
1199
+ const params = {
1200
+ ...baseParams,
1201
+ assetId
1202
+ };
1203
+ await contentfulClient.asset.archive(params);
1204
+ successfullyArchived.push(assetId);
1205
+ } catch (error) {
1206
+ const errorMessage = successfullyArchived.length > 0 ? `Failed to archive asset '${assetId}' after successfully archiving ${successfullyArchived.length} asset(s): [${successfullyArchived.join(", ")}]. Original error: ${error instanceof Error ? error.message : String(error)}` : `Failed to archive asset '${assetId}': ${error instanceof Error ? error.message : String(error)}`;
1207
+ throw new Error(errorMessage);
1208
+ }
1209
+ }
1210
+ if (assetIds.length === 1) {
1211
+ return createSuccessResponse("Asset archived successfully", {
1212
+ assetId: assetIds[0]
1213
+ });
1214
+ } else {
1215
+ return createSuccessResponse(
1216
+ `Successfully archived ${assetIds.length} assets`,
1217
+ {
1218
+ archivedCount: assetIds.length,
1219
+ assetIds
1220
+ }
1221
+ );
1222
+ }
1223
+ }
1224
+ var archiveAssetTool = withErrorHandling(
1225
+ tool17,
1226
+ "Error archiving asset"
1227
+ );
1228
+
1229
+ // src/tools/assets/unarchiveAsset.ts
1230
+ import { z as z23 } from "zod";
1231
+ var UnarchiveAssetToolParams = BaseToolSchema.extend({
1232
+ assetId: z23.union([z23.string(), z23.array(z23.string()).max(100)]).describe(
1233
+ "The ID of the asset to unarchive (string) or an array of asset IDs (up to 100 assets)"
1234
+ )
1235
+ });
1236
+ async function tool18(args) {
1237
+ const baseParams = {
1238
+ spaceId: args.spaceId,
1239
+ environmentId: args.environmentId
1240
+ };
1241
+ const contentfulClient = createToolClient(args);
1242
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1243
+ const successfullyUnarchived = [];
1244
+ for (const assetId of assetIds) {
1245
+ try {
1246
+ const params = {
1247
+ ...baseParams,
1248
+ assetId
1249
+ };
1250
+ await contentfulClient.asset.unarchive(params);
1251
+ successfullyUnarchived.push(assetId);
1252
+ } catch (error) {
1253
+ const errorMessage = successfullyUnarchived.length > 0 ? `Failed to unarchive asset '${assetId}' after successfully unarchiving ${successfullyUnarchived.length} asset(s): [${successfullyUnarchived.join(", ")}]. Original error: ${error instanceof Error ? error.message : String(error)}` : `Failed to unarchive asset '${assetId}': ${error instanceof Error ? error.message : String(error)}`;
1254
+ throw new Error(errorMessage);
1255
+ }
1256
+ }
1257
+ if (assetIds.length === 1) {
1258
+ return createSuccessResponse("Asset unarchived successfully", {
1259
+ assetId: assetIds[0]
1260
+ });
1261
+ } else {
1262
+ return createSuccessResponse(
1263
+ `Successfully unarchived ${assetIds.length} assets`,
1264
+ {
1265
+ unarchivedCount: assetIds.length,
1266
+ assetIds
1267
+ }
1268
+ );
1269
+ }
1270
+ }
1271
+ var unarchiveAssetTool = withErrorHandling(
1272
+ tool18,
1273
+ "Error unarchiving asset"
1274
+ );
1275
+
1276
+ // src/tools/assets/register.ts
1277
+ var assetTools = {
1278
+ uploadAsset: {
1279
+ title: "upload_asset",
1280
+ description: "Upload a new asset",
1281
+ inputParams: UploadAssetToolParams.shape,
1282
+ annotations: {
1283
+ readOnlyHint: false,
1284
+ destructiveHint: false,
1285
+ idempotentHint: false,
1286
+ openWorldHint: false
1287
+ },
1288
+ tool: uploadAssetTool
1289
+ },
1290
+ listAssets: {
1291
+ title: "list_assets",
1292
+ description: "List assets in a space. Returns a maximum of 3 items per request. Use skip parameter to paginate through results.",
1293
+ inputParams: ListAssetsToolParams.shape,
1294
+ annotations: {
1295
+ readOnlyHint: true,
1296
+ openWorldHint: false
1297
+ },
1298
+ tool: listAssetsTool
1299
+ },
1300
+ getAsset: {
1301
+ title: "get_asset",
1302
+ description: "Retrieve an asset",
1303
+ inputParams: GetAssetToolParams.shape,
1304
+ annotations: {
1305
+ readOnlyHint: true,
1306
+ openWorldHint: false
1307
+ },
1308
+ tool: getAssetTool
1309
+ },
1310
+ updateAsset: {
1311
+ title: "update_asset",
1312
+ description: "Update an asset",
1313
+ inputParams: UpdateAssetToolParams.shape,
1314
+ annotations: {
1315
+ readOnlyHint: false,
1316
+ destructiveHint: false,
1317
+ idempotentHint: false,
1318
+ openWorldHint: false
1319
+ },
1320
+ tool: updateAssetTool
1321
+ },
1322
+ deleteAsset: {
1323
+ title: "delete_asset",
1324
+ description: "Delete an asset",
1325
+ inputParams: DeleteAssetToolParams.shape,
1326
+ annotations: {
1327
+ readOnlyHint: false,
1328
+ destructiveHint: true,
1329
+ idempotentHint: true,
1330
+ openWorldHint: false
1331
+ },
1332
+ tool: deleteAssetTool
1333
+ },
1334
+ publishAsset: {
1335
+ title: "publish_asset",
1336
+ description: "Publish an asset or multiple assets. Accepts either a single assetId (string) or an array of assetIds (up to 100 assets). For a single asset, it uses the standard publish operation. For multiple assets, it automatically uses bulk publishing.",
1337
+ inputParams: PublishAssetToolParams.shape,
1338
+ annotations: {
1339
+ readOnlyHint: false,
1340
+ destructiveHint: false,
1341
+ idempotentHint: true,
1342
+ openWorldHint: false
1343
+ },
1344
+ tool: publishAssetTool
1345
+ },
1346
+ unpublishAsset: {
1347
+ title: "unpublish_asset",
1348
+ description: "Unpublish an asset or multiple assets. Accepts either a single assetId (string) or an array of assetIds (up to 100 assets). For a single asset, it uses the standard unpublish operation. For multiple assets, it automatically uses bulk unpublishing.",
1349
+ inputParams: UnpublishAssetToolParams.shape,
1350
+ annotations: {
1351
+ readOnlyHint: false,
1352
+ destructiveHint: false,
1353
+ idempotentHint: true,
1354
+ openWorldHint: false
1355
+ },
1356
+ tool: unpublishAssetTool
1357
+ },
1358
+ archiveAsset: {
1359
+ title: "archive_asset",
1360
+ description: "Archive an asset or multiple assets. Archives assets that are no longer needed but should be preserved. Assets must be unpublished before they can be archived. Accepts either a single assetId (string) or an array of assetIds (up to 100 assets). For multiple assets, processes each one sequentially as a pseudo-bulk operation.",
1361
+ inputParams: ArchiveAssetToolParams.shape,
1362
+ annotations: {
1363
+ readOnlyHint: false,
1364
+ destructiveHint: false,
1365
+ idempotentHint: true,
1366
+ openWorldHint: false
1367
+ },
1368
+ tool: archiveAssetTool
1369
+ },
1370
+ unarchiveAsset: {
1371
+ title: "unarchive_asset",
1372
+ description: "Unarchive an asset or multiple assets. Restores archived assets, making them available for editing and publishing again. Accepts either a single assetId (string) or an array of assetIds (up to 100 assets). For multiple assets, processes each one sequentially as a pseudo-bulk operation.",
1373
+ inputParams: UnarchiveAssetToolParams.shape,
1374
+ annotations: {
1375
+ readOnlyHint: false,
1376
+ destructiveHint: false,
1377
+ idempotentHint: true,
1378
+ openWorldHint: false
1379
+ },
1380
+ tool: unarchiveAssetTool
1381
+ }
1382
+ };
1383
+
1384
+ // src/tools/content-types/getContentType.ts
1385
+ import { z as z24 } from "zod";
1386
+ var GetContentTypeToolParams = BaseToolSchema.extend({
1387
+ contentTypeId: z24.string().describe("The ID of the content type to retrieve details for")
1388
+ });
1389
+ async function tool19(args) {
1390
+ const params = {
1391
+ spaceId: args.spaceId,
1392
+ environmentId: args.environmentId
1393
+ };
1394
+ const contentfulClient = createToolClient(args);
1395
+ const contentType = await contentfulClient.contentType.get({
1396
+ ...params,
1397
+ contentTypeId: args.contentTypeId
1398
+ });
1399
+ return createSuccessResponse("Content type retrieved successfully", {
1400
+ contentType
1401
+ });
1402
+ }
1403
+ var getContentTypeTool = withErrorHandling(
1404
+ tool19,
1405
+ "Error retrieving content type"
1406
+ );
1407
+
1408
+ // src/tools/content-types/listContentTypes.ts
1409
+ import { z as z25 } from "zod";
1410
+ var ListContentTypesToolParams = BaseToolSchema.extend({
1411
+ limit: z25.number().optional().describe("Maximum number of content types to return (max 10)"),
1412
+ skip: z25.number().optional().describe("Skip this many content types for pagination"),
1413
+ select: z25.string().optional().describe("Comma-separated list of fields to return"),
1414
+ include: z25.number().optional().describe("Include this many levels of linked entries"),
1415
+ order: z25.string().optional().describe("Order content types by this field")
1416
+ });
1417
+ async function tool20(args) {
1418
+ const params = {
1419
+ spaceId: args.spaceId,
1420
+ environmentId: args.environmentId
1421
+ };
1422
+ const contentfulClient = createToolClient(args);
1423
+ const contentTypes = await contentfulClient.contentType.getMany({
1424
+ ...params,
1425
+ query: {
1426
+ limit: Math.min(args.limit || 10, 10),
1427
+ skip: args.skip || 0,
1428
+ ...args.select && { select: args.select },
1429
+ ...args.include && { include: args.include },
1430
+ ...args.order && { order: args.order }
1431
+ }
1432
+ });
1433
+ const summarizedContentTypes = contentTypes.items.map((contentType) => ({
1434
+ ...contentType,
1435
+ id: contentType.sys.id,
1436
+ fieldsCount: contentType.fields.length
1437
+ }));
1438
+ const summarized = summarizeData(
1439
+ {
1440
+ ...contentTypes,
1441
+ items: summarizedContentTypes
1442
+ },
1443
+ {
1444
+ maxItems: 10,
1445
+ remainingMessage: "To see more content types, please ask me to retrieve the next page using the skip parameter."
1446
+ }
1447
+ );
1448
+ return createSuccessResponse("Content types retrieved successfully", {
1449
+ contentTypes: summarized,
1450
+ total: contentTypes.total,
1451
+ limit: contentTypes.limit,
1452
+ skip: contentTypes.skip
1453
+ });
1454
+ }
1455
+ var listContentTypesTool = withErrorHandling(
1456
+ tool20,
1457
+ "Error listing content types"
1458
+ );
1459
+
1460
+ // src/tools/content-types/createContentType.ts
1461
+ import { z as z28 } from "zod";
1462
+
1463
+ // src/types/fieldSchema.ts
1464
+ import { z as z27 } from "zod";
1465
+
1466
+ // src/types/contentTypeFieldValidationSchema.ts
1467
+ import { z as z26 } from "zod";
1468
+ import { INLINES, BLOCKS } from "@contentful/rich-text-types";
1469
+ var NumRange = z26.object({
1470
+ min: z26.number().optional(),
1471
+ max: z26.number().optional()
1472
+ });
1473
+ var DateRange = z26.object({
1474
+ min: z26.string().optional(),
1475
+ max: z26.string().optional()
1476
+ });
1477
+ var RegExpSchema = z26.object({
1478
+ pattern: z26.string(),
1479
+ flags: z26.string()
1480
+ });
1481
+ var AssetImageDimensions = z26.object({
1482
+ width: NumRange.optional(),
1483
+ height: NumRange.optional()
1484
+ });
1485
+ var ExternalResource = z26.object({
1486
+ type: z26.string()
1487
+ });
1488
+ var ContentfulEntryResource = z26.object({
1489
+ type: z26.literal("Contentful:Entry"),
1490
+ source: z26.string(),
1491
+ contentTypes: z26.array(z26.string())
1492
+ });
1493
+ var ContentTypeAllowedResources = z26.union([
1494
+ ContentfulEntryResource,
1495
+ ExternalResource
1496
+ ]);
1497
+ var NodesValidation = z26.record(
1498
+ z26.array(
1499
+ z26.object({
1500
+ // subset of ContentTypeFieldValidation used for node validations
1501
+ size: NumRange.optional(),
1502
+ linkContentType: z26.array(z26.string()).optional(),
1503
+ message: z26.string().nullable().optional()
1504
+ })
1505
+ ).or(
1506
+ z26.object({
1507
+ validations: z26.array(
1508
+ z26.object({
1509
+ size: NumRange.optional(),
1510
+ message: z26.string().nullable().optional()
1511
+ })
1512
+ ),
1513
+ allowedResources: z26.array(ContentTypeAllowedResources)
1514
+ })
1515
+ )
1516
+ );
1517
+ var ContentTypeFieldValidationSchema = z26.object({
1518
+ linkContentType: z26.array(z26.string()).optional(),
1519
+ in: z26.array(z26.union([z26.string(), z26.number()])).optional(),
1520
+ linkMimetypeGroup: z26.array(z26.string()).optional(),
1521
+ enabledNodeTypes: z26.array(z26.union([z26.nativeEnum(BLOCKS), z26.nativeEnum(INLINES)])).optional(),
1522
+ enabledMarks: z26.array(z26.string()).optional(),
1523
+ unique: z26.boolean().optional(),
1524
+ size: NumRange.optional(),
1525
+ range: NumRange.optional(),
1526
+ dateRange: DateRange.optional(),
1527
+ regexp: RegExpSchema.optional(),
1528
+ message: z26.string().nullable().optional(),
1529
+ prohibitRegexp: RegExpSchema.optional(),
1530
+ assetImageDimensions: AssetImageDimensions.optional(),
1531
+ assetFileSize: NumRange.optional(),
1532
+ nodes: NodesValidation.optional()
1533
+ });
1534
+
1535
+ // src/types/fieldSchema.ts
1536
+ var FieldSchema = z27.object({
1537
+ id: z27.string().describe("The field ID"),
1538
+ name: z27.string().describe("The field name"),
1539
+ type: z27.string().describe(
1540
+ 'The field type (e.g., "Symbol", "Text", "Integer", "Boolean", "Date", "Location", "Link", "Array", "Object")'
1541
+ ),
1542
+ required: z27.boolean().describe("Whether the field is required"),
1543
+ localized: z27.boolean().describe("Whether the field is localized"),
1544
+ disabled: z27.boolean().optional().describe("Whether the field is disabled"),
1545
+ omitted: z27.boolean().optional().describe("Whether the field is omitted from the API response"),
1546
+ validations: z27.array(ContentTypeFieldValidationSchema).optional().describe("Field validations"),
1547
+ settings: z27.record(z27.any()).optional().describe("Field-specific settings"),
1548
+ defaultValue: z27.any().optional().describe("Default value for the field"),
1549
+ linkType: z27.string().optional().describe('Link type for Link fields (e.g., "Entry", "Asset")'),
1550
+ items: z27.object({
1551
+ type: z27.string(),
1552
+ linkType: z27.string().optional(),
1553
+ validations: z27.array(ContentTypeFieldValidationSchema).optional()
1554
+ }).optional().describe("Items configuration for Array fields")
1555
+ });
1556
+
1557
+ // src/tools/content-types/createContentType.ts
1558
+ var CreateContentTypeToolParams = BaseToolSchema.extend({
1559
+ name: z28.string().describe("The name of the content type"),
1560
+ displayField: z28.string().describe("The field ID to use as the display field"),
1561
+ description: z28.string().optional().describe("Description of the content type"),
1562
+ contentTypeId: z28.string().optional().describe(
1563
+ "Optional ID for the content type. If provided, will use createWithId method"
1564
+ ),
1565
+ fields: z28.array(FieldSchema).describe("Array of field definitions for the content type"),
1566
+ metadata: ContentTypeMetadataSchema
1567
+ });
1568
+ async function tool21(args) {
1569
+ const params = {
1570
+ spaceId: args.spaceId,
1571
+ environmentId: args.environmentId
1572
+ };
1573
+ const contentfulClient = createToolClient(args);
1574
+ const contentTypeData = {
1575
+ name: args.name,
1576
+ displayField: args.displayField,
1577
+ description: args.description,
1578
+ fields: args.fields,
1579
+ metadata: args.metadata
1580
+ };
1581
+ const contentType = args.contentTypeId ? await contentfulClient.contentType.createWithId(
1582
+ { ...params, contentTypeId: args.contentTypeId },
1583
+ contentTypeData
1584
+ ) : await contentfulClient.contentType.create(params, contentTypeData);
1585
+ return createSuccessResponse("Content type created successfully", {
1586
+ contentType
1587
+ });
1588
+ }
1589
+ var createContentTypeTool = withErrorHandling(
1590
+ tool21,
1591
+ "Error creating content type"
1592
+ );
1593
+
1594
+ // src/tools/content-types/updateContentType.ts
1595
+ import { z as z29 } from "zod";
1596
+ var UpdateContentTypeToolParams = BaseToolSchema.extend({
1597
+ contentTypeId: z29.string().describe("The ID of the content type to update"),
1598
+ name: z29.string().optional().describe("The name of the content type"),
1599
+ displayField: z29.string().optional().describe("The field ID to use as the display field"),
1600
+ description: z29.string().optional().describe("Description of the content type"),
1601
+ fields: z29.array(FieldSchema).optional().describe(
1602
+ "Array of field definitions for the content type. Will be merged with existing fields."
1603
+ ),
1604
+ metadata: ContentTypeMetadataSchema
1605
+ });
1606
+ async function tool22(args) {
1607
+ const params = {
1608
+ spaceId: args.spaceId,
1609
+ environmentId: args.environmentId,
1610
+ contentTypeId: args.contentTypeId
1611
+ };
1612
+ const contentfulClient = createToolClient(args);
1613
+ const currentContentType = await contentfulClient.contentType.get(params);
1614
+ const fields = args.fields || currentContentType.fields;
1615
+ if (args.fields) {
1616
+ const existingFieldsMap = currentContentType.fields.reduce(
1617
+ (acc, field) => {
1618
+ acc[field.id] = field;
1619
+ return acc;
1620
+ },
1621
+ {}
1622
+ );
1623
+ fields.forEach((field) => {
1624
+ const existingField = existingFieldsMap[field.id];
1625
+ if (existingField) {
1626
+ field.validations = field.validations || existingField.validations;
1627
+ field.required = field.required !== void 0 ? field.required : existingField.required || false;
1628
+ if (field.type === "Link" && !field.linkType && existingField.linkType) {
1629
+ field.linkType = existingField.linkType;
1630
+ }
1631
+ if (field.type === "Array" && !field.items && existingField.items) {
1632
+ field.items = existingField.items;
1633
+ }
1634
+ } else {
1635
+ field.required = field.required || false;
1636
+ }
1637
+ });
1638
+ }
1639
+ const contentType = await contentfulClient.contentType.update(params, {
1640
+ ...currentContentType,
1641
+ name: args.name || currentContentType.name,
1642
+ description: args.description || currentContentType.description,
1643
+ displayField: args.displayField || currentContentType.displayField,
1644
+ fields,
1645
+ metadata: args.metadata || currentContentType.metadata
1646
+ });
1647
+ return createSuccessResponse("Content type updated successfully", {
1648
+ contentType
1649
+ });
1650
+ }
1651
+ var updateContentTypeTool = withErrorHandling(
1652
+ tool22,
1653
+ "Error updating content type"
1654
+ );
1655
+
1656
+ // src/tools/content-types/deleteContentType.ts
1657
+ import { z as z30 } from "zod";
1658
+ var DeleteContentTypeToolParams = BaseToolSchema.extend({
1659
+ contentTypeId: z30.string().describe("The ID of the content type to delete")
1660
+ });
1661
+ async function tool23(args) {
1662
+ const params = {
1663
+ spaceId: args.spaceId,
1664
+ environmentId: args.environmentId,
1665
+ contentTypeId: args.contentTypeId
1666
+ };
1667
+ const contentfulClient = createToolClient(args);
1668
+ await contentfulClient.contentType.delete(params);
1669
+ return createSuccessResponse("Content type deleted successfully", {
1670
+ contentTypeId: args.contentTypeId
1671
+ });
1672
+ }
1673
+ var deleteContentTypeTool = withErrorHandling(
1674
+ tool23,
1675
+ "Error deleting content type"
1676
+ );
1677
+
1678
+ // src/tools/content-types/publishContentType.ts
1679
+ import { z as z31 } from "zod";
1680
+ var PublishContentTypeToolParams = BaseToolSchema.extend({
1681
+ contentTypeId: z31.string().describe("The ID of the content type to publish")
1682
+ });
1683
+ async function tool24(args) {
1684
+ const params = {
1685
+ spaceId: args.spaceId,
1686
+ environmentId: args.environmentId,
1687
+ contentTypeId: args.contentTypeId
1688
+ };
1689
+ const contentfulClient = createToolClient(args);
1690
+ const currentContentType = await contentfulClient.contentType.get(params);
1691
+ const contentType = await contentfulClient.contentType.publish(
1692
+ params,
1693
+ currentContentType
1694
+ );
1695
+ return createSuccessResponse("Content type published successfully", {
1696
+ contentType
1697
+ });
1698
+ }
1699
+ var publishContentTypeTool = withErrorHandling(
1700
+ tool24,
1701
+ "Error publishing content type"
1702
+ );
1703
+
1704
+ // src/tools/content-types/unpublishContentType.ts
1705
+ import { z as z32 } from "zod";
1706
+ var UnpublishContentTypeToolParams = BaseToolSchema.extend({
1707
+ contentTypeId: z32.string().describe("The ID of the content type to unpublish")
1708
+ });
1709
+ async function tool25(args) {
1710
+ const params = {
1711
+ spaceId: args.spaceId,
1712
+ environmentId: args.environmentId,
1713
+ contentTypeId: args.contentTypeId
1714
+ };
1715
+ const contentfulClient = createToolClient(args);
1716
+ const contentType = await contentfulClient.contentType.unpublish(params);
1717
+ return createSuccessResponse("Content type unpublished successfully", {
1718
+ contentType
1719
+ });
1720
+ }
1721
+ var unpublishContentTypeTool = withErrorHandling(
1722
+ tool25,
1723
+ "Error unpublishing content type"
1724
+ );
1725
+
1726
+ // src/tools/content-types/register.ts
1727
+ var contentTypeTools = {
1728
+ getContentType: {
1729
+ title: "get_content_type",
1730
+ description: "Get details about a specific Contentful content type",
1731
+ inputParams: GetContentTypeToolParams.shape,
1732
+ annotations: {
1733
+ readOnlyHint: true,
1734
+ openWorldHint: false
1735
+ },
1736
+ tool: getContentTypeTool
1737
+ },
1738
+ listContentTypes: {
1739
+ title: "list_content_types",
1740
+ description: "List content types in a space. Returns a maximum of 10 items per request. Use skip parameter to paginate through results.",
1741
+ inputParams: ListContentTypesToolParams.shape,
1742
+ annotations: {
1743
+ readOnlyHint: true,
1744
+ openWorldHint: false
1745
+ },
1746
+ tool: listContentTypesTool
1747
+ },
1748
+ createContentType: {
1749
+ title: "create_content_type",
1750
+ description: "Create a new content type",
1751
+ inputParams: CreateContentTypeToolParams.shape,
1752
+ annotations: {
1753
+ readOnlyHint: false,
1754
+ destructiveHint: false,
1755
+ idempotentHint: false,
1756
+ openWorldHint: false
1757
+ },
1758
+ tool: createContentTypeTool
1759
+ },
1760
+ updateContentType: {
1761
+ title: "update_content_type",
1762
+ description: "Update an existing content type. The handler will merge your field updates with existing content type data, so you only need to provide the fields and properties you want to change.",
1763
+ inputParams: UpdateContentTypeToolParams.shape,
1764
+ annotations: {
1765
+ readOnlyHint: false,
1766
+ destructiveHint: false,
1767
+ idempotentHint: false,
1768
+ openWorldHint: false
1769
+ },
1770
+ tool: updateContentTypeTool
1771
+ },
1772
+ deleteContentType: {
1773
+ title: "delete_content_type",
1774
+ description: "Delete a content type",
1775
+ inputParams: DeleteContentTypeToolParams.shape,
1776
+ annotations: {
1777
+ readOnlyHint: false,
1778
+ destructiveHint: true,
1779
+ idempotentHint: true,
1780
+ openWorldHint: false
1781
+ },
1782
+ tool: deleteContentTypeTool
1783
+ },
1784
+ publishContentType: {
1785
+ title: "publish_content_type",
1786
+ description: "Publish a content type",
1787
+ inputParams: PublishContentTypeToolParams.shape,
1788
+ annotations: {
1789
+ readOnlyHint: false,
1790
+ destructiveHint: false,
1791
+ idempotentHint: true,
1792
+ openWorldHint: false
1793
+ },
1794
+ tool: publishContentTypeTool
1795
+ },
1796
+ unpublishContentType: {
1797
+ title: "unpublish_content_type",
1798
+ description: "Unpublish a content type",
1799
+ inputParams: UnpublishContentTypeToolParams.shape,
1800
+ annotations: {
1801
+ readOnlyHint: false,
1802
+ destructiveHint: false,
1803
+ idempotentHint: true,
1804
+ openWorldHint: false
1805
+ },
1806
+ tool: unpublishContentTypeTool
1807
+ }
1808
+ };
1809
+
1810
+ // src/tools/context/getInitialContextTool.ts
1811
+ import { z as z33 } from "zod";
1812
+ import { outdent } from "outdent";
1813
+
1814
+ // src/tools/context/store.ts
1815
+ var ContextStore = class {
1816
+ context = {
1817
+ hasGlobalContext: false
1818
+ };
1819
+ setInitialContextLoaded() {
1820
+ this.context.hasGlobalContext = true;
1821
+ }
1822
+ hasInitialContext() {
1823
+ return this.context.hasGlobalContext;
1824
+ }
1825
+ resetInitialContext() {
1826
+ this.context.hasGlobalContext = false;
1827
+ }
1828
+ };
1829
+ var contextStore = new ContextStore();
1830
+
1831
+ // src/tools/context/instructions.ts
1832
+ var MCP_INSTRUCTIONS = `You are a helpful assistant integrated with Contentful through the Model Context Protocol (MCP).
1833
+
1834
+ # Core Agent Principles
1835
+
1836
+ ## IMPORTANT FIRST STEP:
1837
+ - Always call get_initial_context first to initialize your connection before using any other tools
1838
+ - This is required for all operations and will give you essential information about the current Contentful environment
1839
+
1840
+ ## Key Principles:
1841
+ - **Persistence**: Keep going until the user's query is completely resolved. Only end your turn when you are sure the problem is solved.
1842
+ - **Tool Usage**: If you are not sure about content or schema structure, use your tools to gather relevant information. Do NOT guess or make up answers.
1843
+ - **Planning**: Plan your approach before each tool call, and reflect on the outcomes of previous tool calls.
1844
+ - **Resource Clarification**: ALWAYS ask the user which resource to work with if there are multiple resources available. Never assume or guess which resource to use.
1845
+ - **Error Handling**: NEVER apologize for errors when making tool calls. Instead, immediately try a different approach or tool call. You may briefly inform the user what you're doing, but never say sorry.
1846
+
1847
+ # Content Handling
1848
+
1849
+ ## Content-Type-First Approach:
1850
+ - **ALWAYS check the content type first** when users ask about finding or editing specific content types (e.g., "Where can I edit our pricing page?")
1851
+ - Use get_content_types proactively to understand what content types exist before attempting queries
1852
+ - This prevents failed queries and immediately reveals relevant content types (e.g., discovering a \`pricingPage\` type when asked about pricing)
1853
+ - Match user requests to the appropriate content types in the entry
1854
+ - If a user asks to create a field that doesn't match the content type (e.g., "writer" when the content type has "author"), suggest the correct type
1855
+
1856
+ ## entry Creation Limits:
1857
+ - A user is only allowed to create/edit/mutate a maximum of 5 (five) entries at a time
1858
+ - For multiple entry creation, use the 'async' parameter (set to true) for better performance
1859
+ - Only use async=true when creating more than one entry in a single conversation
1860
+
1861
+ # Searching for Content
1862
+
1863
+ ## Content-Type-First Search Strategy:
1864
+ - **Content-Type-first approach**: When users ask about specific content (e.g., "pricing page", "blog posts"), use get_content_type first to discover relevant content types
1865
+ - This immediately reveals the correct content types and prevents wasted time on failed queries
1866
+ - After understanding the content type, use search_entries to search for content based on the correct content types and field names
1867
+ - If a query returns no results, retry 2-3 times with modified queries by adjusting filters, relaxing constraints, or trying alternative field names
1868
+ - When retrying queries, consider using more general terms, removing specific filters, or checking for typos in field names
1869
+
1870
+ ## Handling Multi-Step Queries:
1871
+ - For requests involving related entities (e.g., "Find blog posts by Magnus"), use a multi-step approach
1872
+ - ALWAYS check the content type structure first to understand fields and references
1873
+ - First, query for the referenced entity (e.g., author) to find its ID or confirm its existence
1874
+ - If multiple entities match (e.g., several authors named "Magnus"), query them all and display them to the user
1875
+ - Then use the found ID(s) to query for the primary content (e.g., blog posts referencing that author)
1876
+ - For references in Contentful, remember to use the proper reference format
1877
+ - Verify fields in the content type before constructing queries (single reference vs. array of references)
1878
+
1879
+ ## Entry Management:
1880
+ - For entry creation, use create_entry with clear instructions
1881
+ - Use entry_action for operations like publishing, unpublishing, deleting, or discarding entries
1882
+ - Use update_entry for content modifications with AI assistance
1883
+ - Use patch_entry for precise, direct modifications without AI generation (one operation at a time)
1884
+ - Use transform_entry when preserving rich text formatting is crucial
1885
+ - Use translate_entry specifically for language translation tasks
1886
+ - Use transform_image for AI-powered image operations
1887
+ - Always verify entry existence before attempting to modify it
1888
+
1889
+ # Migration Strategies
1890
+ - Use the space_to_space migration workflow to help a user when they want to migrate content from one space to another. Start this workflow by calling the start_space_to_space_migration tool.
1891
+ - You do not need to fetch content types (ex. list_content_types tool) or entries (ex. search_entries tool) prior to starting the migration workflow. Once the user states they want to start the migration workflow, you simply need to call the start_space_to_space_migration tool.
1892
+
1893
+ # Error Handling and Debugging
1894
+
1895
+ ## Error Response Strategy:
1896
+ - If you encounter an error, explain what went wrong clearly
1897
+ - Suggest potential solutions or alternatives
1898
+ - Make sure to check entry existence, field requirements, and permission issues
1899
+ - Try different approaches immediately rather than stopping at the first error
1900
+
1901
+ ## Common Issues to Check:
1902
+ - entry existence and permissions
1903
+ - Required field validation
1904
+ - Correct field types (array vs single reference)
1905
+
1906
+ # Response Format and Communication
1907
+
1908
+ ## General Guidelines:
1909
+ - Keep your responses concise but thorough
1910
+ - Format complex data for readability using markdown
1911
+ - Focus on completing the requested tasks efficiently
1912
+ - Provide context from entries when relevant
1913
+ - When displaying entries, show the most important fields first
1914
+
1915
+ ## Before Using Tools:
1916
+ Before running a tool:
1917
+ 1. Think about what information you need to gather
1918
+ 2. Determine the right tool and parameters to use
1919
+ 3. Briefly communicate to the user what you're about to do in a conversational tone
1920
+
1921
+ ## Problem-Solving Strategy:
1922
+ 1. **Understand the request**: Analyze what the user is asking for and identify necessary entry types and fields
1923
+ 2. **Resource identification**: If multiple resources are available, ALWAYS ask which resource to work with
1924
+ 3. **Plan your approach**: Determine which tools you'll need and in which order
1925
+ 4. **Execute with tools**: Use appropriate tools to query, create, or update entries
1926
+ 5. **Verify results**: Check if results match what the user requested and make adjustments if needed
1927
+ 6. **Respond clearly**: Present results in a clear, concise format
1928
+
1929
+ # Best Practices
1930
+
1931
+ ## Content Management:
1932
+ - When creating content, follow the content type structure exactly
1933
+ - Always verify entry existence before attempting to modify it
1934
+ - Remind users that entry operations can affect live content
1935
+
1936
+ ## Efficiency Tips:
1937
+ - Suggest appropriate entry types based on user needs
1938
+ - Recommend efficient ways to structure content
1939
+ - Explain how Contentful features like content types, entries, and references work
1940
+ - Help users understand the relationship between spaces, environments, and content types
1941
+
1942
+ ## Bulk Actions:
1943
+ - If making multiple calls to the same tool, ALWAYS check and see whether that tool supports bulk operations first, and condense them into a single call if possible.
1944
+
1945
+ You have access to powerful tools that can help you work with Contentful effectively. Always start with get_initial_context, check the schema when needed, clarify resources when multiple exist, and take action to complete user requests fully.`;
1946
+
1947
+ // src/tools/context/getInitialContextTool.ts
1948
+ var GetInitialContextToolParams = z33.object({});
1949
+ async function tool26(_params) {
1950
+ const config = {
1951
+ space: env.data?.SPACE_ID,
1952
+ environment: env.data?.ENVIRONMENT_ID,
1953
+ organization: env.data?.ORGANIZATION_ID
1954
+ };
1955
+ const configInfo = `Current Contentful Configuration:
1956
+ - Space ID: ${config.space}
1957
+ - Environment ID: ${config.environment}
1958
+ - Organization ID: ${config.organization}`;
1959
+ const todaysDate = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US");
1960
+ const message = outdent`
1961
+ ${MCP_INSTRUCTIONS}
1962
+
1963
+ This is the initial context for your Contentful instance:
1964
+
1965
+ <context>
1966
+ ${configInfo}
1967
+ </content>
1968
+
1969
+ <todaysDate>${todaysDate}</todaysDate>
1970
+ `;
1971
+ contextStore.setInitialContextLoaded();
1972
+ return {
1973
+ content: [
1974
+ {
1975
+ type: "text",
1976
+ text: message
1977
+ }
1978
+ ]
1979
+ };
1980
+ }
1981
+ var getInitialContextTool = withErrorHandling(
1982
+ tool26,
1983
+ "Error getting initial context"
1984
+ );
1985
+
1986
+ // src/tools/context/register.ts
1987
+ var contextTools = {
1988
+ getInitialContext: {
1989
+ title: "get_initial_context",
1990
+ description: "IMPORTANT: This tool must be called before using any other tools. It will get initial context and usage instructions for this MCP server. ",
1991
+ inputParams: GetInitialContextToolParams.shape,
1992
+ annotations: {
1993
+ readOnlyHint: true,
1994
+ openWorldHint: false
1995
+ },
1996
+ tool: getInitialContextTool
1997
+ }
1998
+ };
1999
+
2000
+ // src/tools/editor-interfaces/listEditorInterfaces.ts
2001
+ var ListEditorInterfacesToolParams = BaseToolSchema.extend({});
2002
+ async function tool27(args) {
2003
+ const params = {
2004
+ spaceId: args.spaceId,
2005
+ environmentId: args.environmentId
2006
+ };
2007
+ const contentfulClient = createToolClient(args);
2008
+ const editorInterfaces = await contentfulClient.editorInterface.getMany(params);
2009
+ const summarizedInterfaces = editorInterfaces.items.map(
2010
+ (editorInterface) => ({
2011
+ contentTypeId: editorInterface.sys.contentType.sys.id,
2012
+ version: editorInterface.sys.version,
2013
+ controlsCount: editorInterface.controls?.length || 0
2014
+ })
2015
+ );
2016
+ const summarized = summarizeData(
2017
+ {
2018
+ ...editorInterfaces,
2019
+ items: summarizedInterfaces
2020
+ },
2021
+ {
2022
+ maxItems: 20,
2023
+ remainingMessage: "This list includes all editor interfaces in the environment."
2024
+ }
2025
+ );
2026
+ return createSuccessResponse("Editor interfaces retrieved successfully", {
2027
+ editorInterfaces: summarized,
2028
+ total: editorInterfaces.total,
2029
+ limit: editorInterfaces.limit,
2030
+ skip: editorInterfaces.skip
2031
+ });
2032
+ }
2033
+ var listEditorInterfacesTool = withErrorHandling(
2034
+ tool27,
2035
+ "Error listing editor interfaces"
2036
+ );
2037
+
2038
+ // src/tools/editor-interfaces/getEditorInterface.ts
2039
+ import { z as z34 } from "zod";
2040
+ var GetEditorInterfaceToolParams = BaseToolSchema.extend({
2041
+ contentTypeId: z34.string().describe(
2042
+ "The ID of the content type to retrieve the editor interface for"
2043
+ )
2044
+ });
2045
+ async function tool28(args) {
2046
+ const params = {
2047
+ spaceId: args.spaceId,
2048
+ environmentId: args.environmentId,
2049
+ contentTypeId: args.contentTypeId
2050
+ };
2051
+ const contentfulClient = createToolClient(args);
2052
+ const editorInterface = await contentfulClient.editorInterface.get(params);
2053
+ return createSuccessResponse("Editor interface retrieved successfully", {
2054
+ editorInterface
2055
+ });
2056
+ }
2057
+ var getEditorInterfaceTool = withErrorHandling(
2058
+ tool28,
2059
+ "Error retrieving editor interface"
2060
+ );
2061
+
2062
+ // src/tools/editor-interfaces/updateEditorInterface.ts
2063
+ import { z as z35 } from "zod";
2064
+ var ControlSchema = z35.object({
2065
+ fieldId: z35.string().describe("The field ID this control applies to"),
2066
+ widgetId: z35.string().describe("The widget ID to use for this field"),
2067
+ widgetNamespace: z35.enum(["builtin", "extension", "app", "editor-builtin"]).optional().describe(
2068
+ "The namespace of the widget (builtin, extension, app, or editor-builtin)"
2069
+ ),
2070
+ settings: z35.record(z35.any()).optional().describe("Settings object for the widget")
2071
+ });
2072
+ var SidebarItemSchema = z35.object({
2073
+ widgetId: z35.string().describe("The widget ID for the sidebar item"),
2074
+ widgetNamespace: z35.enum(["sidebar-builtin", "extension", "app"]).describe("The namespace of the sidebar widget"),
2075
+ settings: z35.record(z35.any()).optional().describe("Settings object for the sidebar widget"),
2076
+ disabled: z35.boolean().optional().describe("Whether the sidebar item is disabled")
2077
+ });
2078
+ var EditorLayoutItemSchema = z35.object({
2079
+ fieldId: z35.string().describe("The field ID"),
2080
+ settings: z35.record(z35.any()).optional().describe("Layout settings for the field")
2081
+ });
2082
+ var EditorLayoutSchema = z35.object({
2083
+ items: z35.array(EditorLayoutItemSchema).optional().describe("Array of editor layout items")
2084
+ });
2085
+ var GroupControlSchema = z35.object({
2086
+ groupId: z35.string().describe("The group ID"),
2087
+ widgetId: z35.string().describe("The widget ID for the group control"),
2088
+ widgetNamespace: z35.enum(["builtin", "extension", "app"]).optional().describe("The namespace of the group control widget"),
2089
+ settings: z35.record(z35.any()).optional().describe("Settings object for the group control")
2090
+ });
2091
+ var UpdateEditorInterfaceToolParams = BaseToolSchema.extend({
2092
+ contentTypeId: z35.string().describe("The ID of the content type to update the editor interface for"),
2093
+ controls: z35.array(ControlSchema).optional().describe(
2094
+ "Array of control definitions for fields in the content type. Each control defines which widget to use for a field."
2095
+ ),
2096
+ sidebar: z35.array(SidebarItemSchema).optional().describe("Array of sidebar widget configurations"),
2097
+ editorLayout: z35.array(EditorLayoutSchema).optional().describe("Editor layout configuration for organizing fields"),
2098
+ groupControls: z35.array(GroupControlSchema).optional().describe("Array of group control definitions for field groups")
2099
+ });
2100
+ async function tool29(args) {
2101
+ const params = {
2102
+ spaceId: args.spaceId,
2103
+ environmentId: args.environmentId,
2104
+ contentTypeId: args.contentTypeId
2105
+ };
2106
+ const contentfulClient = createToolClient(args);
2107
+ const currentEditorInterface = await contentfulClient.editorInterface.get(params);
2108
+ const updatePayload = {
2109
+ ...currentEditorInterface
2110
+ };
2111
+ if (args.controls !== void 0) {
2112
+ updatePayload["controls"] = args.controls;
2113
+ }
2114
+ if (args.sidebar !== void 0) {
2115
+ updatePayload["sidebar"] = args.sidebar;
2116
+ }
2117
+ if (args.editorLayout !== void 0) {
2118
+ updatePayload["editorLayout"] = args.editorLayout;
2119
+ }
2120
+ if (args.groupControls !== void 0) {
2121
+ updatePayload["groupControls"] = args.groupControls;
2122
+ }
2123
+ const editorInterface = await contentfulClient.editorInterface.update(
2124
+ params,
2125
+ updatePayload
2126
+ );
2127
+ return createSuccessResponse("Editor interface updated successfully", {
2128
+ editorInterface
2129
+ });
2130
+ }
2131
+ var updateEditorInterfaceTool = withErrorHandling(
2132
+ tool29,
2133
+ "Error updating editor interface"
2134
+ );
2135
+
2136
+ // src/tools/editor-interfaces/register.ts
2137
+ var editorInterfaceTools = {
2138
+ listEditorInterfaces: {
2139
+ title: "list_editor_interfaces",
2140
+ description: "Get all editor interfaces of a space. Returns configuration for how content types are displayed and edited in the Contentful web app, including field controls, sidebars, and layout settings.",
2141
+ inputParams: ListEditorInterfacesToolParams.shape,
2142
+ annotations: {
2143
+ readOnlyHint: true,
2144
+ openWorldHint: false
2145
+ },
2146
+ tool: listEditorInterfacesTool
2147
+ },
2148
+ getEditorInterface: {
2149
+ title: "get_editor_interface",
2150
+ description: "Get the editor interface for a specific content type. Returns detailed configuration including field controls (widgets), sidebar widgets, editor layout, and group controls that define how the content type is displayed and edited in the Contentful web app.",
2151
+ inputParams: GetEditorInterfaceToolParams.shape,
2152
+ annotations: {
2153
+ readOnlyHint: true,
2154
+ openWorldHint: false
2155
+ },
2156
+ tool: getEditorInterfaceTool
2157
+ },
2158
+ updateEditorInterface: {
2159
+ title: "update_editor_interface",
2160
+ description: "Update the editor interface for a content type. Allows customization of field controls (widgets), sidebar widgets, editor layout, and group controls. Only provide the properties you want to change - existing values will be preserved for unprovided fields.",
2161
+ inputParams: UpdateEditorInterfaceToolParams.shape,
2162
+ annotations: {
2163
+ readOnlyHint: false,
2164
+ destructiveHint: false,
2165
+ idempotentHint: false,
2166
+ openWorldHint: false
2167
+ },
2168
+ tool: updateEditorInterfaceTool
2169
+ }
2170
+ };
2171
+
2172
+ // src/tools/entries/searchEntries.ts
2173
+ import { z as z36 } from "zod";
2174
+ var SearchEntriesToolParams = BaseToolSchema.extend({
2175
+ query: z36.object({
2176
+ content_type: z36.string().optional().describe("Filter by content type"),
2177
+ include: z36.number().optional().describe("Include this many levels of linked entries"),
2178
+ select: z36.string().optional().describe("Comma-separated list of fields to return"),
2179
+ links_to_entry: z36.string().optional().describe("Find entries that link to the specified entry ID"),
2180
+ limit: z36.number().optional().describe("Maximum number of entries to return"),
2181
+ skip: z36.number().optional().describe("Skip this many entries"),
2182
+ order: z36.string().optional().describe("Order entries by this field")
2183
+ })
2184
+ });
2185
+ async function tool30(args) {
2186
+ const params = {
2187
+ spaceId: args.spaceId,
2188
+ environmentId: args.environmentId
2189
+ };
2190
+ const contentfulClient = createToolClient(args);
2191
+ const entries = await contentfulClient.entry.getMany({
2192
+ ...params,
2193
+ query: {
2194
+ ...args.query,
2195
+ limit: Math.min(args.query.limit || 3, 3),
2196
+ skip: args.query.skip || 0
2197
+ }
2198
+ });
2199
+ const summarized = summarizeData(entries, {
2200
+ maxItems: 3,
2201
+ remainingMessage: "To see more entries, please ask me to retrieve the next page."
2202
+ });
2203
+ return createSuccessResponse("Entries retrieved successfully", {
2204
+ entries: summarized
2205
+ });
2206
+ }
2207
+ var searchEntriesTool = withErrorHandling(
2208
+ tool30,
2209
+ "Error deleting dataset"
2210
+ );
2211
+
2212
+ // src/tools/entries/createEntry.ts
2213
+ import { z as z37 } from "zod";
2214
+ var CreateEntryToolParams = BaseToolSchema.extend({
2215
+ contentTypeId: z37.string().describe("The ID of the content type to create an entry for"),
2216
+ fields: z37.record(z37.any()).describe(
2217
+ "The field values for the new entry. Keys should be field IDs and values should be the field content."
2218
+ ),
2219
+ metadata: EntryMetadataSchema
2220
+ });
2221
+ async function tool31(args) {
2222
+ const params = {
2223
+ spaceId: args.spaceId,
2224
+ environmentId: args.environmentId
2225
+ };
2226
+ const contentfulClient = createToolClient(args);
2227
+ const newEntry = await contentfulClient.entry.create(
2228
+ {
2229
+ ...params,
2230
+ contentTypeId: args.contentTypeId
2231
+ },
2232
+ {
2233
+ fields: args.fields,
2234
+ ...args.metadata ? { metadata: args.metadata } : {}
2235
+ }
2236
+ );
2237
+ return createSuccessResponse("Entry created successfully", { newEntry });
2238
+ }
2239
+ var createEntryTool = withErrorHandling(tool31, "Error creating entry");
2240
+
2241
+ // src/tools/entries/deleteEntry.ts
2242
+ import { z as z38 } from "zod";
2243
+ var DeleteEntryToolParams = BaseToolSchema.extend({
2244
+ entryId: z38.string().describe("The ID of the entry to delete")
2245
+ });
2246
+ async function tool32(args) {
2247
+ const params = {
2248
+ spaceId: args.spaceId,
2249
+ environmentId: args.environmentId,
2250
+ entryId: args.entryId
2251
+ };
2252
+ const contentfulClient = createToolClient(args);
2253
+ const entry = await contentfulClient.entry.get(params);
2254
+ await contentfulClient.entry.delete(params);
2255
+ return createSuccessResponse("Entry deleted successfully", { entry });
2256
+ }
2257
+ var deleteEntryTool = withErrorHandling(tool32, "Error deleting entry");
2258
+
2259
+ // src/tools/entries/updateEntry.ts
2260
+ import { z as z39 } from "zod";
2261
+ var UpdateEntryToolParams = BaseToolSchema.extend({
2262
+ entryId: z39.string().describe("The ID of the entry to update"),
2263
+ fields: z39.record(z39.any()).describe(
2264
+ "The field values to update. Keys should be field IDs and values should be the field content. Will be merged with existing fields."
2265
+ ),
2266
+ metadata: EntryMetadataSchema
2267
+ });
2268
+ async function tool33(args) {
2269
+ const params = {
2270
+ spaceId: args.spaceId,
2271
+ environmentId: args.environmentId,
2272
+ entryId: args.entryId
2273
+ };
2274
+ const contentfulClient = createToolClient(args);
2275
+ const existingEntry = await contentfulClient.entry.get(params);
2276
+ const mergedFields = {
2277
+ ...existingEntry.fields,
2278
+ ...args.fields
2279
+ };
2280
+ const allTags = [
2281
+ ...existingEntry.metadata?.tags || [],
2282
+ ...args.metadata?.tags || []
2283
+ ];
2284
+ const allConcepts = [
2285
+ ...existingEntry.metadata?.concepts || [],
2286
+ ...args.metadata?.concepts || []
2287
+ ];
2288
+ const updatedEntry = await contentfulClient.entry.update(params, {
2289
+ ...existingEntry,
2290
+ fields: mergedFields,
2291
+ metadata: {
2292
+ tags: allTags,
2293
+ concepts: allConcepts
2294
+ }
2295
+ });
2296
+ return createSuccessResponse("Entry updated successfully", { updatedEntry });
2297
+ }
2298
+ var updateEntryTool = withErrorHandling(tool33, "Error updating entry");
2299
+
2300
+ // src/tools/entries/getEntry.ts
2301
+ import { z as z40 } from "zod";
2302
+ var GetEntryToolParams = BaseToolSchema.extend({
2303
+ entryId: z40.string().describe("The ID of the entry to retrieve")
2304
+ });
2305
+ async function tool34(args) {
2306
+ const params = {
2307
+ spaceId: args.spaceId,
2308
+ environmentId: args.environmentId,
2309
+ entryId: args.entryId
2310
+ };
2311
+ const contentfulClient = createToolClient(args);
2312
+ const entry = await contentfulClient.entry.get(params);
2313
+ return createSuccessResponse("Entry retrieved successfully", { entry });
2314
+ }
2315
+ var getEntryTool = withErrorHandling(tool34, "Error retrieving entry");
2316
+
2317
+ // src/tools/entries/publishEntry.ts
2318
+ import { z as z41 } from "zod";
2319
+ var PublishEntryToolParams = BaseToolSchema.extend({
2320
+ entryId: z41.union([z41.string(), z41.array(z41.string()).max(100)]).describe(
2321
+ "The ID of the entry to publish (string) or an array of entry IDs (up to 100 entries)"
2322
+ )
2323
+ });
2324
+ async function tool35(args) {
2325
+ const baseParams = {
2326
+ spaceId: args.spaceId,
2327
+ environmentId: args.environmentId
2328
+ };
2329
+ const contentfulClient = createToolClient(args);
2330
+ const entryIds = Array.isArray(args.entryId) ? args.entryId : [args.entryId];
2331
+ if (entryIds.length === 1) {
2332
+ const entryId = entryIds[0];
2333
+ const params = {
2334
+ ...baseParams,
2335
+ entryId
2336
+ };
2337
+ const entry = await contentfulClient.entry.get(params);
2338
+ const publishedEntry = await contentfulClient.entry.publish(params, entry);
2339
+ return createSuccessResponse("Entry published successfully", {
2340
+ status: publishedEntry.sys.status,
2341
+ entryId
2342
+ });
2343
+ }
2344
+ const entityVersions = await createEntryVersionedLinks(
2345
+ contentfulClient,
2346
+ baseParams,
2347
+ entryIds
2348
+ );
2349
+ const entitiesCollection = createEntitiesCollection(entityVersions);
2350
+ const bulkAction = await contentfulClient.bulkAction.publish(baseParams, {
2351
+ entities: entitiesCollection
2352
+ });
2353
+ const action = await waitForBulkActionCompletion(
2354
+ contentfulClient,
2355
+ baseParams,
2356
+ bulkAction.sys.id
2357
+ );
2358
+ return createSuccessResponse("Entry(s) published successfully", {
2359
+ status: action.sys.status,
2360
+ entryIds
2361
+ });
2362
+ }
2363
+ var publishEntryTool = withErrorHandling(
2364
+ tool35,
2365
+ "Error publishing entry"
2366
+ );
2367
+
2368
+ // src/tools/entries/unpublishEntry.ts
2369
+ import { z as z42 } from "zod";
2370
+ var UnpublishEntryToolParams = BaseToolSchema.extend({
2371
+ entryId: z42.union([z42.string(), z42.array(z42.string()).max(100)]).describe(
2372
+ "The ID of the entry to unpublish (string) or an array of entry IDs (up to 100 entries)"
2373
+ )
2374
+ });
2375
+ async function tool36(args) {
2376
+ const baseParams = {
2377
+ spaceId: args.spaceId,
2378
+ environmentId: args.environmentId
2379
+ };
2380
+ const contentfulClient = createToolClient(args);
2381
+ const entryIds = Array.isArray(args.entryId) ? args.entryId : [args.entryId];
2382
+ if (entryIds.length === 1) {
2383
+ const entryId = entryIds[0];
2384
+ const params = {
2385
+ ...baseParams,
2386
+ entryId
2387
+ };
2388
+ const entry = await contentfulClient.entry.get(params);
2389
+ const unpublishedEntry = await contentfulClient.entry.unpublish(
2390
+ params,
2391
+ entry
2392
+ );
2393
+ return createSuccessResponse("Entry unpublished successfully", {
2394
+ status: unpublishedEntry.sys.status,
2395
+ entryId
2396
+ });
2397
+ }
2398
+ const entityLinks = await createEntryUnversionedLinks(
2399
+ contentfulClient,
2400
+ baseParams,
2401
+ entryIds
2402
+ );
2403
+ const entitiesCollection = createEntitiesCollection(entityLinks);
2404
+ const bulkAction = await contentfulClient.bulkAction.unpublish(baseParams, {
2405
+ entities: entitiesCollection
2406
+ });
2407
+ const action = await waitForBulkActionCompletion(
2408
+ contentfulClient,
2409
+ baseParams,
2410
+ bulkAction.sys.id
2411
+ );
2412
+ return createSuccessResponse("Entry(s) unpublished successfully", {
2413
+ status: action.sys.status,
2414
+ entryIds
2415
+ });
2416
+ }
2417
+ var unpublishEntryTool = withErrorHandling(
2418
+ tool36,
2419
+ "Error unpublishing entry"
2420
+ );
2421
+
2422
+ // src/tools/entries/archiveEntry.ts
2423
+ import { z as z43 } from "zod";
2424
+ var ArchiveEntryToolParams = BaseToolSchema.extend({
2425
+ entryId: z43.union([z43.string(), z43.array(z43.string()).max(100)]).describe(
2426
+ "The ID of the entry to archive (string) or an array of entry IDs (up to 100 entries)"
2427
+ )
2428
+ });
2429
+ async function tool37(args) {
2430
+ const baseParams = {
2431
+ spaceId: args.spaceId,
2432
+ environmentId: args.environmentId
2433
+ };
2434
+ const contentfulClient = createToolClient(args);
2435
+ const entryIds = Array.isArray(args.entryId) ? args.entryId : [args.entryId];
2436
+ const successfullyArchived = [];
2437
+ for (const entryId of entryIds) {
2438
+ try {
2439
+ const params = {
2440
+ ...baseParams,
2441
+ entryId
2442
+ };
2443
+ await contentfulClient.entry.archive(params);
2444
+ successfullyArchived.push(entryId);
2445
+ } catch (error) {
2446
+ const errorMessage = successfullyArchived.length > 0 ? `Failed to archive entry '${entryId}' after successfully archiving ${successfullyArchived.length} entry(s): [${successfullyArchived.join(", ")}]. Original error: ${error instanceof Error ? error.message : String(error)}` : `Failed to archive entry '${entryId}': ${error instanceof Error ? error.message : String(error)}`;
2447
+ throw new Error(errorMessage);
2448
+ }
2449
+ }
2450
+ if (entryIds.length === 1) {
2451
+ return createSuccessResponse("Entry archived successfully", {
2452
+ entryId: entryIds[0]
2453
+ });
2454
+ } else {
2455
+ return createSuccessResponse(
2456
+ `Successfully archived ${entryIds.length} entries`,
2457
+ {
2458
+ archivedCount: entryIds.length,
2459
+ entryIds
2460
+ }
2461
+ );
2462
+ }
2463
+ }
2464
+ var archiveEntryTool = withErrorHandling(
2465
+ tool37,
2466
+ "Error archiving entry"
2467
+ );
2468
+
2469
+ // src/tools/entries/unarchiveEntry.ts
2470
+ import { z as z44 } from "zod";
2471
+ var UnarchiveEntryToolParams = BaseToolSchema.extend({
2472
+ entryId: z44.union([z44.string(), z44.array(z44.string()).max(100)]).describe(
2473
+ "The ID of the entry to unarchive (string) or an array of entry IDs (up to 100 entries)"
2474
+ )
2475
+ });
2476
+ async function tool38(args) {
2477
+ const baseParams = {
2478
+ spaceId: args.spaceId,
2479
+ environmentId: args.environmentId
2480
+ };
2481
+ const contentfulClient = createToolClient(args);
2482
+ const entryIds = Array.isArray(args.entryId) ? args.entryId : [args.entryId];
2483
+ const successfullyUnarchived = [];
2484
+ for (const entryId of entryIds) {
2485
+ try {
2486
+ const params = {
2487
+ ...baseParams,
2488
+ entryId
2489
+ };
2490
+ await contentfulClient.entry.unarchive(params);
2491
+ successfullyUnarchived.push(entryId);
2492
+ } catch (error) {
2493
+ const errorMessage = successfullyUnarchived.length > 0 ? `Failed to unarchive entry '${entryId}' after successfully unarchiving ${successfullyUnarchived.length} entry(s): [${successfullyUnarchived.join(", ")}]. Original error: ${error instanceof Error ? error.message : String(error)}` : `Failed to unarchive entry '${entryId}': ${error instanceof Error ? error.message : String(error)}`;
2494
+ throw new Error(errorMessage);
2495
+ }
2496
+ }
2497
+ if (entryIds.length === 1) {
2498
+ return createSuccessResponse("Entry unarchived successfully", {
2499
+ entryId: entryIds[0]
2500
+ });
2501
+ } else {
2502
+ return createSuccessResponse(
2503
+ `Successfully unarchived ${entryIds.length} entries`,
2504
+ {
2505
+ unarchivedCount: entryIds.length,
2506
+ entryIds
2507
+ }
2508
+ );
2509
+ }
2510
+ }
2511
+ var unarchiveEntryTool = withErrorHandling(
2512
+ tool38,
2513
+ "Error unarchiving entry"
2514
+ );
2515
+
2516
+ // src/tools/entries/register.ts
2517
+ var entryTools = {
2518
+ searchEntries: {
2519
+ title: "search_entries",
2520
+ description: "Search for specific entries in your Contentful space",
2521
+ inputParams: SearchEntriesToolParams.shape,
2522
+ annotations: {
2523
+ readOnlyHint: true,
2524
+ openWorldHint: false
2525
+ },
2526
+ tool: searchEntriesTool
2527
+ },
2528
+ createEntry: {
2529
+ title: "create_entry",
2530
+ description: "Create a new entry in Contentful. Before executing this function, you need to know the contentTypeId (not the content type NAME) and the fields of that contentType. You can get the fields definition by using the GET_CONTENT_TYPE tool. IMPORTANT: All field values MUST include a locale key (e.g., 'en-US') for each value, like: { title: { 'en-US': 'My Title' } }. Every field in Contentful requires a locale even for single-language content. TAGS: To add tags to an entry, include a metadata object with a tags array. Each tag should be an object with sys.type='Link', sys.linkType='Tag', and sys.id='tagId'. Example: { metadata: { tags: [{ sys: { type: 'Link', linkType: 'Tag', id: 'myTagId' } }] } }.",
2531
+ inputParams: CreateEntryToolParams.shape,
2532
+ annotations: {
2533
+ readOnlyHint: false,
2534
+ destructiveHint: false,
2535
+ idempotentHint: false,
2536
+ openWorldHint: false
2537
+ },
2538
+ tool: createEntryTool
2539
+ },
2540
+ getEntry: {
2541
+ title: "get_entry",
2542
+ description: "Retrieve an existing entry",
2543
+ inputParams: GetEntryToolParams.shape,
2544
+ annotations: {
2545
+ readOnlyHint: true,
2546
+ openWorldHint: false
2547
+ },
2548
+ tool: getEntryTool
2549
+ },
2550
+ updateEntry: {
2551
+ title: "update_entry",
2552
+ description: "Update an existing entry. The handler will merge your field updates with the existing entry fields, so you only need to provide the fields you want to change. However, for multiple-locale fields, all existing locales must be included in the update. IMPORTANT: All field values MUST include a locale key (e.g., 'en-US') for each value, like: { title: { 'en-US': 'My Updated Title' } }. Every field in Contentful requires a locale even for single-language content. When updating entries with multiple locales, always include all existing locales in the update to prevent overwriting with empty values. RICH TEXT FIELDS: When updating rich text fields, ALL text nodes MUST include a 'marks' property (can be empty array [] for no formatting). Text nodes with formatting need appropriate marks: { nodeType: 'text', value: 'Bold text', marks: [{ type: 'bold' }], data: {} }.",
2553
+ inputParams: UpdateEntryToolParams.shape,
2554
+ annotations: {
2555
+ readOnlyHint: false,
2556
+ destructiveHint: false,
2557
+ idempotentHint: false,
2558
+ openWorldHint: false
2559
+ },
2560
+ tool: updateEntryTool
2561
+ },
2562
+ deleteEntry: {
2563
+ title: "delete_entry",
2564
+ description: "Delete a specific content entry from your Contentful space",
2565
+ inputParams: DeleteEntryToolParams.shape,
2566
+ annotations: {
2567
+ readOnlyHint: false,
2568
+ destructiveHint: true,
2569
+ idempotentHint: true,
2570
+ openWorldHint: false
2571
+ },
2572
+ tool: deleteEntryTool
2573
+ },
2574
+ publishEntry: {
2575
+ title: "publish_entry",
2576
+ description: "Publish an entry or multiple entries. Accepts either a single entryId (string) or an array of entryIds (up to 100 entries). For a single entry, it uses the standard publish operation. For multiple entries, it automatically uses bulk publishing.",
2577
+ inputParams: PublishEntryToolParams.shape,
2578
+ annotations: {
2579
+ readOnlyHint: false,
2580
+ destructiveHint: false,
2581
+ idempotentHint: true,
2582
+ openWorldHint: false
2583
+ },
2584
+ tool: publishEntryTool
2585
+ },
2586
+ unpublishEntry: {
2587
+ title: "unpublish_entry",
2588
+ description: "Unpublish an entry or multiple entries. Accepts either a single entryId (string) or an array of entryIds (up to 100 entries). For a single entry, it uses the standard unpublish operation. For multiple entries, it automatically uses bulk unpublishing.",
2589
+ inputParams: UnpublishEntryToolParams.shape,
2590
+ annotations: {
2591
+ readOnlyHint: false,
2592
+ destructiveHint: false,
2593
+ idempotentHint: true,
2594
+ openWorldHint: false
2595
+ },
2596
+ tool: unpublishEntryTool
2597
+ },
2598
+ archiveEntry: {
2599
+ title: "archive_entry",
2600
+ description: "Archive an entry or multiple entries. Archives entries that are no longer needed but should be preserved. Entries must be unpublished before they can be archived. Accepts either a single entryId (string) or an array of entryIds (up to 100 entries). For multiple entries, processes each one sequentially as a pseudo-bulk operation.",
2601
+ inputParams: ArchiveEntryToolParams.shape,
2602
+ annotations: {
2603
+ readOnlyHint: false,
2604
+ destructiveHint: false,
2605
+ idempotentHint: true,
2606
+ openWorldHint: false
2607
+ },
2608
+ tool: archiveEntryTool
2609
+ },
2610
+ unarchiveEntry: {
2611
+ title: "unarchive_entry",
2612
+ description: "Unarchive an entry or multiple entries. Restores archived entries, making them available for editing and publishing again. Accepts either a single entryId (string) or an array of entryIds (up to 100 entries). For multiple entries, processes each one sequentially as a pseudo-bulk operation.",
2613
+ inputParams: UnarchiveEntryToolParams.shape,
2614
+ annotations: {
2615
+ readOnlyHint: false,
2616
+ destructiveHint: false,
2617
+ idempotentHint: true,
2618
+ openWorldHint: false
2619
+ },
2620
+ tool: unarchiveEntryTool
2621
+ }
2622
+ };
2623
+
2624
+ // src/tools/environments/createEnvironment.ts
2625
+ import { z as z45 } from "zod";
2626
+ var CreateEnvironmentToolParams = BaseToolSchema.extend({
2627
+ environmentId: z45.string().describe("The ID of the environment to create"),
2628
+ name: z45.string().describe("The name of the environment to create")
2629
+ });
2630
+ async function tool39(args) {
2631
+ const contentfulClient = createToolClient(args);
2632
+ const environment = await contentfulClient.environment.createWithId(
2633
+ {
2634
+ spaceId: args.spaceId,
2635
+ environmentId: args.environmentId
2636
+ },
2637
+ {
2638
+ name: args.name
2639
+ }
2640
+ );
2641
+ return createSuccessResponse("Environment created successfully", {
2642
+ environment
2643
+ });
2644
+ }
2645
+ var createEnvironmentTool = withErrorHandling(
2646
+ tool39,
2647
+ "Error creating environment"
2648
+ );
2649
+
2650
+ // src/tools/environments/listEnvironments.ts
2651
+ import { z as z46 } from "zod";
2652
+ var ListEnvironmentsToolParams = BaseToolSchema.extend({
2653
+ environmentId: z46.string().optional().describe(
2654
+ "The ID of the Contentful environment (not required for listing)"
2655
+ ),
2656
+ limit: z46.number().optional().describe("Maximum number of environments to return (max 10)"),
2657
+ skip: z46.number().optional().describe("Skip this many environments for pagination"),
2658
+ select: z46.string().optional().describe("Comma-separated list of fields to return"),
2659
+ order: z46.string().optional().describe("Order environments by this field")
2660
+ });
2661
+ async function tool40(args) {
2662
+ const clientArgs = {
2663
+ spaceId: args.spaceId,
2664
+ environmentId: args.environmentId || "master"
2665
+ };
2666
+ const contentfulClient = createToolClient(clientArgs);
2667
+ const environments = await contentfulClient.environment.getMany({
2668
+ spaceId: args.spaceId,
2669
+ query: {
2670
+ limit: Math.min(args.limit || 10, 10),
2671
+ skip: args.skip || 0,
2672
+ ...args.select && { select: args.select },
2673
+ ...args.order && { order: args.order }
2674
+ }
2675
+ });
2676
+ const summarizedEnvironments = environments.items.map((environment) => ({
2677
+ id: environment.sys.id,
2678
+ name: environment.name,
2679
+ status: environment.sys.status?.sys?.id || "unknown",
2680
+ createdAt: environment.sys.createdAt,
2681
+ updatedAt: environment.sys.updatedAt
2682
+ }));
2683
+ const summarized = summarizeData(
2684
+ {
2685
+ ...environments,
2686
+ items: summarizedEnvironments
2687
+ },
2688
+ {
2689
+ maxItems: 10,
2690
+ remainingMessage: "To see more environments, please ask me to retrieve the next page using the skip parameter."
2691
+ }
2692
+ );
2693
+ return createSuccessResponse("Environments retrieved successfully", {
2694
+ environments: summarized,
2695
+ total: environments.total,
2696
+ limit: environments.limit,
2697
+ skip: environments.skip
2698
+ });
2699
+ }
2700
+ var listEnvironmentsTool = withErrorHandling(
2701
+ tool40,
2702
+ "Error listing environments"
2703
+ );
2704
+
2705
+ // src/tools/environments/deleteEnvironment.ts
2706
+ import { z as z47 } from "zod";
2707
+ var DeleteEnvironmentToolParams = BaseToolSchema.extend({
2708
+ environmentId: z47.string().describe("The ID of the environment to delete")
2709
+ });
2710
+ async function tool41(args) {
2711
+ const params = {
2712
+ spaceId: args.spaceId,
2713
+ environmentId: args.environmentId
2714
+ };
2715
+ const contentfulClient = createToolClient(args);
2716
+ await contentfulClient.environment.delete(params);
2717
+ return createSuccessResponse("Environment deleted successfully", {
2718
+ environmentId: args.environmentId
2719
+ });
2720
+ }
2721
+ var deleteEnvironmentTool = withErrorHandling(
2722
+ tool41,
2723
+ "Error deleting environment"
2724
+ );
2725
+
2726
+ // src/tools/environments/register.ts
2727
+ var environmentTools = {
2728
+ createEnvironment: {
2729
+ title: "create_environment",
2730
+ description: "Create a new environment",
2731
+ inputParams: CreateEnvironmentToolParams.shape,
2732
+ annotations: {
2733
+ readOnlyHint: false,
2734
+ destructiveHint: false,
2735
+ idempotentHint: false,
2736
+ openWorldHint: false
2737
+ },
2738
+ tool: createEnvironmentTool
2739
+ },
2740
+ listEnvironments: {
2741
+ title: "list_environments",
2742
+ description: "List all environments in a space",
2743
+ inputParams: ListEnvironmentsToolParams.shape,
2744
+ annotations: {
2745
+ readOnlyHint: true,
2746
+ openWorldHint: false
2747
+ },
2748
+ tool: listEnvironmentsTool
2749
+ },
2750
+ deleteEnvironment: {
2751
+ title: "delete_environment",
2752
+ description: "Delete an environment",
2753
+ inputParams: DeleteEnvironmentToolParams.shape,
2754
+ annotations: {
2755
+ readOnlyHint: false,
2756
+ destructiveHint: true,
2757
+ idempotentHint: true,
2758
+ openWorldHint: false
2759
+ },
2760
+ tool: deleteEnvironmentTool
2761
+ }
2762
+ };
2763
+
2764
+ // src/tools/jobs/space-to-space-migration/exportSpace.ts
2765
+ import { z as z49 } from "zod";
2766
+
2767
+ // src/types/querySchema.ts
2768
+ import { z as z48 } from "zod";
2769
+ var EntryQuerySchema = z48.object({
2770
+ content_type: z48.string().optional().describe("Filter by content type"),
2771
+ include: z48.number().optional().describe("Include this many levels of linked entries"),
2772
+ select: z48.string().optional().describe("Comma-separated list of fields to return"),
2773
+ links_to_entry: z48.string().optional().describe("Find entries that link to the specified entry ID"),
2774
+ limit: z48.number().optional().describe("Maximum number of entries to return"),
2775
+ skip: z48.number().optional().describe("Skip this many entries"),
2776
+ order: z48.string().optional().describe("Order entries by this field")
2777
+ });
2778
+ var AssetQuerySchema = z48.object({
2779
+ mimetype_group: z48.string().optional().describe("Filter by MIME type group"),
2780
+ select: z48.string().optional().describe("Comma-separated list of fields to return"),
2781
+ limit: z48.number().optional().describe("Maximum number of assets to return"),
2782
+ skip: z48.number().optional().describe("Skip this many assets"),
2783
+ order: z48.string().optional().describe("Order assets by this field")
2784
+ });
2785
+
2786
+ // src/tools/jobs/space-to-space-migration/exportSpace.ts
2787
+ import path from "path";
2788
+ import { createRequire } from "module";
2789
+ var require2 = createRequire(import.meta.url);
2790
+ var contentfulExport = require2("contentful-export");
2791
+ var ExportSpaceToolParams = BaseToolSchema.extend({
2792
+ exportDir: z49.string().optional().describe(
2793
+ "Directory to save the exported space data (optional, defaults to current directory)"
2794
+ ),
2795
+ saveFile: z49.boolean().optional().default(true).describe("Save the exported space data to a file"),
2796
+ contentFile: z49.string().optional().describe("Custom filename for the exported space data (optional)"),
2797
+ includeDrafts: z49.boolean().optional().default(false).describe("Include draft entries in the export"),
2798
+ includeArchived: z49.boolean().optional().default(false).describe("Include archived entries in the export"),
2799
+ skipContentModel: z49.boolean().optional().default(false).describe("Skip exporting content types"),
2800
+ skipEditorInterfaces: z49.boolean().optional().default(false).describe("Skip exporting editor interfaces"),
2801
+ skipContent: z49.boolean().optional().default(false).describe("Skip exporting entries and assets"),
2802
+ skipRoles: z49.boolean().optional().default(false).describe("Skip exporting roles and permissions"),
2803
+ skipTags: z49.boolean().optional().default(false).describe("Skip exporting tags"),
2804
+ skipWebhooks: z49.boolean().optional().default(false).describe("Skip exporting webhooks"),
2805
+ stripTags: z49.boolean().optional().default(false).describe("Untag assets and entries"),
2806
+ contentOnly: z49.boolean().optional().default(false).describe("Only export assets and entries"),
2807
+ queryEntries: EntryQuerySchema.optional().describe(
2808
+ "Export only entries that match query parameters"
2809
+ ),
2810
+ queryAssets: AssetQuerySchema.optional().describe(
2811
+ "Export only assets that match query parameters"
2812
+ ),
2813
+ downloadAssets: z49.boolean().optional().default(false).describe("Download actual asset files"),
2814
+ maxAllowedLimit: z49.number().optional().default(1e3).describe("Maximum number of items per request"),
2815
+ deliveryToken: z49.string().optional().describe("CDA token to export only published content (excludes tags)"),
2816
+ host: z49.string().optional().describe("Management API host"),
2817
+ hostDelivery: z49.string().optional().describe("Delivery API host"),
2818
+ proxy: z49.string().optional().describe("HTTP/HTTPS proxy config"),
2819
+ rawProxy: z49.boolean().optional().describe("Pass raw proxy config directly to Axios"),
2820
+ headers: z49.record(z49.string()).optional().describe("Additional headers to include in requests"),
2821
+ errorLogFile: z49.string().optional().describe("Path to error log output file"),
2822
+ useVerboseRenderer: z49.boolean().optional().describe("Line-by-line logging, useful for CI"),
2823
+ config: z49.string().optional().describe("Path to a JSON config file with all options")
2824
+ });
2825
+ async function tool42(args) {
2826
+ const clientConfig = getDefaultClientConfig();
2827
+ const managementToken = clientConfig.accessToken;
2828
+ if (!managementToken) {
2829
+ throw new Error("Contentful management token is not configured");
2830
+ }
2831
+ const exportOptions = {
2832
+ ...args,
2833
+ managementToken,
2834
+ environmentId: args.environmentId || "master",
2835
+ exportDir: args.exportDir || process.cwd(),
2836
+ contentFile: args.contentFile || `contentful-export-${args.spaceId}.json`
2837
+ };
2838
+ try {
2839
+ const result = await contentfulExport(exportOptions);
2840
+ const exportPath = path.join(
2841
+ exportOptions.exportDir,
2842
+ exportOptions.contentFile
2843
+ );
2844
+ return createSuccessResponse("Space exported successfully", {
2845
+ spaceId: args.spaceId,
2846
+ environmentId: args.environmentId || "master",
2847
+ exportPath,
2848
+ contentTypes: result.contentTypes?.length || 0,
2849
+ entries: result.entries?.length || 0,
2850
+ assets: result.assets?.length || 0,
2851
+ locales: result.locales?.length || 0,
2852
+ tags: result.tags?.length || 0,
2853
+ webhooks: result.webhooks?.length || 0,
2854
+ roles: result.roles?.length || 0,
2855
+ editorInterfaces: result.editorInterfaces?.length || 0
2856
+ });
2857
+ } catch (error) {
2858
+ throw new Error(
2859
+ `Failed to export space: ${error instanceof Error ? error.message : String(error)}`
2860
+ );
2861
+ }
2862
+ }
2863
+ var createExportSpaceTool = withErrorHandling(
2864
+ tool42,
2865
+ "Error exporting space"
2866
+ );
2867
+
2868
+ // src/tools/jobs/space-to-space-migration/paramCollection.ts
2869
+ import { z as z50 } from "zod";
2870
+ var ParamCollectionToolParams = BaseToolSchema.extend({
2871
+ confirmation: z50.boolean().optional().describe(
2872
+ "User confirmation that they are ready to proceed with the workflow"
2873
+ ),
2874
+ export: z50.object({
2875
+ spaceId: z50.string().optional().describe("ID of the space with source data"),
2876
+ environmentId: z50.string().optional().describe("ID of the environment in the source space"),
2877
+ deliveryToken: z50.string().optional().describe("CDA token to export only published content (excludes tags)"),
2878
+ exportDir: z50.string().optional().describe("Path to export JSON output"),
2879
+ saveFile: z50.boolean().optional().describe("Save the export as a JSON file"),
2880
+ contentFile: z50.string().optional().describe("Filename for exported data"),
2881
+ includeDrafts: z50.boolean().optional().describe("Include drafts in exported entries"),
2882
+ includeArchived: z50.boolean().optional().describe("Include archived entries"),
2883
+ skipContentModel: z50.boolean().optional().describe("Skip exporting content models"),
2884
+ skipEditorInterfaces: z50.boolean().optional().describe("Skip exporting editor interfaces"),
2885
+ skipContent: z50.boolean().optional().describe("Skip exporting entries and assets"),
2886
+ skipRoles: z50.boolean().optional().describe("Skip exporting roles and permissions"),
2887
+ skipTags: z50.boolean().optional().describe("Skip exporting tags"),
2888
+ skipWebhooks: z50.boolean().optional().describe("Skip exporting webhooks"),
2889
+ stripTags: z50.boolean().optional().describe("Remove tags from entries and assets"),
2890
+ contentOnly: z50.boolean().optional().describe("Export only entries and assets"),
2891
+ queryEntries: EntryQuerySchema.optional().describe(
2892
+ "Export only entries that match query parameters"
2893
+ ),
2894
+ queryAssets: AssetQuerySchema.optional().describe(
2895
+ "Export only assets that match query parameters"
2896
+ ),
2897
+ downloadAssets: z50.boolean().optional().describe("Download asset files to disk"),
2898
+ host: z50.string().optional().describe("Management API host"),
2899
+ hostDelivery: z50.string().optional().describe("Delivery API host"),
2900
+ proxy: z50.string().optional().describe("HTTP/HTTPS proxy config"),
2901
+ rawProxy: z50.boolean().optional().describe("Pass raw proxy config directly to Axios"),
2902
+ maxAllowedLimit: z50.number().optional().describe("Page size for requests"),
2903
+ headers: z50.record(z50.any()).optional().describe("Additional headers to include in requests"),
2904
+ errorLogFile: z50.string().optional().describe("Path to error log output file"),
2905
+ useVerboseRenderer: z50.boolean().optional().describe("Line-by-line logging, useful for CI"),
2906
+ config: z50.string().optional().describe("Path to a JSON config file with all options")
2907
+ }).optional(),
2908
+ import: z50.object({
2909
+ spaceId: z50.string().optional().describe("ID of the space to import into"),
2910
+ environmentId: z50.string().optional().describe("Target environment in destination space"),
2911
+ contentFile: z50.string().optional().describe("Path to JSON file containing the content to import"),
2912
+ content: z50.record(z50.any()).optional().describe(
2913
+ "JS object containing import content (must match expected structure)"
2914
+ ),
2915
+ contentModelOnly: z50.boolean().optional().describe("Import only content types"),
2916
+ skipContentModel: z50.boolean().optional().describe("Skip importing content types and locales"),
2917
+ skipLocales: z50.boolean().optional().describe("Skip importing locales"),
2918
+ skipContentUpdates: z50.boolean().optional().describe("Do not update existing content"),
2919
+ skipContentPublishing: z50.boolean().optional().describe("Create but do not publish content"),
2920
+ uploadAssets: z50.boolean().optional().describe("Upload asset files (requires assetsDirectory)"),
2921
+ skipAssetUpdates: z50.boolean().optional().describe("Do not update existing assets"),
2922
+ assetsDirectory: z50.string().optional().describe("Path to directory containing exported asset files"),
2923
+ timeout: z50.number().optional().describe("Time between retries during asset processing (ms)"),
2924
+ retryLimit: z50.number().optional().describe("Max retries for asset processing"),
2925
+ host: z50.string().optional().describe("Management API host"),
2926
+ proxy: z50.string().optional().describe("HTTP/HTTPS proxy string (host:port or user:pass@host:port)"),
2927
+ rawProxy: z50.boolean().optional().describe("Pass proxy config directly to Axios"),
2928
+ rateLimit: z50.number().optional().describe("Max requests per second to the API"),
2929
+ headers: z50.record(z50.any()).optional().describe("Additional headers to attach to requests"),
2930
+ errorLogFile: z50.string().optional().describe("Path to error log file"),
2931
+ useVerboseRenderer: z50.boolean().optional().describe("Line-by-line progress output (good for CI)"),
2932
+ config: z50.string().optional().describe("Path to config JSON file (merged with CLI args)")
2933
+ }).optional()
2934
+ });
2935
+ var paramCollectionConfig = {
2936
+ export: {
2937
+ requiredParams: `
2938
+ spaceId // [string] [required] - ID of the space with source data
2939
+ `,
2940
+ optionalParams: `
2941
+ environmentId // [string] [default: 'master'] - ID of the environment in the source space
2942
+ deliveryToken // [string] - CDA token to export only published content (excludes tags)
2943
+
2944
+ exportDir // [string] [default: process.cwd()] - Path to export JSON output
2945
+ saveFile // [boolean] [default: true] - Save the export as a JSON file
2946
+ contentFile // [string] - Filename for exported data
2947
+
2948
+ includeDrafts // [boolean] [default: false] - Include drafts in exported entries
2949
+ includeArchived // [boolean] [default: false] - Include archived entries
2950
+ skipContentModel // [boolean] [default: false] - Skip exporting content models
2951
+ skipEditorInterfaces // [boolean] [default: false] - Skip exporting editor interfaces
2952
+ skipContent // [boolean] [default: false] - Skip exporting entries and assets
2953
+ skipRoles // [boolean] [default: false] - Skip exporting roles and permissions
2954
+ skipTags // [boolean] [default: false] - Skip exporting tags
2955
+ skipWebhooks // [boolean] [default: false] - Skip exporting webhooks
2956
+ stripTags // [boolean] [default: false] - Remove tags from entries and assets
2957
+ contentOnly // [boolean] [default: false] - Export only entries and assets
2958
+
2959
+ queryEntries // [array] - Export only entries that match query parameters
2960
+ queryAssets // [array] - Export only assets that match query parameters
2961
+ downloadAssets // [boolean] - Download asset files to disk
2962
+
2963
+ host // [string] [default: 'api.contentful.com'] - Management API host
2964
+ hostDelivery // [string] [default: 'cdn.contentful.com'] - Delivery API host
2965
+ proxy // [string] - HTTP/HTTPS proxy config
2966
+ rawProxy // [boolean] - Pass raw proxy config directly to Axios
2967
+ maxAllowedLimit // [number] [default: 1000] - Page size for requests
2968
+ headers // [object] - Additional headers to include in requests
2969
+
2970
+ errorLogFile // [string] - Path to error log output file
2971
+ useVerboseRenderer // [boolean] [default: false] - Line-by-line logging, useful for CI
2972
+ config // [string] - Path to a JSON config file with all options
2973
+ `
2974
+ },
2975
+ import: {
2976
+ requiredParams: `
2977
+ spaceId // [string] [required] - ID of the space to import into
2978
+ managementToken // [string] [required] - Contentful Management API token
2979
+ `,
2980
+ optionalParams: `
2981
+ environmentId // [string] [default: 'master'] - Target environment in destination space
2982
+ contentFile // [string] - Path to JSON file containing the content to import
2983
+ content // [object] - JS object containing import content (must match expected structure)
2984
+
2985
+ contentModelOnly // [boolean] [default: false] - Import only content types
2986
+ skipContentModel // [boolean] [default: false] - Skip importing content types and locales
2987
+ skipLocales // [boolean] [default: false] - Skip importing locales
2988
+ skipContentUpdates // [boolean] [default: false] - Do not update existing content
2989
+ skipContentPublishing // [boolean] [default: false] - Create but do not publish content
2990
+
2991
+ uploadAssets // [boolean] [default: false] - Upload asset files (requires assetsDirectory)
2992
+ skipAssetUpdates // [boolean] [default: false] - Do not update existing assets
2993
+ assetsDirectory // [string] - Path to directory containing exported asset files
2994
+ timeout // [number] [default: 3000] - Time between retries during asset processing (ms)
2995
+ retryLimit // [number] [default: 10] - Max retries for asset processing
2996
+
2997
+ host // [string] [default: 'api.contentful.com'] - Management API host
2998
+ proxy // [string] - HTTP/HTTPS proxy string (host:port or user:pass@host:port)
2999
+ rawProxy // [boolean] - Pass proxy config directly to Axios
3000
+ rateLimit // [number] [default: 7] - Max requests per second to the API
3001
+ headers // [object] - Additional headers to attach to requests
3002
+
3003
+ errorLogFile // [string] - Path to error log file
3004
+ useVerboseRenderer // [boolean] [default: false] - Line-by-line progress output (good for CI)
3005
+ config // [string] - Path to config JSON file (merged with CLI args)
3006
+ `
3007
+ }
3008
+ };
3009
+ async function tool43(args) {
3010
+ const exportParams = args.export ? Object.fromEntries(
3011
+ Object.entries(args.export).filter(([, value]) => value !== void 0)
3012
+ ) : {};
3013
+ const importParams = args.import ? Object.fromEntries(
3014
+ Object.entries(args.import).filter(([, value]) => value !== void 0)
3015
+ ) : {};
3016
+ const params = {
3017
+ export: Object.keys(exportParams).length > 0 ? exportParams : void 0,
3018
+ import: Object.keys(importParams).length > 0 ? importParams : void 0
3019
+ };
3020
+ if (args.confirmation === true) {
3021
+ return createSuccessResponse("User ready to proceed with workflow", {
3022
+ message: "User has confirmed they are ready to proceed with the space-to-space migration workflow.",
3023
+ workflowParams: params,
3024
+ nextStep: "Proceed with the migration workflow using the collected parameters."
3025
+ });
3026
+ }
3027
+ return createSuccessResponse("Param collection tool", {
3028
+ instructions: `
3029
+ Help the user collect the correct parameters for the space to space migration workflow.
3030
+ Call this tool repeatedly until the user feels they are ready to start the workflow.
3031
+
3032
+ Help them understand the required and optional parameters for the export and import tools.
3033
+ Help them understand the instructions for the export and import tools.
3034
+ Help them understand the available params for the export and import tools, ensure you list at all the optional params not just the required ones.
3035
+
3036
+ Continue to build the parameters passed into this tool until the user passes a confirmation that they are ready to start the workflow.
3037
+ `,
3038
+ availableParams: paramCollectionConfig,
3039
+ currentParams: params
3040
+ });
3041
+ }
3042
+ var createParamCollectionTool = withErrorHandling(
3043
+ tool43,
3044
+ "Error creating param collection tool"
3045
+ );
3046
+
3047
+ // src/tools/jobs/space-to-space-migration/importSpace.ts
3048
+ import { z as z51 } from "zod";
3049
+ import { createRequire as createRequire2 } from "module";
3050
+ var require3 = createRequire2(import.meta.url);
3051
+ var contentfulImport = require3("contentful-import");
3052
+ var ImportSpaceToolParams = BaseToolSchema.extend({
3053
+ contentFile: z51.string().optional().describe("Path to JSON file containing the content to import"),
3054
+ content: z51.record(z51.any()).optional().describe(
3055
+ "JS object containing import content (must match expected structure)"
3056
+ ),
3057
+ contentModelOnly: z51.boolean().optional().default(false).describe("Import only content types"),
3058
+ skipContentModel: z51.boolean().optional().default(false).describe("Skip importing content types and locales"),
3059
+ skipLocales: z51.boolean().optional().default(false).describe("Skip importing locales"),
3060
+ skipContentUpdates: z51.boolean().optional().default(false).describe("Do not update existing content"),
3061
+ skipContentPublishing: z51.boolean().optional().default(false).describe("Create but do not publish content"),
3062
+ uploadAssets: z51.boolean().optional().default(false).describe("Upload asset files (requires assetsDirectory)"),
3063
+ skipAssetUpdates: z51.boolean().optional().default(false).describe("Do not update existing assets"),
3064
+ assetsDirectory: z51.string().optional().describe("Path to directory containing exported asset files"),
3065
+ timeout: z51.number().optional().default(3e3).describe("Time between retries during asset processing (ms)"),
3066
+ retryLimit: z51.number().optional().default(10).describe("Max retries for asset processing"),
3067
+ host: z51.string().optional().describe("Management API host"),
3068
+ proxy: z51.string().optional().describe("HTTP/HTTPS proxy string (host:port or user:pass@host:port)"),
3069
+ rawProxy: z51.boolean().optional().describe("Pass proxy config directly to Axios"),
3070
+ rateLimit: z51.number().optional().default(7).describe("Max requests per second to the API"),
3071
+ headers: z51.record(z51.any()).optional().describe("Additional headers to attach to requests"),
3072
+ errorLogFile: z51.string().optional().describe("Path to error log file"),
3073
+ useVerboseRenderer: z51.boolean().optional().describe("Line-by-line progress output (good for CI)"),
3074
+ config: z51.string().optional().describe("Path to config JSON file (merged with CLI args)")
3075
+ });
3076
+ async function tool44(args) {
3077
+ const clientConfig = getDefaultClientConfig();
3078
+ const managementToken = clientConfig.accessToken;
3079
+ if (!managementToken) {
3080
+ throw new Error("Contentful management token is not configured");
3081
+ }
3082
+ const importOptions = {
3083
+ ...args,
3084
+ managementToken,
3085
+ environmentId: args.environmentId || "master"
3086
+ };
3087
+ try {
3088
+ const result = await contentfulImport(importOptions);
3089
+ return createSuccessResponse("Space imported successfully", {
3090
+ spaceId: args.spaceId,
3091
+ environmentId: args.environmentId || "master",
3092
+ contentTypes: result.contentTypes?.length || 0,
3093
+ entries: result.entries?.length || 0,
3094
+ assets: result.assets?.length || 0,
3095
+ locales: result.locales?.length || 0,
3096
+ tags: result.tags?.length || 0,
3097
+ webhooks: result.webhooks?.length || 0,
3098
+ roles: result.roles?.length || 0,
3099
+ editorInterfaces: result.editorInterfaces?.length || 0
3100
+ });
3101
+ } catch (error) {
3102
+ throw new Error(
3103
+ `Failed to import space: ${error instanceof Error ? error.message : String(error)}`
3104
+ );
3105
+ }
3106
+ }
3107
+ var createImportSpaceTool = withErrorHandling(
3108
+ tool44,
3109
+ "Error importing space"
3110
+ );
3111
+
3112
+ // src/tools/jobs/space-to-space-migration/migrationHandler.ts
3113
+ import { z as z52 } from "zod";
3114
+
3115
+ // src/tools/jobs/space-to-space-migration/instructions.ts
3116
+ var S2S_MIGRATION_INSTRUCTIONS = `
3117
+ You are a helpful assistant that can help with space to space migration.
3118
+
3119
+ You will be given a list of tools that can be used to migrate a space to another space.
3120
+
3121
+ ## Workflow Management:
3122
+ The space to space migration workflow is managed by a single unified tool: **space_to_space_migration_handler**
3123
+
3124
+ - To **start** the workflow: Call space_to_space_migration_handler with enableWorkflow=true
3125
+ - To **conclude** the workflow: Call space_to_space_migration_handler with enableWorkflow=false
3126
+
3127
+ Once the workflow is started, you will need to call the tools in the following order:
3128
+
3129
+ 1. space_to_space_migration_handler with enableWorkflow=true (already confirmed by the user)
3130
+ 2. IMPORTANT: After starting the workflow, you MUST ask the user for confirmation before proceeding to the next step. The enabled tools will not appear until the agent is reprompted by the user.
3131
+ 3. space_to_space_param_collection (only call after user confirms they are ready to proceed)
3132
+ 4. export_space
3133
+ 5. import_space
3134
+ 6. space_to_space_migration_handler with enableWorkflow=false (to conclude the workflow)
3135
+
3136
+ ## Path Configuration Best Practices:
3137
+ - ALWAYS use consistent path formats throughout the workflow
3138
+
3139
+ ### Asset Handling Paths:
3140
+ - When downloadAssets=true, the export tool creates an assets directory structure like: exportDir/images.ctfassets.net/
3141
+ - The import tool expects assetsDirectory to point to the images.ctfassets.net directory, not the parent export directory
3142
+
3143
+ Troubleshooting:
3144
+ - If the start_space_to_space_migration is not found, try to call it again on behalf of the user.
3145
+ - If space_to_space_param_collection or other tools are not found, ask the user to confirm they are ready to proceed, as the tools need to be enabled first.
3146
+ - If import fails with path errors, verify that exportDir and assetsDirectory paths are correctly aligned and accessible.
3147
+ `;
3148
+
3149
+ // src/tools/jobs/space-to-space-migration/migrationHandler.ts
3150
+ var S2S_TEARDOWN_INSTRUCTIONS = `
3151
+ The space to space migration workflow has been concluded and all related tools have been disabled.
3152
+
3153
+ The workflow is now complete. You can start a new migration workflow by calling space_to_space_migration_handler with enableWorkflow=true if needed.
3154
+ `;
3155
+ var SpaceToSpaceMigrationHandlerToolParams = BaseToolSchema.extend({
3156
+ enableWorkflow: z52.boolean().describe(
3157
+ "Set to true to enable the workflow tools, false to disable them and conclude the workflow"
3158
+ )
3159
+ });
3160
+ var makeSpaceToSpaceMigrationHandlerTool = (tools) => {
3161
+ async function tool66(args) {
3162
+ const { enableWorkflow } = args;
3163
+ if (enableWorkflow) {
3164
+ tools.forEach((tool67) => {
3165
+ if (tool67) {
3166
+ tool67.enable();
3167
+ }
3168
+ });
3169
+ return createSuccessResponse(
3170
+ "Space to space migration workflow started.",
3171
+ {
3172
+ enableWorkflow,
3173
+ instructions: S2S_MIGRATION_INSTRUCTIONS
3174
+ }
3175
+ );
3176
+ } else {
3177
+ tools.forEach((tool67) => {
3178
+ if (tool67) {
3179
+ tool67.disable();
3180
+ }
3181
+ });
3182
+ return createSuccessResponse(
3183
+ "Space to space migration workflow concluded.",
3184
+ {
3185
+ enableWorkflow,
3186
+ instructions: S2S_TEARDOWN_INSTRUCTIONS
3187
+ }
3188
+ );
3189
+ }
3190
+ }
3191
+ return withErrorHandling(
3192
+ tool66,
3193
+ "Error managing space to space migration workflow"
3194
+ );
3195
+ };
3196
+
3197
+ // src/tools/jobs/space-to-space-migration/register.ts
3198
+ var jobTools = {
3199
+ spaceToSpaceParamCollection: {
3200
+ title: "space_to_space_param_collection",
3201
+ description: "Collect parameters for the space to space migration workflow. This tool should ALWAYS start with confirmation false, until the user confirms they are ready to proceed with the workflow. Do not assume they use wants to proceed with the workflow until they explicitly say so.",
3202
+ inputParams: ParamCollectionToolParams.shape,
3203
+ annotations: {
3204
+ readOnlyHint: true,
3205
+ openWorldHint: false
3206
+ },
3207
+ tool: createParamCollectionTool
3208
+ },
3209
+ exportSpace: {
3210
+ title: "export_space",
3211
+ description: "Export a space to a file",
3212
+ inputParams: ExportSpaceToolParams.shape,
3213
+ annotations: {
3214
+ readOnlyHint: true,
3215
+ openWorldHint: false
3216
+ },
3217
+ tool: createExportSpaceTool
3218
+ },
3219
+ importSpace: {
3220
+ title: "import_space",
3221
+ description: "Import a space from a file. Step 4 of the space to space migration workflow.",
3222
+ inputParams: ImportSpaceToolParams.shape,
3223
+ annotations: {
3224
+ readOnlyHint: false,
3225
+ destructiveHint: false,
3226
+ idempotentHint: false,
3227
+ openWorldHint: false
3228
+ },
3229
+ tool: createImportSpaceTool
3230
+ },
3231
+ spaceToSpaceMigrationHandler: {
3232
+ title: "space_to_space_migration_handler",
3233
+ description: "Enable or disable the space to space migration workflow tools. Set enableWorkflow=true to start, false to conclude the workflow.",
3234
+ inputParams: SpaceToSpaceMigrationHandlerToolParams.shape,
3235
+ annotations: {
3236
+ readOnlyHint: false,
3237
+ destructiveHint: false,
3238
+ idempotentHint: false,
3239
+ openWorldHint: false
3240
+ },
3241
+ tool: makeSpaceToSpaceMigrationHandlerTool
3242
+ }
3243
+ };
3244
+
3245
+ // src/tools/locales/getLocale.ts
3246
+ import { z as z53 } from "zod";
3247
+ var GetLocaleToolParams = BaseToolSchema.extend({
3248
+ localeId: z53.string().describe("The ID of the locale to retrieve")
3249
+ });
3250
+ async function tool45(args) {
3251
+ const params = {
3252
+ spaceId: args.spaceId,
3253
+ environmentId: args.environmentId,
3254
+ localeId: args.localeId
3255
+ };
3256
+ const contentfulClient = createToolClient(args);
3257
+ const locale = await contentfulClient.locale.get(params);
3258
+ return createSuccessResponse("Locale retrieved successfully", { locale });
3259
+ }
3260
+ var getLocaleTool = withErrorHandling(tool45, "Error retrieving locale");
3261
+
3262
+ // src/tools/locales/createLocale.ts
3263
+ import { z as z54 } from "zod";
3264
+ var CreateLocaleToolParams = BaseToolSchema.extend({
3265
+ name: z54.string().describe("The name of the locale"),
3266
+ code: z54.string().describe('The locale code (e.g., "en-US")'),
3267
+ fallbackCode: z54.string().nullable().describe(
3268
+ "The locale code to fallback to when there is no content for the current locale"
3269
+ ),
3270
+ contentDeliveryApi: z54.boolean().optional().default(true).describe(
3271
+ "If the content under this locale should be available on the CDA (for public reading)"
3272
+ ),
3273
+ contentManagementApi: z54.boolean().optional().default(true).describe(
3274
+ "If the content under this locale should be available on the CMA (for editing)"
3275
+ ),
3276
+ default: z54.boolean().optional().default(false).describe("If this is the default locale"),
3277
+ optional: z54.boolean().optional().default(false).describe("If the locale needs to be filled in on entries or not")
3278
+ });
3279
+ async function tool46(args) {
3280
+ const params = {
3281
+ spaceId: args.spaceId,
3282
+ environmentId: args.environmentId
3283
+ };
3284
+ const contentfulClient = createToolClient(args);
3285
+ const newLocale = await contentfulClient.locale.create(params, {
3286
+ name: args.name,
3287
+ code: args.code,
3288
+ fallbackCode: args.fallbackCode,
3289
+ contentDeliveryApi: args.contentDeliveryApi,
3290
+ contentManagementApi: args.contentManagementApi,
3291
+ optional: args.optional
3292
+ });
3293
+ return createSuccessResponse("Locale created successfully", { newLocale });
3294
+ }
3295
+ var createLocaleTool = withErrorHandling(
3296
+ tool46,
3297
+ "Error creating locale"
3298
+ );
3299
+
3300
+ // src/tools/locales/listLocales.ts
3301
+ import { z as z55 } from "zod";
3302
+ var ListLocaleToolParams = BaseToolSchema.extend({
3303
+ limit: z55.number().optional().describe("Maximum number of locales to return"),
3304
+ skip: z55.number().optional().describe("Skip this many locales for pagination"),
3305
+ select: z55.string().optional().describe("Comma-separated list of fields to return"),
3306
+ include: z55.number().optional().describe("Include this many levels of linked entries"),
3307
+ order: z55.string().optional().describe("Order locales by this field")
3308
+ });
3309
+ async function tool47(args) {
3310
+ const params = {
3311
+ spaceId: args.spaceId,
3312
+ environmentId: args.environmentId
3313
+ };
3314
+ const contentfulClient = createToolClient(args);
3315
+ const locales = await contentfulClient.locale.getMany({
3316
+ ...params,
3317
+ query: {
3318
+ limit: args.limit || 100,
3319
+ skip: args.skip || 0,
3320
+ ...args.select && { select: args.select },
3321
+ ...args.include && { include: args.include },
3322
+ ...args.order && { order: args.order }
3323
+ }
3324
+ });
3325
+ const summarizedLocales = locales.items.map((locale) => ({
3326
+ id: locale.sys.id,
3327
+ name: locale.name,
3328
+ code: locale.code,
3329
+ fallbackCode: locale.fallbackCode || null,
3330
+ contentDeliveryApi: locale.contentDeliveryApi,
3331
+ contentManagementApi: locale.contentManagementApi,
3332
+ default: locale.default,
3333
+ optional: locale.optional,
3334
+ createdAt: locale.sys.createdAt,
3335
+ updatedAt: locale.sys.updatedAt,
3336
+ version: locale.sys.version
3337
+ }));
3338
+ const summarized = summarizeData(
3339
+ {
3340
+ ...locales,
3341
+ items: summarizedLocales
3342
+ },
3343
+ {
3344
+ maxItems: 10,
3345
+ remainingMessage: "To see more locales, please ask me to retrieve the next page using the skip parameter."
3346
+ }
3347
+ );
3348
+ return createSuccessResponse("Locales retrieved successfully", {
3349
+ locales: summarized,
3350
+ total: locales.total,
3351
+ limit: locales.limit,
3352
+ skip: locales.skip
3353
+ });
3354
+ }
3355
+ var listLocaleTool = withErrorHandling(tool47, "Error listing locales");
3356
+
3357
+ // src/tools/locales/updateLocale.ts
3358
+ import { z as z56 } from "zod";
3359
+ var UpdateLocaleToolParams = BaseToolSchema.extend({
3360
+ localeId: z56.string().describe("The ID of the locale to update"),
3361
+ fields: z56.object({
3362
+ name: z56.string().optional().describe("The name of the locale"),
3363
+ // NOTE: internal_code changes are not allowed
3364
+ code: z56.string().optional().describe("The code of the locale"),
3365
+ fallbackCode: z56.string().optional().describe(
3366
+ "The locale code to fallback to when there is no content for the current locale"
3367
+ ),
3368
+ contentDeliveryApi: z56.boolean().optional().describe(
3369
+ "If the content under this locale should be available on the CDA (for public reading)"
3370
+ ),
3371
+ contentManagementApi: z56.boolean().optional().describe(
3372
+ "If the content under this locale should be available on the CMA (for editing)"
3373
+ ),
3374
+ optional: z56.boolean().optional().describe("If the locale needs to be filled in on entries or not")
3375
+ })
3376
+ });
3377
+ async function tool48(args) {
3378
+ const params = {
3379
+ spaceId: args.spaceId,
3380
+ environmentId: args.environmentId,
3381
+ localeId: args.localeId
3382
+ };
3383
+ const contentfulClient = createToolClient(args);
3384
+ const existingLocale = await contentfulClient.locale.get(params);
3385
+ delete existingLocale.internal_code;
3386
+ const updateData = { ...existingLocale, ...args.fields };
3387
+ const updatedLocale = await contentfulClient.locale.update(
3388
+ params,
3389
+ updateData
3390
+ );
3391
+ return createSuccessResponse("Locale updated successfully", {
3392
+ updatedLocale
3393
+ });
3394
+ }
3395
+ var updateLocaleTool = withErrorHandling(
3396
+ tool48,
3397
+ "Error updating locale"
3398
+ );
3399
+
3400
+ // src/tools/locales/deleteLocale.ts
3401
+ import { z as z57 } from "zod";
3402
+ var DeleteLocaleToolParams = BaseToolSchema.extend({
3403
+ localeId: z57.string().describe("The ID of the locale to delete")
3404
+ });
3405
+ async function tool49(args) {
3406
+ const params = {
3407
+ spaceId: args.spaceId,
3408
+ environmentId: args.environmentId,
3409
+ localeId: args.localeId
3410
+ };
3411
+ const contentfulClient = createToolClient(args);
3412
+ const locale = await contentfulClient.locale.get(params);
3413
+ await contentfulClient.locale.delete(params);
3414
+ return createSuccessResponse("Locale deleted successfully", { locale });
3415
+ }
3416
+ var deleteLocaleTool = withErrorHandling(
3417
+ tool49,
3418
+ "Error deleting locale"
3419
+ );
3420
+
3421
+ // src/tools/locales/register.ts
3422
+ var localeTools = {
3423
+ getLocale: {
3424
+ title: "get_locale",
3425
+ description: "Retrieve a specific locale from your Contentful environment",
3426
+ inputParams: GetLocaleToolParams.shape,
3427
+ annotations: {
3428
+ readOnlyHint: true,
3429
+ openWorldHint: false
3430
+ },
3431
+ tool: getLocaleTool
3432
+ },
3433
+ createLocale: {
3434
+ title: "create_locale",
3435
+ description: `Create a new locale in your Contentful environment. A locale defines a language-region pair (e.g., "en-US" for English United States). You can specify fallback behavior, API availability settings, and whether the locale is optional for content editors. Note: setting 'default' is currently not supported.`,
3436
+ inputParams: CreateLocaleToolParams.shape,
3437
+ annotations: {
3438
+ readOnlyHint: false,
3439
+ destructiveHint: false,
3440
+ idempotentHint: false,
3441
+ openWorldHint: false
3442
+ },
3443
+ tool: createLocaleTool
3444
+ },
3445
+ listLocales: {
3446
+ title: "list_locales",
3447
+ description: "List all locales in your Contentful environment. Returns locale information including language codes, fallback settings, and API availability.",
3448
+ inputParams: ListLocaleToolParams.shape,
3449
+ annotations: {
3450
+ readOnlyHint: true,
3451
+ openWorldHint: false
3452
+ },
3453
+ tool: listLocaleTool
3454
+ },
3455
+ updateLocale: {
3456
+ title: "update_locale",
3457
+ description: "Update an existing locale in your Contentful environment. You can modify the locale name, code, fallback behavior, API availability settings, and whether the locale is optional for content editors. Only provide the fields you want to change. IMPORTANT: internal_code cannot be updated.",
3458
+ inputParams: UpdateLocaleToolParams.shape,
3459
+ annotations: {
3460
+ readOnlyHint: false,
3461
+ destructiveHint: false,
3462
+ idempotentHint: false,
3463
+ openWorldHint: false
3464
+ },
3465
+ tool: updateLocaleTool
3466
+ },
3467
+ deleteLocale: {
3468
+ title: "delete_locale",
3469
+ description: "Delete a specific locale from your Contentful environment. This operation permanently removes the locale and cannot be undone.",
3470
+ inputParams: DeleteLocaleToolParams.shape,
3471
+ annotations: {
3472
+ readOnlyHint: false,
3473
+ destructiveHint: true,
3474
+ idempotentHint: true,
3475
+ openWorldHint: false
3476
+ },
3477
+ tool: deleteLocaleTool
3478
+ }
3479
+ };
3480
+
3481
+ // src/tools/orgs/listOrgs.ts
3482
+ import { z as z58 } from "zod";
3483
+ import ctfl2 from "contentful-management";
3484
+ var ListOrgsToolParams = z58.object({
3485
+ limit: z58.number().optional().describe("Maximum number of organizations to return (max 10)"),
3486
+ skip: z58.number().optional().describe("Skip this many organizations for pagination"),
3487
+ select: z58.string().optional().describe("Comma-separated list of fields to return"),
3488
+ order: z58.string().optional().describe("Order organizations by this field")
3489
+ });
3490
+ async function tool50(args) {
3491
+ const clientConfig = getDefaultClientConfig();
3492
+ delete clientConfig.space;
3493
+ const contentfulClient = ctfl2.createClient(clientConfig, { type: "plain" });
3494
+ const organizations = await contentfulClient.organization.getAll({
3495
+ query: {
3496
+ limit: Math.min(args.limit || 10, 10),
3497
+ skip: args.skip || 0,
3498
+ ...args.select && { select: args.select },
3499
+ ...args.order && { order: args.order }
3500
+ }
3501
+ });
3502
+ const summarizedOrganizations = organizations.items.map((org) => ({
3503
+ id: org.sys.id,
3504
+ name: org.name,
3505
+ createdAt: org.sys.createdAt,
3506
+ updatedAt: org.sys.updatedAt
3507
+ }));
3508
+ const summarized = summarizeData(
3509
+ {
3510
+ ...organizations,
3511
+ items: summarizedOrganizations
3512
+ },
3513
+ {
3514
+ maxItems: 10,
3515
+ remainingMessage: "To see more organizations, please ask me to retrieve the next page using the skip parameter."
3516
+ }
3517
+ );
3518
+ return createSuccessResponse("Organizations retrieved successfully", {
3519
+ organizations: summarized,
3520
+ total: organizations.total,
3521
+ limit: organizations.limit,
3522
+ skip: organizations.skip
3523
+ });
3524
+ }
3525
+ var listOrgsTool = withErrorHandling(
3526
+ tool50,
3527
+ "Error listing organizations"
3528
+ );
3529
+
3530
+ // src/tools/orgs/getOrg.ts
3531
+ import { z as z59 } from "zod";
3532
+ import ctfl3 from "contentful-management";
3533
+ var GetOrgToolParams = z59.object({
3534
+ organizationId: z59.string().describe("The ID of the organization to retrieve")
3535
+ });
3536
+ async function tool51(args) {
3537
+ const clientConfig = getDefaultClientConfig();
3538
+ delete clientConfig.space;
3539
+ const contentfulClient = ctfl3.createClient(clientConfig, { type: "plain" });
3540
+ const organization = await contentfulClient.organization.get({
3541
+ organizationId: args.organizationId
3542
+ });
3543
+ return createSuccessResponse("Organization retrieved successfully", {
3544
+ organization
3545
+ });
3546
+ }
3547
+ var getOrgTool = withErrorHandling(
3548
+ tool51,
3549
+ "Error retrieving organization"
3550
+ );
3551
+
3552
+ // src/tools/orgs/register.ts
3553
+ var orgTools = {
3554
+ listOrgs: {
3555
+ title: "list_orgs",
3556
+ description: "List all organizations that the user has access to",
3557
+ inputParams: ListOrgsToolParams.shape,
3558
+ annotations: {
3559
+ readOnlyHint: true,
3560
+ openWorldHint: false
3561
+ },
3562
+ tool: listOrgsTool
3563
+ },
3564
+ getOrg: {
3565
+ title: "get_org",
3566
+ description: "Get details of a specific organization",
3567
+ inputParams: GetOrgToolParams.shape,
3568
+ annotations: {
3569
+ readOnlyHint: true,
3570
+ openWorldHint: false
3571
+ },
3572
+ tool: getOrgTool
3573
+ }
3574
+ };
3575
+
3576
+ // src/tools/spaces/listSpaces.ts
3577
+ import { z as z60 } from "zod";
3578
+ import ctfl4 from "contentful-management";
3579
+ var ListSpacesToolParams = z60.object({
3580
+ limit: z60.number().optional().describe("Maximum number of spaces to return (max 10)"),
3581
+ skip: z60.number().optional().describe("Skip this many spaces for pagination"),
3582
+ select: z60.string().optional().describe("Comma-separated list of fields to return"),
3583
+ order: z60.string().optional().describe("Order spaces by this field")
3584
+ });
3585
+ async function tool52(args) {
3586
+ const clientConfig = getDefaultClientConfig();
3587
+ delete clientConfig.space;
3588
+ const contentfulClient = ctfl4.createClient(clientConfig, { type: "plain" });
3589
+ const spaces = await contentfulClient.space.getMany({
3590
+ query: {
3591
+ limit: Math.min(args.limit || 10, 10),
3592
+ skip: args.skip || 0,
3593
+ ...args.select && { select: args.select },
3594
+ ...args.order && { order: args.order }
3595
+ }
3596
+ });
3597
+ const summarizedSpaces = spaces.items.map((space) => ({
3598
+ id: space.sys.id,
3599
+ name: space.name,
3600
+ createdAt: space.sys.createdAt,
3601
+ updatedAt: space.sys.updatedAt
3602
+ }));
3603
+ const summarized = summarizeData(
3604
+ {
3605
+ ...spaces,
3606
+ items: summarizedSpaces
3607
+ },
3608
+ {
3609
+ maxItems: 10,
3610
+ remainingMessage: "To see more spaces, please ask me to retrieve the next page using the skip parameter."
3611
+ }
3612
+ );
3613
+ return createSuccessResponse("Spaces retrieved successfully", {
3614
+ spaces: summarized,
3615
+ total: spaces.total,
3616
+ limit: spaces.limit,
3617
+ skip: spaces.skip
3618
+ });
3619
+ }
3620
+ var listSpacesTool = withErrorHandling(tool52, "Error listing spaces");
3621
+
3622
+ // src/tools/spaces/getSpace.ts
3623
+ import { z as z61 } from "zod";
3624
+ import ctfl5 from "contentful-management";
3625
+ var GetSpaceToolParams = z61.object({
3626
+ spaceId: z61.string().describe("The ID of the space to retrieve")
3627
+ });
3628
+ async function tool53(args) {
3629
+ const clientConfig = getDefaultClientConfig();
3630
+ delete clientConfig.space;
3631
+ const contentfulClient = ctfl5.createClient(clientConfig, { type: "plain" });
3632
+ const space = await contentfulClient.space.get({
3633
+ spaceId: args.spaceId
3634
+ });
3635
+ return createSuccessResponse("Space retrieved successfully", { space });
3636
+ }
3637
+ var getSpaceTool = withErrorHandling(tool53, "Error retrieving space");
3638
+
3639
+ // src/tools/spaces/register.ts
3640
+ var spaceTools = {
3641
+ listSpaces: {
3642
+ title: "list_spaces",
3643
+ description: "List all available spaces",
3644
+ inputParams: ListSpacesToolParams.shape,
3645
+ annotations: {
3646
+ readOnlyHint: true,
3647
+ openWorldHint: false
3648
+ },
3649
+ tool: listSpacesTool
3650
+ },
3651
+ getSpace: {
3652
+ title: "get_space",
3653
+ description: "Get details of a space",
3654
+ inputParams: GetSpaceToolParams.shape,
3655
+ annotations: {
3656
+ readOnlyHint: true,
3657
+ openWorldHint: false
3658
+ },
3659
+ tool: getSpaceTool
3660
+ }
3661
+ };
3662
+
3663
+ // src/tools/tags/listTags.ts
3664
+ import { z as z62 } from "zod";
3665
+ var ListTagsToolParams = BaseToolSchema.extend({
3666
+ limit: z62.number().optional().describe("Maximum number of tags to return"),
3667
+ skip: z62.number().optional().describe("Skip this many tags for pagination"),
3668
+ select: z62.string().optional().describe("Comma-separated list of fields to return"),
3669
+ order: z62.string().optional().describe("Order tags by this field")
3670
+ });
3671
+ async function tool54(args) {
3672
+ const params = {
3673
+ spaceId: args.spaceId,
3674
+ environmentId: args.environmentId
3675
+ };
3676
+ const contentfulClient = createToolClient(args);
3677
+ const tags = await contentfulClient.tag.getMany({
3678
+ ...params,
3679
+ query: {
3680
+ limit: args.limit || 100,
3681
+ skip: args.skip || 0,
3682
+ ...args.select && { select: args.select },
3683
+ ...args.order && { order: args.order }
3684
+ }
3685
+ });
3686
+ const summarizedTags = tags.items.map((tag) => ({
3687
+ id: tag.sys.id,
3688
+ name: tag.name,
3689
+ visibility: tag.sys.visibility,
3690
+ createdAt: tag.sys.createdAt,
3691
+ updatedAt: tag.sys.updatedAt
3692
+ }));
3693
+ const summarized = summarizeData(
3694
+ {
3695
+ ...tags,
3696
+ items: summarizedTags
3697
+ },
3698
+ {
3699
+ maxItems: 100,
3700
+ remainingMessage: "To see more tags, please ask me to retrieve the next page using the skip parameter."
3701
+ }
3702
+ );
3703
+ return createSuccessResponse("Tags retrieved successfully", {
3704
+ tags: summarized,
3705
+ total: tags.total,
3706
+ limit: tags.limit,
3707
+ skip: tags.skip
3708
+ });
3709
+ }
3710
+ var listTagsTool = withErrorHandling(tool54, "Error listing tags");
3711
+
3712
+ // src/tools/tags/createTag.ts
3713
+ import { z as z63 } from "zod";
3714
+ var CreateTagToolParams = BaseToolSchema.extend({
3715
+ name: z63.string().describe("The name of the tag"),
3716
+ id: z63.string().describe("The ID of the tag"),
3717
+ visibility: z63.enum(["public", "private"]).describe("The visibility of the tag. Default to private if not specified")
3718
+ });
3719
+ async function tool55(args) {
3720
+ const params = {
3721
+ spaceId: args.spaceId,
3722
+ environmentId: args.environmentId,
3723
+ tagId: args.id
3724
+ };
3725
+ const contentfulClient = createToolClient(args);
3726
+ const newTag = await contentfulClient.tag.createWithId(params, {
3727
+ name: args.name,
3728
+ sys: { visibility: args.visibility }
3729
+ });
3730
+ return createSuccessResponse("Tag created successfully", { newTag });
3731
+ }
3732
+ var createTagTool = withErrorHandling(tool55, "Error creating tag");
3733
+
3734
+ // src/tools/tags/register.ts
3735
+ var tagTools = {
3736
+ listTags: {
3737
+ title: "list_tags",
3738
+ description: "List all tags in a space. Returns all tags that exist in a given environment.",
3739
+ inputParams: ListTagsToolParams.shape,
3740
+ annotations: {
3741
+ readOnlyHint: true,
3742
+ openWorldHint: false
3743
+ },
3744
+ tool: listTagsTool
3745
+ },
3746
+ createTag: {
3747
+ title: "create_tag",
3748
+ description: "Creates a new tag and returns it. Both name and ID must be unique to each environment. Tag names can be modified after creation, but the tag ID cannot. The tag visibility can be set to public or private, defaulting to private if not specified.",
3749
+ inputParams: CreateTagToolParams.shape,
3750
+ annotations: {
3751
+ readOnlyHint: false,
3752
+ destructiveHint: false,
3753
+ idempotentHint: false,
3754
+ openWorldHint: false
3755
+ },
3756
+ tool: createTagTool
3757
+ }
3758
+ };
3759
+
3760
+ // src/tools/taxonomies/concept-schemes/createConceptScheme.ts
3761
+ import { z as z65 } from "zod";
3762
+ import ctfl6 from "contentful-management";
3763
+
3764
+ // src/types/conceptPayloadTypes.ts
3765
+ import { z as z64 } from "zod";
3766
+ var TaxonomyConceptLinkSchema = z64.object({
3767
+ sys: z64.object({
3768
+ type: z64.literal("Link"),
3769
+ linkType: z64.literal("TaxonomyConcept"),
3770
+ id: z64.string()
3771
+ })
3772
+ });
3773
+
3774
+ // src/tools/taxonomies/concept-schemes/createConceptScheme.ts
3775
+ var CreateConceptSchemeToolParams = z65.object({
3776
+ organizationId: z65.string().describe("The ID of the Contentful organization"),
3777
+ conceptSchemeId: z65.string().optional().describe(
3778
+ "Optional user-defined ID for the concept scheme. If not provided, Contentful will generate one automatically."
3779
+ ),
3780
+ prefLabel: z65.record(z65.string()).describe("The preferred label for the concept scheme (localized)"),
3781
+ uri: z65.string().nullable().optional().describe("The URI for the concept scheme"),
3782
+ definition: z65.record(z65.string().nullable()).optional().describe("Definition of the concept scheme (localized)"),
3783
+ editorialNote: z65.record(z65.string().nullable()).optional().describe("Editorial note for the concept scheme (localized)"),
3784
+ historyNote: z65.record(z65.string().nullable()).optional().describe("History note for the concept scheme (localized)"),
3785
+ example: z65.record(z65.string().nullable()).optional().describe("Example for the concept scheme (localized)"),
3786
+ note: z65.record(z65.string().nullable()).optional().describe("General note for the concept scheme (localized)"),
3787
+ scopeNote: z65.record(z65.string().nullable()).optional().describe("Scope note for the concept scheme (localized)"),
3788
+ topConcepts: z65.array(TaxonomyConceptLinkSchema).optional().describe("Links to top-level concepts in this scheme")
3789
+ });
3790
+ async function tool56(args) {
3791
+ const clientConfig = getDefaultClientConfig();
3792
+ delete clientConfig.space;
3793
+ const contentfulClient = ctfl6.createClient(clientConfig, { type: "plain" });
3794
+ const conceptSchemePayload = {
3795
+ prefLabel: args.prefLabel,
3796
+ ...Object.fromEntries(
3797
+ Object.entries({
3798
+ uri: args.uri,
3799
+ definition: args.definition,
3800
+ editorialNote: args.editorialNote,
3801
+ historyNote: args.historyNote,
3802
+ example: args.example,
3803
+ note: args.note,
3804
+ scopeNote: args.scopeNote,
3805
+ topConcepts: args.topConcepts
3806
+ }).filter(([, value]) => value !== void 0)
3807
+ )
3808
+ };
3809
+ const newConceptScheme = args.conceptSchemeId ? await contentfulClient.conceptScheme.createWithId(
3810
+ {
3811
+ organizationId: args.organizationId,
3812
+ conceptSchemeId: args.conceptSchemeId
3813
+ },
3814
+ conceptSchemePayload
3815
+ ) : await contentfulClient.conceptScheme.create(
3816
+ { organizationId: args.organizationId },
3817
+ conceptSchemePayload
3818
+ );
3819
+ return createSuccessResponse("Concept scheme created successfully", {
3820
+ newConceptScheme
3821
+ });
3822
+ }
3823
+ var createConceptSchemeTool = withErrorHandling(
3824
+ tool56,
3825
+ "Error creating concept scheme"
3826
+ );
3827
+
3828
+ // src/tools/taxonomies/concept-schemes/getConceptScheme.ts
3829
+ import { z as z66 } from "zod";
3830
+ import ctfl7 from "contentful-management";
3831
+ var GetConceptSchemeToolParams = z66.object({
3832
+ organizationId: z66.string().describe("The ID of the Contentful organization"),
3833
+ conceptSchemeId: z66.string().describe("The ID of the concept scheme to retrieve")
3834
+ });
3835
+ async function tool57(args) {
3836
+ const clientConfig = getDefaultClientConfig();
3837
+ delete clientConfig.space;
3838
+ const contentfulClient = ctfl7.createClient(clientConfig, { type: "plain" });
3839
+ const params = {
3840
+ organizationId: args.organizationId,
3841
+ conceptSchemeId: args.conceptSchemeId
3842
+ };
3843
+ const conceptScheme = await contentfulClient.conceptScheme.get(params);
3844
+ return createSuccessResponse("Concept scheme retrieved successfully", {
3845
+ conceptScheme
3846
+ });
3847
+ }
3848
+ var getConceptSchemeTool = withErrorHandling(
3849
+ tool57,
3850
+ "Error retrieving concept scheme"
3851
+ );
3852
+
3853
+ // src/tools/taxonomies/concept-schemes/listConceptSchemes.ts
3854
+ import { z as z67 } from "zod";
3855
+ import ctfl8 from "contentful-management";
3856
+ var ListConceptSchemesToolParams = z67.object({
3857
+ organizationId: z67.string().describe("The ID of the Contentful organization"),
3858
+ limit: z67.number().optional().describe("Maximum number of concept schemes to return"),
3859
+ skip: z67.number().optional().describe("Skip this many concept schemes for pagination"),
3860
+ select: z67.string().optional().describe("Comma-separated list of fields to return"),
3861
+ include: z67.number().optional().describe("Include this many levels of linked entries"),
3862
+ order: z67.string().optional().describe("Order concept schemes by this field")
3863
+ });
3864
+ async function tool58(args) {
3865
+ const clientConfig = getDefaultClientConfig();
3866
+ delete clientConfig.space;
3867
+ const contentfulClient = ctfl8.createClient(clientConfig, { type: "plain" });
3868
+ const conceptSchemes = await contentfulClient.conceptScheme.getMany({
3869
+ organizationId: args.organizationId,
3870
+ query: {
3871
+ limit: args.limit || 10,
3872
+ skip: args.skip || 0,
3873
+ ...args.select && { select: args.select },
3874
+ ...args.include && { include: args.include },
3875
+ ...args.order && { order: args.order }
3876
+ }
3877
+ });
3878
+ const summarizedConceptSchemes = conceptSchemes.items.map(
3879
+ (conceptScheme) => ({
3880
+ id: conceptScheme.sys.id,
3881
+ prefLabel: conceptScheme.prefLabel || {},
3882
+ uri: conceptScheme.uri || null,
3883
+ definition: conceptScheme.definition || null,
3884
+ topConcepts: conceptScheme.topConcepts || [],
3885
+ createdAt: conceptScheme.sys.createdAt,
3886
+ updatedAt: conceptScheme.sys.updatedAt,
3887
+ version: conceptScheme.sys.version
3888
+ })
3889
+ );
3890
+ const summarized = summarizeData(
3891
+ {
3892
+ ...conceptSchemes,
3893
+ items: summarizedConceptSchemes
3894
+ },
3895
+ {
3896
+ maxItems: 10,
3897
+ remainingMessage: "To see more concept schemes, please ask me to retrieve the next page using the skip parameter."
3898
+ }
3899
+ );
3900
+ return createSuccessResponse("Concept schemes retrieved successfully", {
3901
+ conceptSchemes: summarized,
3902
+ total: conceptSchemes.total || conceptSchemes.items.length,
3903
+ limit: conceptSchemes.limit || args.limit || 10,
3904
+ skip: conceptSchemes.skip || args.skip || 0
3905
+ });
3906
+ }
3907
+ var listConceptSchemesTool = withErrorHandling(
3908
+ tool58,
3909
+ "Error listing concept schemes"
3910
+ );
3911
+
3912
+ // src/tools/taxonomies/concept-schemes/updateConceptScheme.ts
3913
+ import { z as z68 } from "zod";
3914
+ import ctfl9 from "contentful-management";
3915
+ var UpdateConceptSchemeToolParams = z68.object({
3916
+ organizationId: z68.string().describe("The ID of the Contentful organization"),
3917
+ conceptSchemeId: z68.string().describe("The ID of the concept scheme to update"),
3918
+ version: z68.number().describe("The current version of the concept scheme"),
3919
+ prefLabel: z68.record(z68.string()).optional().describe("The preferred label for the concept scheme (localized)"),
3920
+ uri: z68.string().nullable().optional().describe("The URI for the concept scheme"),
3921
+ definition: z68.record(z68.string().nullable()).optional().describe("Definition of the concept scheme (localized)"),
3922
+ editorialNote: z68.record(z68.string().nullable()).optional().describe("Editorial note for the concept scheme (localized)"),
3923
+ historyNote: z68.record(z68.string().nullable()).optional().describe("History note for the concept scheme (localized)"),
3924
+ example: z68.record(z68.string().nullable()).optional().describe("Example for the concept scheme (localized)"),
3925
+ note: z68.record(z68.string().nullable()).optional().describe("General note for the concept scheme (localized)"),
3926
+ scopeNote: z68.record(z68.string().nullable()).optional().describe("Scope note for the concept scheme (localized)"),
3927
+ topConcepts: z68.array(TaxonomyConceptLinkSchema).optional().describe("Links to top-level concepts in this scheme"),
3928
+ addConcept: z68.string().optional().describe(
3929
+ "ID of a concept to add to this scheme (adds to both concepts and topConcepts)"
3930
+ )
3931
+ });
3932
+ async function tool59(args) {
3933
+ const clientConfig = getDefaultClientConfig();
3934
+ delete clientConfig.space;
3935
+ const contentfulClient = ctfl9.createClient(clientConfig, { type: "plain" });
3936
+ const params = {
3937
+ organizationId: args.organizationId,
3938
+ conceptSchemeId: args.conceptSchemeId
3939
+ };
3940
+ const fieldMappings = {
3941
+ prefLabel: "/prefLabel",
3942
+ definition: "/definition",
3943
+ editorialNote: "/editorialNote",
3944
+ historyNote: "/historyNote",
3945
+ example: "/example",
3946
+ note: "/note",
3947
+ scopeNote: "/scopeNote",
3948
+ topConcepts: "/topConcepts"
3949
+ };
3950
+ const patchOperations = [];
3951
+ Object.entries(fieldMappings).forEach(([field, path2]) => {
3952
+ const value = args[field];
3953
+ if (value !== void 0) {
3954
+ patchOperations.push({
3955
+ op: "replace",
3956
+ path: path2,
3957
+ value
3958
+ });
3959
+ }
3960
+ });
3961
+ if (args.uri !== void 0) {
3962
+ patchOperations.push({
3963
+ op: args.uri === null ? "remove" : "replace",
3964
+ path: "/uri",
3965
+ ...args.uri !== null && { value: args.uri }
3966
+ });
3967
+ }
3968
+ if (args.addConcept) {
3969
+ const conceptLink = {
3970
+ sys: {
3971
+ id: args.addConcept,
3972
+ linkType: "TaxonomyConcept",
3973
+ type: "Link"
3974
+ }
3975
+ };
3976
+ patchOperations.push({
3977
+ op: "add",
3978
+ path: "/concepts/-",
3979
+ value: conceptLink
3980
+ });
3981
+ patchOperations.push({
3982
+ op: "add",
3983
+ path: "/topConcepts/-",
3984
+ value: conceptLink
3985
+ });
3986
+ }
3987
+ const updatedConceptScheme = await contentfulClient.conceptScheme.update(
3988
+ {
3989
+ ...params,
3990
+ version: args.version
3991
+ },
3992
+ patchOperations
3993
+ );
3994
+ return createSuccessResponse("Concept scheme updated successfully", {
3995
+ updatedConceptScheme
3996
+ });
3997
+ }
3998
+ var updateConceptSchemeTool = withErrorHandling(
3999
+ tool59,
4000
+ "Error updating concept scheme"
4001
+ );
4002
+
4003
+ // src/tools/taxonomies/concept-schemes/deleteConceptScheme.ts
4004
+ import { z as z69 } from "zod";
4005
+ import ctfl10 from "contentful-management";
4006
+ var DeleteConceptSchemeToolParams = z69.object({
4007
+ organizationId: z69.string().describe("The ID of the Contentful organization"),
4008
+ conceptSchemeId: z69.string().describe("The ID of the concept scheme to delete"),
4009
+ version: z69.number().describe("The version of the concept scheme to delete")
4010
+ });
4011
+ async function tool60(args) {
4012
+ const clientConfig = getDefaultClientConfig();
4013
+ delete clientConfig.space;
4014
+ const contentfulClient = ctfl10.createClient(clientConfig, { type: "plain" });
4015
+ await contentfulClient.conceptScheme.delete({
4016
+ organizationId: args.organizationId,
4017
+ conceptSchemeId: args.conceptSchemeId,
4018
+ version: args.version
4019
+ });
4020
+ return createSuccessResponse("Concept scheme deleted successfully", {
4021
+ conceptSchemeId: args.conceptSchemeId
4022
+ });
4023
+ }
4024
+ var deleteConceptSchemeTool = withErrorHandling(
4025
+ tool60,
4026
+ "Error deleting concept scheme"
4027
+ );
4028
+
4029
+ // src/tools/taxonomies/concept-schemes/register.ts
4030
+ var conceptSchemeTools = {
4031
+ createConceptScheme: {
4032
+ title: "create_concept_scheme",
4033
+ description: "Create a new taxonomy concept scheme in Contentful. Concept schemes organize related concepts and provide hierarchical structure for taxonomy management. The prefLabel is required and should be localized. You can optionally provide a conceptSchemeId for a user-defined ID, or let Contentful generate one automatically. You can also include definitions, notes, and references to top-level concepts.",
4034
+ inputParams: CreateConceptSchemeToolParams.shape,
4035
+ annotations: {
4036
+ readOnlyHint: false,
4037
+ destructiveHint: false,
4038
+ idempotentHint: false,
4039
+ openWorldHint: false
4040
+ },
4041
+ tool: createConceptSchemeTool
4042
+ },
4043
+ getConceptScheme: {
4044
+ title: "get_concept_scheme",
4045
+ description: "Retrieve a specific taxonomy concept scheme from Contentful. Returns the complete concept scheme with all its properties including prefLabel, definition, topConcepts, and other metadata.",
4046
+ inputParams: GetConceptSchemeToolParams.shape,
4047
+ annotations: {
4048
+ readOnlyHint: true,
4049
+ openWorldHint: false
4050
+ },
4051
+ tool: getConceptSchemeTool
4052
+ },
4053
+ listConceptSchemes: {
4054
+ title: "list_concept_schemes",
4055
+ description: "List taxonomy concept schemes in a Contentful organization. Supports pagination and filtering options. Returns a summarized view of concept schemes with essential information.",
4056
+ inputParams: ListConceptSchemesToolParams.shape,
4057
+ annotations: {
4058
+ readOnlyHint: true,
4059
+ openWorldHint: false
4060
+ },
4061
+ tool: listConceptSchemesTool
4062
+ },
4063
+ updateConceptScheme: {
4064
+ title: "update_concept_scheme",
4065
+ description: "Update a taxonomy concept scheme in Contentful. Requires the concept scheme ID and version number for optimistic concurrency control. You can update any combination of fields - only the fields you provide will be changed, while others remain unchanged. Use this to modify labels, definitions, relationships, and other concept scheme properties.",
4066
+ inputParams: UpdateConceptSchemeToolParams.shape,
4067
+ annotations: {
4068
+ readOnlyHint: false,
4069
+ destructiveHint: false,
4070
+ idempotentHint: false,
4071
+ openWorldHint: false
4072
+ },
4073
+ tool: updateConceptSchemeTool
4074
+ },
4075
+ deleteConceptScheme: {
4076
+ title: "delete_concept_scheme",
4077
+ description: "Delete a taxonomy concept scheme from Contentful. Requires the concept scheme ID and version number for optimistic concurrency control. This operation permanently removes the concept scheme and cannot be undone.",
4078
+ inputParams: DeleteConceptSchemeToolParams.shape,
4079
+ annotations: {
4080
+ readOnlyHint: false,
4081
+ destructiveHint: true,
4082
+ idempotentHint: true,
4083
+ openWorldHint: false
4084
+ },
4085
+ tool: deleteConceptSchemeTool
4086
+ }
4087
+ };
4088
+
4089
+ // src/tools/taxonomies/concepts/createConcept.ts
4090
+ import { z as z70 } from "zod";
4091
+ import ctfl11 from "contentful-management";
4092
+ var CreateConceptToolParams = z70.object({
4093
+ organizationId: z70.string().describe("The ID of the Contentful organization"),
4094
+ conceptId: z70.string().optional().describe(
4095
+ "Optional user-defined ID for the concept. If not provided, Contentful will generate one automatically."
4096
+ ),
4097
+ prefLabel: z70.record(z70.string()).describe("The preferred label for the concept (localized)"),
4098
+ uri: z70.string().nullable().optional().describe("The URI for the concept"),
4099
+ altLabels: z70.record(z70.array(z70.string())).optional().describe("Alternative labels for the concept (localized)"),
4100
+ hiddenLabels: z70.record(z70.array(z70.string())).optional().describe("Hidden labels for the concept (localized)"),
4101
+ definition: z70.record(z70.string().nullable()).optional().describe("Definition of the concept (localized)"),
4102
+ editorialNote: z70.record(z70.string().nullable()).optional().describe("Editorial note for the concept (localized)"),
4103
+ historyNote: z70.record(z70.string().nullable()).optional().describe("History note for the concept (localized)"),
4104
+ example: z70.record(z70.string().nullable()).optional().describe("Example for the concept (localized)"),
4105
+ note: z70.record(z70.string().nullable()).optional().describe("General note for the concept (localized)"),
4106
+ scopeNote: z70.record(z70.string().nullable()).optional().describe("Scope note for the concept (localized)"),
4107
+ notations: z70.array(z70.string()).optional().describe("Notations for the concept"),
4108
+ broader: z70.array(TaxonomyConceptLinkSchema).optional().describe("Links to broader concepts"),
4109
+ related: z70.array(TaxonomyConceptLinkSchema).optional().describe("Links to related concepts")
4110
+ });
4111
+ async function tool61(args) {
4112
+ const clientConfig = getDefaultClientConfig();
4113
+ delete clientConfig.space;
4114
+ const contentfulClient = ctfl11.createClient(clientConfig, { type: "plain" });
4115
+ const conceptPayload = {
4116
+ prefLabel: args.prefLabel,
4117
+ ...args.uri !== void 0 && { uri: args.uri },
4118
+ ...args.altLabels && { altLabels: args.altLabels },
4119
+ ...args.hiddenLabels && { hiddenLabels: args.hiddenLabels },
4120
+ ...args.definition && { definition: args.definition },
4121
+ ...args.editorialNote && { editorialNote: args.editorialNote },
4122
+ ...args.historyNote && { historyNote: args.historyNote },
4123
+ ...args.example && { example: args.example },
4124
+ ...args.note && { note: args.note },
4125
+ ...args.scopeNote && { scopeNote: args.scopeNote },
4126
+ ...args.notations && { notations: args.notations },
4127
+ ...args.broader && { broader: args.broader },
4128
+ ...args.related && { related: args.related }
4129
+ };
4130
+ const newConcept = args.conceptId ? await contentfulClient.concept.createWithId(
4131
+ { organizationId: args.organizationId, conceptId: args.conceptId },
4132
+ conceptPayload
4133
+ ) : await contentfulClient.concept.create(
4134
+ { organizationId: args.organizationId },
4135
+ conceptPayload
4136
+ );
4137
+ return createSuccessResponse("Concept created successfully", { newConcept });
4138
+ }
4139
+ var createConceptTool = withErrorHandling(
4140
+ tool61,
4141
+ "Error creating concept"
4142
+ );
4143
+
4144
+ // src/tools/taxonomies/concepts/deleteConcept.ts
4145
+ import { z as z71 } from "zod";
4146
+ import ctfl12 from "contentful-management";
4147
+ var DeleteConceptToolParams = z71.object({
4148
+ organizationId: z71.string().describe("The ID of the Contentful organization"),
4149
+ conceptId: z71.string().describe("The ID of the concept to delete"),
4150
+ version: z71.number().describe("The version of the concept to delete")
4151
+ });
4152
+ async function tool62(args) {
4153
+ const clientConfig = getDefaultClientConfig();
4154
+ delete clientConfig.space;
4155
+ const contentfulClient = ctfl12.createClient(clientConfig, { type: "plain" });
4156
+ await contentfulClient.concept.delete({
4157
+ organizationId: args.organizationId,
4158
+ conceptId: args.conceptId,
4159
+ version: args.version
4160
+ });
4161
+ return createSuccessResponse("Concept deleted successfully", {
4162
+ conceptId: args.conceptId
4163
+ });
4164
+ }
4165
+ var deleteConceptTool = withErrorHandling(
4166
+ tool62,
4167
+ "Error deleting concept"
4168
+ );
4169
+
4170
+ // src/tools/taxonomies/concepts/updateConcept.ts
4171
+ import { z as z72 } from "zod";
4172
+ import ctfl13 from "contentful-management";
4173
+ var UpdateConceptToolParams = z72.object({
4174
+ organizationId: z72.string().describe("The ID of the Contentful organization"),
4175
+ conceptId: z72.string().describe("The ID of the concept to update"),
4176
+ version: z72.number().describe("The current version of the concept"),
4177
+ prefLabel: z72.record(z72.string()).optional().describe("The preferred label for the concept (localized)"),
4178
+ uri: z72.string().nullable().optional().describe("The URI for the concept"),
4179
+ altLabels: z72.record(z72.array(z72.string())).optional().describe("Alternative labels for the concept (localized)"),
4180
+ hiddenLabels: z72.record(z72.array(z72.string())).optional().describe("Hidden labels for the concept (localized)"),
4181
+ definition: z72.record(z72.string().nullable()).optional().describe("Definition of the concept (localized)"),
4182
+ editorialNote: z72.record(z72.string().nullable()).optional().describe("Editorial note for the concept (localized)"),
4183
+ historyNote: z72.record(z72.string().nullable()).optional().describe("History note for the concept (localized)"),
4184
+ example: z72.record(z72.string().nullable()).optional().describe("Example for the concept (localized)"),
4185
+ note: z72.record(z72.string().nullable()).optional().describe("General note for the concept (localized)"),
4186
+ scopeNote: z72.record(z72.string().nullable()).optional().describe("Scope note for the concept (localized)"),
4187
+ notations: z72.array(z72.string()).optional().describe("Notations for the concept"),
4188
+ broader: z72.array(TaxonomyConceptLinkSchema).optional().describe("Links to broader concepts"),
4189
+ related: z72.array(TaxonomyConceptLinkSchema).optional().describe("Links to related concepts")
4190
+ });
4191
+ async function tool63(args) {
4192
+ const clientConfig = getDefaultClientConfig();
4193
+ delete clientConfig.space;
4194
+ const contentfulClient = ctfl13.createClient(clientConfig, { type: "plain" });
4195
+ const existingConcept = await contentfulClient.concept.get({
4196
+ organizationId: args.organizationId,
4197
+ conceptId: args.conceptId
4198
+ });
4199
+ const updatedPayload = {
4200
+ prefLabel: args.prefLabel ?? existingConcept.prefLabel,
4201
+ uri: args.uri !== void 0 ? args.uri : existingConcept.uri,
4202
+ altLabels: args.altLabels ?? existingConcept.altLabels,
4203
+ hiddenLabels: args.hiddenLabels ?? existingConcept.hiddenLabels,
4204
+ definition: args.definition ?? existingConcept.definition,
4205
+ editorialNote: args.editorialNote ?? existingConcept.editorialNote,
4206
+ historyNote: args.historyNote ?? existingConcept.historyNote,
4207
+ example: args.example ?? existingConcept.example,
4208
+ note: args.note ?? existingConcept.note,
4209
+ scopeNote: args.scopeNote ?? existingConcept.scopeNote,
4210
+ notations: args.notations ?? existingConcept.notations,
4211
+ broader: args.broader ?? existingConcept.broader,
4212
+ related: args.related ?? existingConcept.related
4213
+ };
4214
+ const updatedConcept = await contentfulClient.concept.updatePut(
4215
+ {
4216
+ organizationId: args.organizationId,
4217
+ conceptId: args.conceptId,
4218
+ version: args.version
4219
+ },
4220
+ updatedPayload
4221
+ );
4222
+ return createSuccessResponse("Concept updated successfully", {
4223
+ updatedConcept
4224
+ });
4225
+ }
4226
+ var updateConceptTool = withErrorHandling(
4227
+ tool63,
4228
+ "Error updating concept"
4229
+ );
4230
+
4231
+ // src/tools/taxonomies/concepts/getConcept.ts
4232
+ import { z as z73 } from "zod";
4233
+ import ctfl14 from "contentful-management";
4234
+ var GetConceptToolParams = z73.object({
4235
+ organizationId: z73.string().describe("The ID of the Contentful organization"),
4236
+ conceptId: z73.string().describe("The ID of the concept to retrieve")
4237
+ });
4238
+ async function tool64(args) {
4239
+ const clientConfig = getDefaultClientConfig();
4240
+ delete clientConfig.space;
4241
+ const contentfulClient = ctfl14.createClient(clientConfig, { type: "plain" });
4242
+ const concept = await contentfulClient.concept.get({
4243
+ organizationId: args.organizationId,
4244
+ conceptId: args.conceptId
4245
+ });
4246
+ return createSuccessResponse("Concept retrieved successfully", { concept });
4247
+ }
4248
+ var getConceptTool = withErrorHandling(
4249
+ tool64,
4250
+ "Error retrieving concept"
4251
+ );
4252
+
4253
+ // src/tools/taxonomies/concepts/listConcepts.ts
4254
+ import { z as z74 } from "zod";
4255
+ import ctfl15 from "contentful-management";
4256
+ var ListConceptsToolParams = z74.object({
4257
+ organizationId: z74.string().describe("The ID of the Contentful organization"),
4258
+ conceptId: z74.string().optional().describe("The ID of the concept (required for descendants/ancestors)"),
4259
+ limit: z74.number().optional().describe("Maximum number of concepts to return"),
4260
+ skip: z74.number().optional().describe("Skip this many concepts for pagination"),
4261
+ select: z74.string().optional().describe("Comma-separated list of fields to return"),
4262
+ include: z74.number().optional().describe("Include this many levels of linked entries"),
4263
+ order: z74.string().optional().describe("Order concepts by this field"),
4264
+ getDescendants: z74.boolean().optional().describe("Get descendants of the specified concept (requires conceptId)"),
4265
+ getAncestors: z74.boolean().optional().describe("Get ancestors of the specified concept (requires conceptId)"),
4266
+ getTotalOnly: z74.boolean().optional().describe("Get only the total number of concepts without full data")
4267
+ });
4268
+ async function tool65(args) {
4269
+ const clientConfig = getDefaultClientConfig();
4270
+ delete clientConfig.space;
4271
+ const contentfulClient = ctfl15.createClient(clientConfig, { type: "plain" });
4272
+ if ((args.getDescendants || args.getAncestors) && !args.conceptId) {
4273
+ throw new Error(
4274
+ "conceptId is required when getting descendants or ancestors"
4275
+ );
4276
+ }
4277
+ if (args.getTotalOnly) {
4278
+ const total = await contentfulClient.concept.getTotal({
4279
+ organizationId: args.organizationId
4280
+ });
4281
+ return createSuccessResponse("Total concepts retrieved successfully", {
4282
+ total
4283
+ });
4284
+ }
4285
+ if (args.getDescendants) {
4286
+ const descendants = await contentfulClient.concept.getDescendants({
4287
+ organizationId: args.organizationId,
4288
+ conceptId: args.conceptId,
4289
+ ...args.limit && { limit: args.limit },
4290
+ ...args.skip && { skip: args.skip },
4291
+ ...args.select && { select: args.select },
4292
+ ...args.include && { include: args.include },
4293
+ ...args.order && { order: args.order }
4294
+ });
4295
+ const summarizedDescendants = descendants.items.map((concept) => ({
4296
+ sys: concept.sys,
4297
+ prefLabel: concept.prefLabel,
4298
+ uri: concept.uri,
4299
+ broader: concept.broader,
4300
+ related: concept.related
4301
+ }));
4302
+ const responseData2 = summarizeData({
4303
+ ...descendants,
4304
+ items: summarizedDescendants
4305
+ });
4306
+ return createSuccessResponse(
4307
+ "Concept descendants retrieved successfully",
4308
+ responseData2
4309
+ );
4310
+ }
4311
+ if (args.getAncestors) {
4312
+ const ancestors = await contentfulClient.concept.getAncestors({
4313
+ organizationId: args.organizationId,
4314
+ conceptId: args.conceptId,
4315
+ ...args.limit && { limit: args.limit },
4316
+ ...args.skip && { skip: args.skip },
4317
+ ...args.select && { select: args.select },
4318
+ ...args.include && { include: args.include },
4319
+ ...args.order && { order: args.order }
4320
+ });
4321
+ const summarizedAncestors = ancestors.items.map((concept) => ({
4322
+ sys: concept.sys,
4323
+ prefLabel: concept.prefLabel,
4324
+ uri: concept.uri,
4325
+ broader: concept.broader,
4326
+ related: concept.related
4327
+ }));
4328
+ const responseData2 = summarizeData({
4329
+ ...ancestors,
4330
+ items: summarizedAncestors
4331
+ });
4332
+ return createSuccessResponse(
4333
+ "Concept ancestors retrieved successfully",
4334
+ responseData2
4335
+ );
4336
+ }
4337
+ const concepts = await contentfulClient.concept.getMany({
4338
+ organizationId: args.organizationId,
4339
+ query: {
4340
+ limit: args.limit || 10,
4341
+ skip: args.skip || 0,
4342
+ ...args.select && { select: args.select },
4343
+ ...args.include && { include: args.include },
4344
+ ...args.order && { order: args.order }
4345
+ }
4346
+ });
4347
+ const summarizedConcepts = concepts.items.map((concept) => ({
4348
+ sys: concept.sys,
4349
+ prefLabel: concept.prefLabel,
4350
+ uri: concept.uri,
4351
+ broader: concept.broader,
4352
+ related: concept.related
4353
+ }));
4354
+ const responseData = summarizeData({
4355
+ ...concepts,
4356
+ items: summarizedConcepts
4357
+ });
4358
+ return createSuccessResponse(
4359
+ "Concepts retrieved successfully",
4360
+ responseData
4361
+ );
4362
+ }
4363
+ var listConceptsTool = withErrorHandling(
4364
+ tool65,
4365
+ "Error retrieving concepts"
4366
+ );
4367
+
4368
+ // src/tools/taxonomies/concepts/register.ts
4369
+ var conceptTools = {
4370
+ createConcept: {
4371
+ title: "create_concept",
4372
+ description: "Create a new taxonomy concept in Contentful. Concepts are used to organize and categorize content within taxonomies. The prefLabel is required and should be localized. You can optionally provide a conceptId for a user-defined ID, or let Contentful generate one automatically. You can also include definitions, notes, relationships to other concepts, and various metadata fields.",
4373
+ inputParams: CreateConceptToolParams.shape,
4374
+ annotations: {
4375
+ readOnlyHint: false,
4376
+ destructiveHint: false,
4377
+ idempotentHint: false,
4378
+ openWorldHint: false
4379
+ },
4380
+ tool: createConceptTool
4381
+ },
4382
+ getConcept: {
4383
+ title: "get_concept",
4384
+ description: "Retrieve a specific taxonomy concept from Contentful. Returns the complete concept with all its properties including prefLabel, definition, relationships, and other metadata.",
4385
+ inputParams: GetConceptToolParams.shape,
4386
+ annotations: {
4387
+ readOnlyHint: true,
4388
+ openWorldHint: false
4389
+ },
4390
+ tool: getConceptTool
4391
+ },
4392
+ listConcepts: {
4393
+ title: "list_concepts",
4394
+ description: "List taxonomy concepts in a Contentful organization. Supports multiple modes: (1) Default - list all concepts with pagination and filtering, (2) getTotalOnly - return only the total count of concepts, (3) getDescendants - get descendants of a specific concept (requires conceptId), (4) getAncestors - get ancestors of a specific concept (requires conceptId). Returns summarized view of concepts with essential information.",
4395
+ inputParams: ListConceptsToolParams.shape,
4396
+ annotations: {
4397
+ readOnlyHint: true,
4398
+ openWorldHint: false
4399
+ },
4400
+ tool: listConceptsTool
4401
+ },
4402
+ updateConcept: {
4403
+ title: "update_concept",
4404
+ description: "Update a taxonomy concept in Contentful. Requires the concept ID and version number for optimistic concurrency control. You can update any combination of fields - only the fields you provide will be changed, while others remain unchanged. Use this to modify labels, definitions, relationships, and other concept properties.",
4405
+ inputParams: UpdateConceptToolParams.shape,
4406
+ annotations: {
4407
+ readOnlyHint: false,
4408
+ destructiveHint: false,
4409
+ idempotentHint: false,
4410
+ openWorldHint: false
4411
+ },
4412
+ tool: updateConceptTool
4413
+ },
4414
+ deleteConcept: {
4415
+ title: "delete_concept",
4416
+ description: "Delete a taxonomy concept from Contentful. Requires the concept ID and version number for optimistic concurrency control. This operation permanently removes the concept and cannot be undone.",
4417
+ inputParams: DeleteConceptToolParams.shape,
4418
+ annotations: {
4419
+ readOnlyHint: false,
4420
+ destructiveHint: true,
4421
+ idempotentHint: true,
4422
+ openWorldHint: false
4423
+ },
4424
+ tool: deleteConceptTool
4425
+ }
4426
+ };
4427
+
4428
+ // src/tools/taxonomies/register.ts
4429
+ var taxonomyTools = {
4430
+ ...conceptSchemeTools,
4431
+ ...conceptTools
4432
+ };
4433
+ export {
4434
+ aiActionTools,
4435
+ assetTools,
4436
+ contentTypeTools,
4437
+ contextTools,
4438
+ editorInterfaceTools,
4439
+ entryTools,
4440
+ environmentTools,
4441
+ jobTools,
4442
+ localeTools,
4443
+ orgTools,
4444
+ spaceTools,
4445
+ tagTools,
4446
+ taxonomyTools
4447
+ };
4448
+ //# sourceMappingURL=index.js.map