@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 +4448 -0
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
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
|