@contentful/mcp-tools 0.12.2 → 0.12.3-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5248 -1134
- package/dist/index.js +2513 -202
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -335,7 +335,12 @@ var RESOURCE_DISPLAY_NAME = {
|
|
|
335
335
|
aiAction: "AI action",
|
|
336
336
|
locale: "locale",
|
|
337
337
|
concept: "concept",
|
|
338
|
-
conceptScheme: "concept scheme"
|
|
338
|
+
conceptScheme: "concept scheme",
|
|
339
|
+
componentType: "component type",
|
|
340
|
+
experience: "experience",
|
|
341
|
+
fragment: "fragment",
|
|
342
|
+
template: "template",
|
|
343
|
+
dataAssembly: "data assembly"
|
|
339
344
|
};
|
|
340
345
|
function buildConfirmationPreview(resource, id, details, confirmToken) {
|
|
341
346
|
const displayName = RESOURCE_DISPLAY_NAME[resource];
|
|
@@ -2303,141 +2308,59 @@ var ContextStore = class {
|
|
|
2303
2308
|
var contextStore = new ContextStore();
|
|
2304
2309
|
|
|
2305
2310
|
// src/tools/context/instructions.ts
|
|
2306
|
-
var
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
- **
|
|
2316
|
-
- **
|
|
2317
|
-
- **
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
- **
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
- 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
|
|
2329
|
-
|
|
2330
|
-
## entry Creation Limits:
|
|
2331
|
-
- A user is only allowed to create/edit/mutate a maximum of 5 (five) entries at a time
|
|
2332
|
-
- For multiple entry creation, use the 'async' parameter (set to true) for better performance
|
|
2333
|
-
- Only use async=true when creating more than one entry in a single conversation
|
|
2334
|
-
|
|
2335
|
-
# Searching for Content
|
|
2336
|
-
|
|
2337
|
-
## Content-Type-First Search Strategy:
|
|
2338
|
-
- **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
|
|
2339
|
-
- This immediately reveals the correct content types and prevents wasted time on failed queries
|
|
2340
|
-
- After understanding the content type, use search_entries to search for content based on the correct content types and field names
|
|
2341
|
-
- If a query returns no results, retry 2-3 times with modified queries by adjusting filters, relaxing constraints, or trying alternative field names
|
|
2342
|
-
- When retrying queries, consider using more general terms, removing specific filters, or checking for typos in field names
|
|
2343
|
-
|
|
2344
|
-
## Handling Multi-Step Queries:
|
|
2345
|
-
- For requests involving related entities (e.g., "Find blog posts by Magnus"), use a multi-step approach
|
|
2346
|
-
- ALWAYS check the content type structure first to understand fields and references
|
|
2347
|
-
- First, query for the referenced entity (e.g., author) to find its ID or confirm its existence
|
|
2348
|
-
- If multiple entities match (e.g., several authors named "Magnus"), query them all and display them to the user
|
|
2349
|
-
- Then use the found ID(s) to query for the primary content (e.g., blog posts referencing that author)
|
|
2350
|
-
- For references in Contentful, remember to use the proper reference format
|
|
2351
|
-
- Verify fields in the content type before constructing queries (single reference vs. array of references)
|
|
2352
|
-
|
|
2353
|
-
## Entry Management:
|
|
2354
|
-
- For entry creation, use create_entry with clear instructions
|
|
2355
|
-
- Use entry_action for operations like publishing, unpublishing, deleting, or discarding entries
|
|
2356
|
-
- Use update_entry for content modifications with AI assistance. Always call get_entry first and pass the returned sys.version to update_entry; this is required and prevents overwriting concurrent changes.
|
|
2357
|
-
- Use patch_entry for precise, direct modifications without AI generation (one operation at a time)
|
|
2358
|
-
- Use transform_entry when preserving rich text formatting is crucial
|
|
2359
|
-
- Use translate_entry specifically for language translation tasks
|
|
2360
|
-
- Use transform_image for AI-powered image operations
|
|
2361
|
-
- Always verify entry existence before attempting to modify it
|
|
2362
|
-
|
|
2363
|
-
# Migration Strategies
|
|
2364
|
-
- 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.
|
|
2365
|
-
- 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.
|
|
2366
|
-
|
|
2367
|
-
# Error Handling and Debugging
|
|
2368
|
-
|
|
2369
|
-
## Error Response Strategy:
|
|
2370
|
-
- If you encounter an error, explain what went wrong clearly
|
|
2371
|
-
- Suggest potential solutions or alternatives
|
|
2372
|
-
- Make sure to check entry existence, field requirements, and permission issues
|
|
2373
|
-
- Try different approaches immediately rather than stopping at the first error
|
|
2374
|
-
|
|
2375
|
-
## Common Issues to Check:
|
|
2376
|
-
- entry existence and permissions
|
|
2377
|
-
- Required field validation
|
|
2378
|
-
- Correct field types (array vs single reference)
|
|
2379
|
-
|
|
2380
|
-
# Response Format and Communication
|
|
2381
|
-
|
|
2382
|
-
## General Guidelines:
|
|
2383
|
-
- Keep your responses concise but thorough
|
|
2384
|
-
- Format complex data for readability using markdown
|
|
2385
|
-
- Focus on completing the requested tasks efficiently
|
|
2386
|
-
- Provide context from entries when relevant
|
|
2387
|
-
- When displaying entries, show the most important fields first
|
|
2388
|
-
|
|
2389
|
-
## Before Using Tools:
|
|
2390
|
-
Before running a tool:
|
|
2391
|
-
1. Think about what information you need to gather
|
|
2392
|
-
2. Determine the right tool and parameters to use
|
|
2393
|
-
3. Briefly communicate to the user what you're about to do in a conversational tone
|
|
2394
|
-
|
|
2395
|
-
## Problem-Solving Strategy:
|
|
2396
|
-
1. **Understand the request**: Analyze what the user is asking for and identify necessary entry types and fields
|
|
2397
|
-
2. **Resource identification**: If multiple resources are available, ALWAYS ask which resource to work with
|
|
2398
|
-
3. **Plan your approach**: Determine which tools you'll need and in which order
|
|
2399
|
-
4. **Execute with tools**: Use appropriate tools to query, create, or update entries
|
|
2400
|
-
5. **Verify results**: Check if results match what the user requested and make adjustments if needed
|
|
2401
|
-
6. **Respond clearly**: Present results in a clear, concise format
|
|
2402
|
-
|
|
2403
|
-
# Best Practices
|
|
2404
|
-
|
|
2405
|
-
## Content Management:
|
|
2406
|
-
- When creating content, follow the content type structure exactly
|
|
2407
|
-
- Always verify entry existence before attempting to modify it
|
|
2408
|
-
- Remind users that entry operations can affect live content
|
|
2409
|
-
|
|
2410
|
-
## Efficiency Tips:
|
|
2411
|
-
- Suggest appropriate entry types based on user needs
|
|
2412
|
-
- Recommend efficient ways to structure content
|
|
2413
|
-
- Explain how Contentful features like content types, entries, and references work
|
|
2414
|
-
- Help users understand the relationship between spaces, environments, and content types
|
|
2415
|
-
|
|
2416
|
-
## Bulk Actions:
|
|
2417
|
-
- 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.
|
|
2418
|
-
|
|
2419
|
-
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.`;
|
|
2311
|
+
var CORE_INVARIANTS = `# Core operating rules
|
|
2312
|
+
|
|
2313
|
+
- **Content-type first.** Before finding or editing content, call \`list_content_types\` to see what content types exist, and \`get_content_type\` to inspect a type's fields. This prevents failed queries and reveals the right type (e.g. a \`pricingPage\` type when asked about pricing).
|
|
2314
|
+
- **Edit safely.** To modify an entry, call \`get_entry\` first, then pass the returned \`sys.version\` to \`update_entry\`. The version is required and prevents overwriting concurrent changes.
|
|
2315
|
+
- **Bulk cap.** The bulk operations \`publish_entry\`, \`unpublish_entry\`, \`archive_entry\`, and \`unarchive_entry\` accept at most 10 IDs per call by default. This cap does not apply to creating or updating entries.
|
|
2316
|
+
- **Ask when ambiguous.** If multiple spaces or environments are available, ask the user which to use. Do not guess.`;
|
|
2317
|
+
var SEARCHING_GUIDANCE = `# Searching for content
|
|
2318
|
+
|
|
2319
|
+
- **Content-type first.** When users ask about specific content ("pricing page", "blog posts"), call \`list_content_types\` / \`get_content_type\` to discover the correct type before searching. This prevents wasted queries on wrong field names.
|
|
2320
|
+
- **Then search.** Use \`search_entries\` with the correct content type and field names. Use \`semantic_search\` when the user's request is conceptual rather than an exact field match.
|
|
2321
|
+
- **Retry thoughtfully.** If a query returns no results, retry 2-3 times: relax filters, use more general terms, or check for typos in field names.
|
|
2322
|
+
- **Multi-step reference queries.** For requests like "blog posts by Magnus", first inspect the content type to confirm the reference field, then query for the referenced entry (the author) to get its ID, then query the primary content filtering on that ID. If several entities match, show them all and ask.`;
|
|
2323
|
+
var CONVENTIONS_GUIDANCE = `# Response and workflow conventions
|
|
2324
|
+
|
|
2325
|
+
- **Plan, then act.** Before a tool call, think about what you need, pick the right tool, and briefly tell the user what you are about to do.
|
|
2326
|
+
- **Persist.** Keep going until the request is fully resolved; do not stop at the first error. On failure, explain what went wrong and immediately try a different approach \u2014 never apologize for tool errors.
|
|
2327
|
+
- **Clarify resources.** If multiple spaces or environments exist, always ask which to use before acting.
|
|
2328
|
+
- **Format for readability.** Use markdown for complex data; show the most important fields of an entry first; keep responses concise but complete.
|
|
2329
|
+
- **Prefer bulk.** If you would call the same tool many times, check whether it supports multiple IDs and condense into one call (respecting the 10-ID cap on publish-family operations).`;
|
|
2330
|
+
var EXO_DISPOSITION = `# Tool disposition: prefer Experience Orchestration
|
|
2331
|
+
|
|
2332
|
+
Experience Orchestration (ExO) tools are enabled. Prefer ExO primitives \u2014 Component Types, Experiences, Templates \u2014 over classic content types and entries, unless the user explicitly asks for classic content types or entries instead.`;
|
|
2420
2333
|
|
|
2421
2334
|
// src/tools/context/getInitialContextTool.ts
|
|
2422
2335
|
var GetInitialContextToolParams = z35.object({});
|
|
2423
2336
|
function getInitialContextTool(config) {
|
|
2424
2337
|
async function tool2(_params) {
|
|
2425
|
-
const
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2338
|
+
const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
|
|
2339
|
+
weekday: "long",
|
|
2340
|
+
year: "numeric",
|
|
2341
|
+
month: "long",
|
|
2342
|
+
day: "numeric"
|
|
2343
|
+
});
|
|
2344
|
+
const sessionFacts = outdent`
|
|
2345
|
+
Current Contentful session:
|
|
2346
|
+
- Today's date: ${today}
|
|
2347
|
+
- Space ID: ${config.spaceId || "Not set"}
|
|
2348
|
+
- Environment ID: ${config.environmentId || "master"}
|
|
2349
|
+
- Organization ID: ${config.organizationId || "Not set"}`;
|
|
2350
|
+
const exoBlock = config.exoToolsRegistered ? `
|
|
2351
|
+
|
|
2352
|
+
${EXO_DISPOSITION}` : "";
|
|
2430
2353
|
const message = outdent`
|
|
2431
|
-
|
|
2354
|
+
You are an assistant integrated with Contentful through the Model Context Protocol (MCP). Always call this tool first.
|
|
2355
|
+
|
|
2356
|
+
${sessionFacts}
|
|
2432
2357
|
|
|
2433
|
-
|
|
2358
|
+
${CORE_INVARIANTS}
|
|
2434
2359
|
|
|
2435
|
-
|
|
2436
|
-
${configInfo}
|
|
2437
|
-
</content>
|
|
2360
|
+
${SEARCHING_GUIDANCE}
|
|
2438
2361
|
|
|
2439
|
-
|
|
2440
|
-
|
|
2362
|
+
${CONVENTIONS_GUIDANCE}
|
|
2363
|
+
` + exoBlock;
|
|
2441
2364
|
contextStore.setInitialContextLoaded();
|
|
2442
2365
|
return {
|
|
2443
2366
|
content: [
|
|
@@ -5679,88 +5602,2464 @@ function createJobTools(config) {
|
|
|
5679
5602
|
};
|
|
5680
5603
|
}
|
|
5681
5604
|
|
|
5682
|
-
// src/
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
this.config = { ...this.config, ...updates };
|
|
5699
|
-
}
|
|
5700
|
-
/**
|
|
5701
|
-
* Get AI action tools
|
|
5702
|
-
*/
|
|
5703
|
-
getAiActionTools() {
|
|
5704
|
-
return createAiActionTools(this.config);
|
|
5705
|
-
}
|
|
5706
|
-
/**
|
|
5707
|
-
* Get asset tools
|
|
5708
|
-
*/
|
|
5709
|
-
getAssetTools() {
|
|
5710
|
-
return createAssetTools(this.config);
|
|
5711
|
-
}
|
|
5712
|
-
/**
|
|
5713
|
-
* Get content type tools
|
|
5714
|
-
*/
|
|
5715
|
-
getContentTypeTools() {
|
|
5716
|
-
return createContentTypeTools(this.config);
|
|
5717
|
-
}
|
|
5718
|
-
/**
|
|
5719
|
-
* Get context tools
|
|
5720
|
-
*/
|
|
5721
|
-
getContextTools() {
|
|
5722
|
-
return createContextTools(this.config);
|
|
5605
|
+
// src/tools/exo/component-types/getComponentType.ts
|
|
5606
|
+
import { z as z82 } from "zod";
|
|
5607
|
+
var GetComponentTypeToolParams = BaseToolSchema.extend({
|
|
5608
|
+
componentTypeId: z82.string().describe("The ID of the component type to retrieve details for")
|
|
5609
|
+
});
|
|
5610
|
+
function getComponentTypeTool(config) {
|
|
5611
|
+
async function tool2(args) {
|
|
5612
|
+
const contentfulClient = createToolClient(config, args);
|
|
5613
|
+
const componentType = await contentfulClient.componentType.get({
|
|
5614
|
+
spaceId: args.spaceId,
|
|
5615
|
+
environmentId: args.environmentId,
|
|
5616
|
+
componentTypeId: args.componentTypeId
|
|
5617
|
+
});
|
|
5618
|
+
return createSuccessResponse("Component type retrieved successfully", {
|
|
5619
|
+
componentType
|
|
5620
|
+
});
|
|
5723
5621
|
}
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5622
|
+
return withErrorHandling(tool2, "Error retrieving component type");
|
|
5623
|
+
}
|
|
5624
|
+
|
|
5625
|
+
// src/tools/exo/component-types/listComponentTypes.ts
|
|
5626
|
+
import { z as z83 } from "zod";
|
|
5627
|
+
var ListComponentTypesToolParams = BaseToolSchema.extend({
|
|
5628
|
+
limit: z83.number().optional().describe("Maximum number of component types to return (max 10)"),
|
|
5629
|
+
pageNext: z83.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
5630
|
+
pagePrev: z83.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
5631
|
+
order: z83.string().optional().describe("Order component types by this field (e.g. sys.createdAt)")
|
|
5632
|
+
});
|
|
5633
|
+
function listComponentTypesTool(config) {
|
|
5634
|
+
async function tool2(args) {
|
|
5635
|
+
const contentfulClient = createToolClient(config, args);
|
|
5636
|
+
const componentTypes = await contentfulClient.componentType.getMany({
|
|
5637
|
+
spaceId: args.spaceId,
|
|
5638
|
+
environmentId: args.environmentId,
|
|
5639
|
+
query: {
|
|
5640
|
+
limit: Math.min(args.limit || 10, 10),
|
|
5641
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
5642
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
5643
|
+
...args.order && { order: args.order }
|
|
5644
|
+
}
|
|
5645
|
+
});
|
|
5646
|
+
const summarized = summarizeData(componentTypes, {
|
|
5647
|
+
maxItems: 10,
|
|
5648
|
+
remainingMessage: "To see more component types, ask me to retrieve the next page using the pageNext cursor."
|
|
5649
|
+
});
|
|
5650
|
+
return createSuccessResponse("Component types retrieved successfully", {
|
|
5651
|
+
componentTypes: summarized,
|
|
5652
|
+
total: componentTypes.total,
|
|
5653
|
+
limit: componentTypes.limit,
|
|
5654
|
+
pages: componentTypes.pages
|
|
5655
|
+
});
|
|
5729
5656
|
}
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5657
|
+
return withErrorHandling(tool2, "Error listing component types");
|
|
5658
|
+
}
|
|
5659
|
+
|
|
5660
|
+
// src/tools/exo/component-types/createComponentType.ts
|
|
5661
|
+
import { z as z85 } from "zod";
|
|
5662
|
+
|
|
5663
|
+
// src/types/componentTypeSchemas.ts
|
|
5664
|
+
import { z as z84 } from "zod";
|
|
5665
|
+
var URN_EXAMPLES = {
|
|
5666
|
+
"Contentful:ComponentType": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/componentTypes/{id}",
|
|
5667
|
+
"Contentful:Fragment": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/fragments/{id}",
|
|
5668
|
+
"Contentful:Template": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/templates/{id}",
|
|
5669
|
+
"Contentful:DataAssembly": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/dataAssemblies/{id}"
|
|
5670
|
+
};
|
|
5671
|
+
var resourceLinkSchema2 = (linkType) => {
|
|
5672
|
+
const example = URN_EXAMPLES[linkType];
|
|
5673
|
+
const urnDesc = example ? `URN of the linked resource (e.g. "${example}")` : "URN of the linked resource";
|
|
5674
|
+
return z84.object({
|
|
5675
|
+
sys: z84.object({
|
|
5676
|
+
type: z84.literal("ResourceLink"),
|
|
5677
|
+
linkType: z84.literal(linkType),
|
|
5678
|
+
urn: z84.string().describe(urnDesc)
|
|
5679
|
+
})
|
|
5680
|
+
});
|
|
5681
|
+
};
|
|
5682
|
+
var linkSchema2 = (linkType) => z84.object({
|
|
5683
|
+
sys: z84.object({
|
|
5684
|
+
type: z84.literal("Link"),
|
|
5685
|
+
linkType: z84.literal(linkType),
|
|
5686
|
+
id: z84.string()
|
|
5687
|
+
})
|
|
5688
|
+
});
|
|
5689
|
+
var ComponentTypeResourceLinkSchema = resourceLinkSchema2("Contentful:ComponentType");
|
|
5690
|
+
var FragmentResourceLinkSchema = resourceLinkSchema2("Contentful:Fragment");
|
|
5691
|
+
var ViewportSchema = z84.object({
|
|
5692
|
+
id: z84.string().describe("Viewport identifier"),
|
|
5693
|
+
query: z84.string().describe("CSS media query string"),
|
|
5694
|
+
displayName: z84.string().describe("Human-readable viewport name"),
|
|
5695
|
+
previewSize: z84.string().describe('Preview size (e.g. "1024px")')
|
|
5696
|
+
});
|
|
5697
|
+
var DataTypeDefinitionSchema = z84.lazy(
|
|
5698
|
+
() => z84.discriminatedUnion("type", [
|
|
5699
|
+
z84.object({
|
|
5700
|
+
type: z84.enum(["String", "Number", "Integer", "Boolean"]),
|
|
5701
|
+
name: z84.string().optional(),
|
|
5702
|
+
required: z84.boolean().optional()
|
|
5703
|
+
}),
|
|
5704
|
+
z84.object({
|
|
5705
|
+
type: z84.literal("RichText"),
|
|
5706
|
+
name: z84.string().optional(),
|
|
5707
|
+
required: z84.boolean().optional()
|
|
5708
|
+
}),
|
|
5709
|
+
z84.object({
|
|
5710
|
+
type: z84.literal("Array"),
|
|
5711
|
+
name: z84.string().optional(),
|
|
5712
|
+
required: z84.boolean().optional(),
|
|
5713
|
+
items: DataTypeDefinitionSchema
|
|
5714
|
+
}),
|
|
5715
|
+
z84.object({
|
|
5716
|
+
type: z84.literal("Record"),
|
|
5717
|
+
name: z84.string().optional(),
|
|
5718
|
+
required: z84.boolean().optional(),
|
|
5719
|
+
fields: z84.record(z84.string(), DataTypeDefinitionSchema)
|
|
5720
|
+
}),
|
|
5721
|
+
z84.object({
|
|
5722
|
+
type: z84.literal("TypeRef"),
|
|
5723
|
+
name: z84.string().optional(),
|
|
5724
|
+
required: z84.boolean().optional(),
|
|
5725
|
+
ref: z84.object({
|
|
5726
|
+
sys: z84.object({
|
|
5727
|
+
type: z84.literal("ResourceLink"),
|
|
5728
|
+
linkType: z84.string(),
|
|
5729
|
+
urn: z84.string()
|
|
5730
|
+
})
|
|
5731
|
+
})
|
|
5732
|
+
}),
|
|
5733
|
+
z84.object({
|
|
5734
|
+
type: z84.literal("Literal"),
|
|
5735
|
+
name: z84.string().optional(),
|
|
5736
|
+
required: z84.boolean().optional(),
|
|
5737
|
+
value: z84.custom().describe("JSON literal value"),
|
|
5738
|
+
valueType: DataTypeDefinitionSchema
|
|
5739
|
+
}),
|
|
5740
|
+
z84.object({
|
|
5741
|
+
type: z84.literal("DiscriminatedUnion"),
|
|
5742
|
+
name: z84.string().optional(),
|
|
5743
|
+
required: z84.boolean().optional(),
|
|
5744
|
+
discriminator: z84.string(),
|
|
5745
|
+
members: z84.array(DataTypeDefinitionSchema)
|
|
5746
|
+
})
|
|
5747
|
+
])
|
|
5748
|
+
);
|
|
5749
|
+
var ContentPropertySchema = z84.intersection(
|
|
5750
|
+
DataTypeDefinitionSchema,
|
|
5751
|
+
z84.object({
|
|
5752
|
+
id: z84.string().describe("Content property identifier"),
|
|
5753
|
+
name: z84.string().describe("Human-readable name"),
|
|
5754
|
+
required: z84.boolean().describe("Whether the property is required"),
|
|
5755
|
+
defaultValue: z84.unknown().optional().describe("Default value")
|
|
5756
|
+
})
|
|
5757
|
+
);
|
|
5758
|
+
var DTCG_DESIGN_PROPERTY_TYPES = [
|
|
5759
|
+
"DTCG.Color",
|
|
5760
|
+
"DTCG.Dimension",
|
|
5761
|
+
"DTCG.FontFamily",
|
|
5762
|
+
"DTCG.FontWeight",
|
|
5763
|
+
"DTCG.Duration",
|
|
5764
|
+
"DTCG.CubicBezier",
|
|
5765
|
+
"DTCG.Number",
|
|
5766
|
+
"DTCG.StrokeStyle",
|
|
5767
|
+
"DTCG.Border",
|
|
5768
|
+
"DTCG.Transition",
|
|
5769
|
+
"DTCG.Shadow",
|
|
5770
|
+
"DTCG.Gradient",
|
|
5771
|
+
"DTCG.Typography"
|
|
5772
|
+
];
|
|
5773
|
+
var DesignPropertyCommonFieldsSchema = z84.object({
|
|
5774
|
+
id: z84.string().describe("Design property identifier"),
|
|
5775
|
+
name: z84.string().describe("Human-readable name"),
|
|
5776
|
+
description: z84.string().optional().describe("Optional description")
|
|
5777
|
+
});
|
|
5778
|
+
var StringDesignPropertySchema = DesignPropertyCommonFieldsSchema.extend({
|
|
5779
|
+
type: z84.literal("String"),
|
|
5780
|
+
fallbackValue: z84.object({
|
|
5781
|
+
type: z84.literal("ManualDesignValue"),
|
|
5782
|
+
value: z84.string()
|
|
5783
|
+
}).optional().describe("Manual fallback value for this design property"),
|
|
5784
|
+
validations: z84.array(
|
|
5785
|
+
z84.object({
|
|
5786
|
+
regexp: z84.object({
|
|
5787
|
+
pattern: z84.string().describe("Regular expression pattern")
|
|
5788
|
+
})
|
|
5789
|
+
})
|
|
5790
|
+
).optional().describe("Regexp validations constraining allowed string values")
|
|
5791
|
+
});
|
|
5792
|
+
var BooleanDesignPropertySchema = DesignPropertyCommonFieldsSchema.extend({
|
|
5793
|
+
type: z84.literal("Boolean"),
|
|
5794
|
+
fallbackValue: z84.object({
|
|
5795
|
+
type: z84.literal("ManualDesignValue"),
|
|
5796
|
+
value: z84.boolean()
|
|
5797
|
+
}).optional().describe("Manual fallback value for this design property")
|
|
5798
|
+
});
|
|
5799
|
+
var DesignTokenValueSchema = z84.object({
|
|
5800
|
+
type: z84.literal("DesignToken"),
|
|
5801
|
+
value: z84.string().min(1).describe("Design token reference (non-empty)")
|
|
5802
|
+
});
|
|
5803
|
+
var TokenBackedDesignPropertySchema = DesignPropertyCommonFieldsSchema.extend({
|
|
5804
|
+
type: z84.enum(DTCG_DESIGN_PROPERTY_TYPES),
|
|
5805
|
+
fallbackValue: DesignTokenValueSchema.optional().describe(
|
|
5806
|
+
"Design-token-backed fallback value for this design property"
|
|
5807
|
+
),
|
|
5808
|
+
allowedResources: z84.array(
|
|
5809
|
+
z84.object({
|
|
5810
|
+
type: z84.literal("DesignToken"),
|
|
5811
|
+
value: z84.string(),
|
|
5812
|
+
name: z84.string().optional()
|
|
5813
|
+
})
|
|
5814
|
+
).optional().describe("Allowed design token resources")
|
|
5815
|
+
});
|
|
5816
|
+
var DesignPropertySchema = z84.union([
|
|
5817
|
+
StringDesignPropertySchema,
|
|
5818
|
+
BooleanDesignPropertySchema,
|
|
5819
|
+
TokenBackedDesignPropertySchema
|
|
5820
|
+
]);
|
|
5821
|
+
var ManualDesignValueSchema = z84.object({
|
|
5822
|
+
type: z84.literal("ManualDesignValue"),
|
|
5823
|
+
value: z84.union([z84.string(), z84.number(), z84.boolean()])
|
|
5824
|
+
});
|
|
5825
|
+
var DesignPropertyValueSchema = z84.union([
|
|
5826
|
+
ManualDesignValueSchema,
|
|
5827
|
+
DesignTokenValueSchema
|
|
5828
|
+
]);
|
|
5829
|
+
var DesignPropertyPointerValueSchema = z84.custom(
|
|
5830
|
+
(val) => typeof val === "string" && /^\$designProperties\//.test(val),
|
|
5831
|
+
{ message: 'Must be a "$designProperties/..." pointer' }
|
|
5832
|
+
);
|
|
5833
|
+
var DimensionedDesignPropertyValueSchema = z84.record(
|
|
5834
|
+
z84.string(),
|
|
5835
|
+
DesignPropertyValueSchema
|
|
5836
|
+
);
|
|
5837
|
+
var ComponentTreeDesignPropertyValueSchema = z84.union([
|
|
5838
|
+
DesignPropertyValueSchema,
|
|
5839
|
+
DesignPropertyPointerValueSchema,
|
|
5840
|
+
DimensionedDesignPropertyValueSchema
|
|
5841
|
+
]);
|
|
5842
|
+
var COMPONENT_TYPE_ALLOWED_RESOURCE_SOURCE = "crn:contentful:::experience:spaces/$self/environments/$self";
|
|
5843
|
+
var SlotDefinitionSchema = z84.object({
|
|
5844
|
+
id: z84.string().describe("Slot identifier"),
|
|
5845
|
+
name: z84.string().describe("Human-readable name"),
|
|
5846
|
+
required: z84.boolean().describe("Whether the slot must be filled"),
|
|
5847
|
+
validations: z84.array(
|
|
5848
|
+
z84.object({
|
|
5849
|
+
size: z84.object({
|
|
5850
|
+
min: z84.number().optional(),
|
|
5851
|
+
max: z84.number().optional()
|
|
5852
|
+
}).optional()
|
|
5853
|
+
})
|
|
5854
|
+
).describe("Slot cardinality validations"),
|
|
5855
|
+
allowedResources: z84.array(
|
|
5856
|
+
z84.object({
|
|
5857
|
+
type: z84.literal("Contentful:ComponentType"),
|
|
5858
|
+
source: z84.literal(COMPONENT_TYPE_ALLOWED_RESOURCE_SOURCE),
|
|
5859
|
+
allowedTypes: z84.array(z84.string()).describe("IDs of component types allowed in this slot")
|
|
5860
|
+
})
|
|
5861
|
+
).optional().describe("Constrains which component types may be placed in this slot")
|
|
5862
|
+
});
|
|
5863
|
+
var FragmentNodeSchema = z84.object({
|
|
5864
|
+
id: z84.string().describe("Node identifier"),
|
|
5865
|
+
name: z84.string().optional().describe("Optional display name"),
|
|
5866
|
+
nodeType: z84.literal("Fragment").describe('Must be "Fragment"'),
|
|
5867
|
+
fragment: FragmentResourceLinkSchema.describe("Resource link to the referenced fragment")
|
|
5868
|
+
});
|
|
5869
|
+
var SlotNodeSchema = z84.object({
|
|
5870
|
+
id: z84.string().describe("Node identifier"),
|
|
5871
|
+
nodeType: z84.literal("Slot").describe('Must be "Slot"'),
|
|
5872
|
+
slotId: z84.string().describe("ID of the slot definition to render")
|
|
5873
|
+
});
|
|
5874
|
+
var TreeNodeSchema = z84.lazy(
|
|
5875
|
+
() => z84.union([ComponentNodeSchema, FragmentNodeSchema, SlotNodeSchema])
|
|
5876
|
+
);
|
|
5877
|
+
var ComponentNodeSchema = z84.lazy(
|
|
5878
|
+
() => z84.object({
|
|
5879
|
+
id: z84.string().describe("Node identifier"),
|
|
5880
|
+
name: z84.string().optional().describe("Optional display name"),
|
|
5881
|
+
nodeType: z84.literal("Component").describe('Must be "Component"'),
|
|
5882
|
+
componentType: ComponentTypeResourceLinkSchema.describe(
|
|
5883
|
+
"Resource link to the component type to render"
|
|
5884
|
+
),
|
|
5885
|
+
contentProperties: z84.union([
|
|
5886
|
+
z84.record(z84.string(), z84.unknown()),
|
|
5887
|
+
z84.string().describe('"$contentProperties/..." pointer')
|
|
5888
|
+
]).describe(
|
|
5889
|
+
'Content property bindings \u2014 values or "$contentProperties/..." pointers'
|
|
5890
|
+
),
|
|
5891
|
+
designProperties: z84.record(z84.string(), ComponentTreeDesignPropertyValueSchema).describe(
|
|
5892
|
+
'Design property values \u2014 ManualDesignValue, DesignTokenValue, or "$designProperties/..." pointers'
|
|
5893
|
+
),
|
|
5894
|
+
slots: z84.record(z84.string(), z84.array(TreeNodeSchema)).describe("Child tree nodes keyed by slot ID")
|
|
5895
|
+
})
|
|
5896
|
+
);
|
|
5897
|
+
var TagLinkSchema = linkSchema2("Tag");
|
|
5898
|
+
var ConceptLinkSchema = linkSchema2("TaxonomyConcept");
|
|
5899
|
+
var ExoMetadataSchema = z84.object({
|
|
5900
|
+
tags: z84.array(TagLinkSchema).optional().describe("Tags attached to this entity"),
|
|
5901
|
+
concepts: z84.array(ConceptLinkSchema).optional().describe("Taxonomy concepts attached to this entity")
|
|
5902
|
+
});
|
|
5903
|
+
var ExperienceMetadataSchema = ExoMetadataSchema.extend({
|
|
5904
|
+
name: z84.string().optional().describe("Variant label for this metadata entry")
|
|
5905
|
+
});
|
|
5906
|
+
var DataAssemblyResourceLinkSchema = resourceLinkSchema2("Contentful:DataAssembly");
|
|
5907
|
+
var ExperienceContentBindingsSchema = z84.object({
|
|
5908
|
+
sys: DataAssemblyResourceLinkSchema.shape.sys,
|
|
5909
|
+
parameters: z84.record(
|
|
5910
|
+
z84.string(),
|
|
5911
|
+
z84.object({
|
|
5912
|
+
sys: z84.object({
|
|
5913
|
+
type: z84.literal("ResourceLink"),
|
|
5914
|
+
linkType: z84.string(),
|
|
5915
|
+
urn: z84.string()
|
|
5916
|
+
})
|
|
5917
|
+
})
|
|
5918
|
+
).describe("Parameter bindings keyed by parameter ID")
|
|
5919
|
+
});
|
|
5920
|
+
var InlineFragmentNodeSchema = z84.lazy(
|
|
5921
|
+
() => z84.object({
|
|
5922
|
+
id: z84.string().describe("Node identifier"),
|
|
5923
|
+
nodeType: z84.literal("InlineFragment").describe('Must be "InlineFragment"'),
|
|
5924
|
+
componentType: ComponentTypeResourceLinkSchema.describe(
|
|
5925
|
+
"Resource link to the component type this inline fragment renders"
|
|
5926
|
+
),
|
|
5927
|
+
designProperties: z84.record(z84.string(), DimensionedDesignPropertyValueSchema).describe("Design property values for this inline fragment"),
|
|
5928
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
5929
|
+
"Optional content bindings linking this inline fragment to a data assembly"
|
|
5930
|
+
),
|
|
5931
|
+
slots: z84.record(z84.string(), z84.array(ExperienceSlotNodeSchema)).optional().describe("Child slot contents keyed by slot ID")
|
|
5932
|
+
})
|
|
5933
|
+
);
|
|
5934
|
+
var ExperienceSlotNodeSchema = z84.lazy(
|
|
5935
|
+
() => z84.union([FragmentNodeSchema, InlineFragmentNodeSchema])
|
|
5936
|
+
);
|
|
5937
|
+
|
|
5938
|
+
// src/tools/exo/component-types/createComponentType.ts
|
|
5939
|
+
var CreateComponentTypeToolParams = BaseToolSchema.extend({
|
|
5940
|
+
name: z85.string().describe("The name of the component type"),
|
|
5941
|
+
description: z85.string().describe("Description of the component type"),
|
|
5942
|
+
viewports: z85.array(ViewportSchema).describe("Viewport definitions for the component type (may be empty)"),
|
|
5943
|
+
contentProperties: z85.array(ContentPropertySchema).describe("Content property definitions (may be empty)"),
|
|
5944
|
+
designProperties: z85.array(DesignPropertySchema).describe("Design property definitions (may be empty)"),
|
|
5945
|
+
componentTree: z85.array(TreeNodeSchema).optional().describe("Optional component tree node definitions"),
|
|
5946
|
+
slots: z85.array(SlotDefinitionSchema).optional().describe("Optional slot definitions"),
|
|
5947
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
5948
|
+
"Optional ExO metadata (tags, concepts)"
|
|
5949
|
+
)
|
|
5950
|
+
});
|
|
5951
|
+
function createComponentTypeTool(config) {
|
|
5952
|
+
async function tool2(args) {
|
|
5953
|
+
assertEnvironmentNotProtected(
|
|
5954
|
+
args.environmentId,
|
|
5955
|
+
config.protectedEnvironments
|
|
5956
|
+
);
|
|
5957
|
+
const contentfulClient = createToolClient(config, args);
|
|
5958
|
+
const componentType = await contentfulClient.componentType.create(
|
|
5959
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
5960
|
+
{
|
|
5961
|
+
name: args.name,
|
|
5962
|
+
description: args.description,
|
|
5963
|
+
viewports: args.viewports,
|
|
5964
|
+
contentProperties: args.contentProperties,
|
|
5965
|
+
designProperties: args.designProperties,
|
|
5966
|
+
...args.componentTree && { componentTree: args.componentTree },
|
|
5967
|
+
...args.slots && { slots: args.slots },
|
|
5968
|
+
...args.metadata && { metadata: args.metadata }
|
|
5969
|
+
}
|
|
5970
|
+
);
|
|
5971
|
+
return createSuccessResponse("Component type created successfully", {
|
|
5972
|
+
componentType
|
|
5973
|
+
});
|
|
5735
5974
|
}
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5975
|
+
return withErrorHandling(tool2, "Error creating component type");
|
|
5976
|
+
}
|
|
5977
|
+
|
|
5978
|
+
// src/tools/exo/component-types/upsertComponentType.ts
|
|
5979
|
+
import { z as z86 } from "zod";
|
|
5980
|
+
var UpsertComponentTypeToolParams = BaseToolSchema.extend({
|
|
5981
|
+
componentTypeId: z86.string().describe("The ID of the component type to update"),
|
|
5982
|
+
version: z86.number().describe(
|
|
5983
|
+
"REQUIRED. The component type's sys.version as returned by get_component_type. You must call get_component_type first to read the current state and version. The update is rejected if this does not match the current version, which means the component type changed since you read it."
|
|
5984
|
+
),
|
|
5985
|
+
name: z86.string().optional().describe("The name of the component type"),
|
|
5986
|
+
description: z86.string().optional().describe("Description of the component type"),
|
|
5987
|
+
viewports: z86.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
5988
|
+
contentProperties: z86.array(ContentPropertySchema).optional().describe("Content property definitions; replaces existing if provided"),
|
|
5989
|
+
designProperties: z86.array(DesignPropertySchema).optional().describe("Design property definitions; replaces existing if provided"),
|
|
5990
|
+
componentTree: z86.array(TreeNodeSchema).optional().describe("Component tree node definitions; replaces existing if provided"),
|
|
5991
|
+
slots: z86.array(SlotDefinitionSchema).optional().describe("Slot definitions; replaces existing if provided"),
|
|
5992
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
5993
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
5994
|
+
)
|
|
5995
|
+
});
|
|
5996
|
+
function upsertComponentTypeTool(config) {
|
|
5997
|
+
async function tool2(args) {
|
|
5998
|
+
assertEnvironmentNotProtected(
|
|
5999
|
+
args.environmentId,
|
|
6000
|
+
config.protectedEnvironments
|
|
6001
|
+
);
|
|
6002
|
+
const params = {
|
|
6003
|
+
spaceId: args.spaceId,
|
|
6004
|
+
environmentId: args.environmentId,
|
|
6005
|
+
componentTypeId: args.componentTypeId
|
|
6006
|
+
};
|
|
6007
|
+
const contentfulClient = createToolClient(config, args);
|
|
6008
|
+
const current = await contentfulClient.componentType.get(params);
|
|
6009
|
+
if (args.version !== current.sys.version) {
|
|
6010
|
+
throw new Error(
|
|
6011
|
+
`Version conflict: the component type has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the component type with get_component_type and retry the update with the latest sys.version.`
|
|
6012
|
+
);
|
|
6013
|
+
}
|
|
6014
|
+
const componentType = await contentfulClient.componentType.upsert(params, {
|
|
6015
|
+
sys: {
|
|
6016
|
+
id: current.sys.id,
|
|
6017
|
+
type: "ComponentType",
|
|
6018
|
+
version: current.sys.version
|
|
6019
|
+
},
|
|
6020
|
+
name: args.name ?? current.name,
|
|
6021
|
+
description: args.description ?? current.description,
|
|
6022
|
+
viewports: args.viewports ?? current.viewports,
|
|
6023
|
+
contentProperties: args.contentProperties ?? current.contentProperties,
|
|
6024
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
6025
|
+
...args.componentTree ?? current.componentTree ? { componentTree: args.componentTree ?? current.componentTree } : {},
|
|
6026
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
6027
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {},
|
|
6028
|
+
...current.dataAssemblies ? { dataAssemblies: current.dataAssemblies } : {}
|
|
6029
|
+
});
|
|
6030
|
+
return createSuccessResponse("Component type updated successfully", {
|
|
6031
|
+
componentType
|
|
6032
|
+
});
|
|
5741
6033
|
}
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
6034
|
+
return withErrorHandling(tool2, "Error updating component type");
|
|
6035
|
+
}
|
|
6036
|
+
|
|
6037
|
+
// src/tools/exo/component-types/deleteComponentType.ts
|
|
6038
|
+
import { z as z87 } from "zod";
|
|
6039
|
+
var DeleteComponentTypeToolParams = BaseToolSchema.extend({
|
|
6040
|
+
componentTypeId: z87.string().describe("The ID of the component type to delete"),
|
|
6041
|
+
confirm: z87.boolean().optional().describe(
|
|
6042
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
6043
|
+
),
|
|
6044
|
+
confirmToken: z87.string().optional().describe(
|
|
6045
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
6046
|
+
)
|
|
6047
|
+
});
|
|
6048
|
+
function deleteComponentTypeTool(config) {
|
|
6049
|
+
async function tool2(args) {
|
|
6050
|
+
assertEnvironmentNotProtected(
|
|
6051
|
+
args.environmentId,
|
|
6052
|
+
config.protectedEnvironments
|
|
6053
|
+
);
|
|
6054
|
+
const params = {
|
|
6055
|
+
spaceId: args.spaceId,
|
|
6056
|
+
environmentId: args.environmentId,
|
|
6057
|
+
componentTypeId: args.componentTypeId
|
|
6058
|
+
};
|
|
6059
|
+
const contentfulClient = createToolClient(config, args);
|
|
6060
|
+
const componentType = await contentfulClient.componentType.get(params);
|
|
6061
|
+
const expectedToken = buildConfirmToken(
|
|
6062
|
+
"componentType",
|
|
6063
|
+
args.componentTypeId,
|
|
6064
|
+
componentType.sys.version
|
|
6065
|
+
);
|
|
6066
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
6067
|
+
return createSuccessResponse(
|
|
6068
|
+
`${CONFIRMATION_MESSAGE_PREFIX} component type`,
|
|
6069
|
+
buildConfirmationPreview(
|
|
6070
|
+
"componentType",
|
|
6071
|
+
args.componentTypeId,
|
|
6072
|
+
{ componentType },
|
|
6073
|
+
expectedToken
|
|
6074
|
+
)
|
|
6075
|
+
);
|
|
6076
|
+
}
|
|
6077
|
+
await contentfulClient.componentType.delete(params);
|
|
6078
|
+
return createSuccessResponse("Component type deleted successfully", {
|
|
6079
|
+
componentTypeId: args.componentTypeId
|
|
6080
|
+
});
|
|
5747
6081
|
}
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
6082
|
+
return withErrorHandling(tool2, "Error deleting component type");
|
|
6083
|
+
}
|
|
6084
|
+
|
|
6085
|
+
// src/tools/exo/component-types/publishComponentType.ts
|
|
6086
|
+
import { z as z88 } from "zod";
|
|
6087
|
+
var PublishComponentTypeToolParams = BaseToolSchema.extend({
|
|
6088
|
+
componentTypeId: z88.string().describe("The ID of the component type to publish"),
|
|
6089
|
+
version: z88.number().describe(
|
|
6090
|
+
"REQUIRED. The component type's sys.version as returned by get_component_type. You must call get_component_type first to read the current state and version. The publish is rejected if this does not match the current version, which means the component type changed since you read it."
|
|
6091
|
+
)
|
|
6092
|
+
});
|
|
6093
|
+
function publishComponentTypeTool(config) {
|
|
6094
|
+
async function tool2(args) {
|
|
6095
|
+
assertEnvironmentNotProtected(
|
|
6096
|
+
args.environmentId,
|
|
6097
|
+
config.protectedEnvironments
|
|
6098
|
+
);
|
|
6099
|
+
const params = {
|
|
6100
|
+
spaceId: args.spaceId,
|
|
6101
|
+
environmentId: args.environmentId,
|
|
6102
|
+
componentTypeId: args.componentTypeId
|
|
6103
|
+
};
|
|
6104
|
+
const contentfulClient = createToolClient(config, args);
|
|
6105
|
+
const current = await contentfulClient.componentType.get(params);
|
|
6106
|
+
if (args.version !== current.sys.version) {
|
|
6107
|
+
throw new Error(
|
|
6108
|
+
`Version conflict: the component type has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the component type with get_component_type and retry with the latest sys.version.`
|
|
6109
|
+
);
|
|
6110
|
+
}
|
|
6111
|
+
const componentType = await contentfulClient.componentType.publish({
|
|
6112
|
+
...params,
|
|
6113
|
+
version: args.version
|
|
6114
|
+
});
|
|
6115
|
+
return createSuccessResponse("Component type published successfully", {
|
|
6116
|
+
componentType
|
|
6117
|
+
});
|
|
5753
6118
|
}
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
6119
|
+
return withErrorHandling(tool2, "Error publishing component type");
|
|
6120
|
+
}
|
|
6121
|
+
|
|
6122
|
+
// src/tools/exo/component-types/unpublishComponentType.ts
|
|
6123
|
+
import { z as z89 } from "zod";
|
|
6124
|
+
var UnpublishComponentTypeToolParams = BaseToolSchema.extend({
|
|
6125
|
+
componentTypeId: z89.string().describe("The ID of the component type to unpublish"),
|
|
6126
|
+
version: z89.number().describe(
|
|
6127
|
+
"REQUIRED. The component type's sys.version as returned by get_component_type. You must call get_component_type first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the component type changed since you read it."
|
|
6128
|
+
)
|
|
6129
|
+
});
|
|
6130
|
+
function unpublishComponentTypeTool(config) {
|
|
6131
|
+
async function tool2(args) {
|
|
6132
|
+
assertEnvironmentNotProtected(
|
|
6133
|
+
args.environmentId,
|
|
6134
|
+
config.protectedEnvironments
|
|
6135
|
+
);
|
|
6136
|
+
const params = {
|
|
6137
|
+
spaceId: args.spaceId,
|
|
6138
|
+
environmentId: args.environmentId,
|
|
6139
|
+
componentTypeId: args.componentTypeId
|
|
6140
|
+
};
|
|
6141
|
+
const contentfulClient = createToolClient(config, args);
|
|
6142
|
+
const current = await contentfulClient.componentType.get(params);
|
|
6143
|
+
if (args.version !== current.sys.version) {
|
|
6144
|
+
throw new Error(
|
|
6145
|
+
`Version conflict: the component type has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the component type with get_component_type and retry with the latest sys.version.`
|
|
6146
|
+
);
|
|
6147
|
+
}
|
|
6148
|
+
const componentType = await contentfulClient.componentType.unpublish({
|
|
6149
|
+
...params,
|
|
6150
|
+
version: args.version
|
|
6151
|
+
});
|
|
6152
|
+
return createSuccessResponse("Component type unpublished successfully", {
|
|
6153
|
+
componentType
|
|
6154
|
+
});
|
|
5759
6155
|
}
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
6156
|
+
return withErrorHandling(tool2, "Error unpublishing component type");
|
|
6157
|
+
}
|
|
6158
|
+
|
|
6159
|
+
// src/tools/exo/component-types/register.ts
|
|
6160
|
+
function createComponentTypeTools(config) {
|
|
6161
|
+
const getComponentType = getComponentTypeTool(config);
|
|
6162
|
+
const listComponentTypes = listComponentTypesTool(config);
|
|
6163
|
+
const createComponentType = createComponentTypeTool(config);
|
|
6164
|
+
const upsertComponentType = upsertComponentTypeTool(config);
|
|
6165
|
+
const deleteComponentType = deleteComponentTypeTool(config);
|
|
6166
|
+
const publishComponentType = publishComponentTypeTool(config);
|
|
6167
|
+
const unpublishComponentType = unpublishComponentTypeTool(config);
|
|
6168
|
+
return {
|
|
6169
|
+
getComponentType: {
|
|
6170
|
+
title: "get_component_type",
|
|
6171
|
+
description: "Get details about a specific ExO component type (a reusable section/pattern template defining slots, content properties, and design properties).",
|
|
6172
|
+
inputParams: GetComponentTypeToolParams.shape,
|
|
6173
|
+
annotations: {
|
|
6174
|
+
readOnlyHint: true,
|
|
6175
|
+
destructiveHint: false,
|
|
6176
|
+
openWorldHint: false
|
|
6177
|
+
},
|
|
6178
|
+
tool: getComponentType
|
|
6179
|
+
},
|
|
6180
|
+
listComponentTypes: {
|
|
6181
|
+
title: "list_component_types",
|
|
6182
|
+
description: "List ExO component types in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
6183
|
+
inputParams: ListComponentTypesToolParams.shape,
|
|
6184
|
+
annotations: {
|
|
6185
|
+
readOnlyHint: true,
|
|
6186
|
+
destructiveHint: false,
|
|
6187
|
+
openWorldHint: false
|
|
6188
|
+
},
|
|
6189
|
+
tool: listComponentTypes
|
|
6190
|
+
},
|
|
6191
|
+
createComponentType: {
|
|
6192
|
+
title: "create_component_type",
|
|
6193
|
+
description: "Create a new ExO component type.",
|
|
6194
|
+
inputParams: CreateComponentTypeToolParams.shape,
|
|
6195
|
+
annotations: {
|
|
6196
|
+
readOnlyHint: false,
|
|
6197
|
+
destructiveHint: false,
|
|
6198
|
+
idempotentHint: false,
|
|
6199
|
+
openWorldHint: false
|
|
6200
|
+
},
|
|
6201
|
+
tool: createComponentType
|
|
6202
|
+
},
|
|
6203
|
+
upsertComponentType: {
|
|
6204
|
+
title: "upsert_component_type",
|
|
6205
|
+
description: "Update an existing ExO component type. You MUST call get_component_type first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing component type fields, so you only need to provide the fields you want to change. If the version is stale (the component type changed since you read it), the update is rejected and you must re-fetch with get_component_type.",
|
|
6206
|
+
inputParams: UpsertComponentTypeToolParams.shape,
|
|
6207
|
+
annotations: {
|
|
6208
|
+
readOnlyHint: false,
|
|
6209
|
+
destructiveHint: false,
|
|
6210
|
+
idempotentHint: false,
|
|
6211
|
+
openWorldHint: false
|
|
6212
|
+
},
|
|
6213
|
+
tool: upsertComponentType
|
|
6214
|
+
},
|
|
6215
|
+
deleteComponentType: {
|
|
6216
|
+
title: "delete_component_type",
|
|
6217
|
+
description: "Delete an ExO component type. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same componentTypeId, confirm: true, and the confirmToken from the preview.",
|
|
6218
|
+
inputParams: DeleteComponentTypeToolParams.shape,
|
|
6219
|
+
annotations: {
|
|
6220
|
+
readOnlyHint: false,
|
|
6221
|
+
destructiveHint: true,
|
|
6222
|
+
idempotentHint: false,
|
|
6223
|
+
openWorldHint: false
|
|
6224
|
+
},
|
|
6225
|
+
tool: deleteComponentType
|
|
6226
|
+
},
|
|
6227
|
+
publishComponentType: {
|
|
6228
|
+
title: "publish_component_type",
|
|
6229
|
+
description: "Publish an ExO component type. You MUST call get_component_type first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_component_type.",
|
|
6230
|
+
inputParams: PublishComponentTypeToolParams.shape,
|
|
6231
|
+
annotations: {
|
|
6232
|
+
readOnlyHint: false,
|
|
6233
|
+
destructiveHint: true,
|
|
6234
|
+
idempotentHint: true,
|
|
6235
|
+
openWorldHint: false
|
|
6236
|
+
},
|
|
6237
|
+
tool: publishComponentType
|
|
6238
|
+
},
|
|
6239
|
+
unpublishComponentType: {
|
|
6240
|
+
title: "unpublish_component_type",
|
|
6241
|
+
description: "Unpublish an ExO component type. You MUST call get_component_type first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_component_type.",
|
|
6242
|
+
inputParams: UnpublishComponentTypeToolParams.shape,
|
|
6243
|
+
annotations: {
|
|
6244
|
+
readOnlyHint: false,
|
|
6245
|
+
destructiveHint: true,
|
|
6246
|
+
idempotentHint: true,
|
|
6247
|
+
openWorldHint: false
|
|
6248
|
+
},
|
|
6249
|
+
tool: unpublishComponentType
|
|
6250
|
+
}
|
|
6251
|
+
};
|
|
6252
|
+
}
|
|
6253
|
+
|
|
6254
|
+
// src/tools/exo/fragments/getFragment.ts
|
|
6255
|
+
import { z as z90 } from "zod";
|
|
6256
|
+
var GetFragmentToolParams = BaseToolSchema.extend({
|
|
6257
|
+
fragmentId: z90.string().describe("The ID of the fragment to retrieve details for")
|
|
6258
|
+
});
|
|
6259
|
+
function getFragmentTool(config) {
|
|
6260
|
+
async function tool2(args) {
|
|
6261
|
+
const contentfulClient = createToolClient(config, args);
|
|
6262
|
+
const fragment = await contentfulClient.fragment.get({
|
|
6263
|
+
spaceId: args.spaceId,
|
|
6264
|
+
environmentId: args.environmentId,
|
|
6265
|
+
fragmentId: args.fragmentId
|
|
6266
|
+
});
|
|
6267
|
+
return createSuccessResponse("Fragment retrieved successfully", {
|
|
6268
|
+
fragment
|
|
6269
|
+
});
|
|
6270
|
+
}
|
|
6271
|
+
return withErrorHandling(tool2, "Error retrieving fragment");
|
|
6272
|
+
}
|
|
6273
|
+
|
|
6274
|
+
// src/tools/exo/fragments/listFragments.ts
|
|
6275
|
+
import { z as z91 } from "zod";
|
|
6276
|
+
var ListFragmentsToolParams = BaseToolSchema.extend({
|
|
6277
|
+
limit: z91.number().optional().describe("Maximum number of fragments to return (max 10)"),
|
|
6278
|
+
pageNext: z91.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
6279
|
+
pagePrev: z91.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
6280
|
+
order: z91.string().optional().describe("Order fragments by this field (e.g. sys.createdAt)")
|
|
6281
|
+
});
|
|
6282
|
+
function listFragmentsTool(config) {
|
|
6283
|
+
async function tool2(args) {
|
|
6284
|
+
const contentfulClient = createToolClient(config, args);
|
|
6285
|
+
const fragments = await contentfulClient.fragment.getMany({
|
|
6286
|
+
spaceId: args.spaceId,
|
|
6287
|
+
environmentId: args.environmentId,
|
|
6288
|
+
query: {
|
|
6289
|
+
limit: Math.min(args.limit || 10, 10),
|
|
6290
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
6291
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
6292
|
+
...args.order && { order: args.order }
|
|
6293
|
+
}
|
|
6294
|
+
});
|
|
6295
|
+
const summarized = summarizeData(fragments, {
|
|
6296
|
+
maxItems: 10,
|
|
6297
|
+
remainingMessage: "To see more fragments, ask me to retrieve the next page using the pageNext cursor."
|
|
6298
|
+
});
|
|
6299
|
+
return createSuccessResponse("Fragments retrieved successfully", {
|
|
6300
|
+
fragments: summarized,
|
|
6301
|
+
total: fragments.total,
|
|
6302
|
+
limit: fragments.limit,
|
|
6303
|
+
pages: fragments.pages
|
|
6304
|
+
});
|
|
6305
|
+
}
|
|
6306
|
+
return withErrorHandling(tool2, "Error listing fragments");
|
|
6307
|
+
}
|
|
6308
|
+
|
|
6309
|
+
// src/tools/exo/fragments/createFragment.ts
|
|
6310
|
+
import { z as z92 } from "zod";
|
|
6311
|
+
var CreateFragmentToolParams = BaseToolSchema.extend({
|
|
6312
|
+
name: z92.string().describe("The name of the fragment"),
|
|
6313
|
+
description: z92.string().describe("Description of the fragment"),
|
|
6314
|
+
componentType: ComponentTypeResourceLinkSchema.describe(
|
|
6315
|
+
"Resource link to the component type this fragment is based on"
|
|
6316
|
+
),
|
|
6317
|
+
viewports: z92.array(ViewportSchema).describe("Viewport definitions (may be empty)"),
|
|
6318
|
+
designProperties: z92.record(z92.string(), DimensionedDesignPropertyValueSchema).describe("Design property values keyed by property ID (may be empty object)"),
|
|
6319
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
6320
|
+
"Optional content bindings for the fragment"
|
|
6321
|
+
),
|
|
6322
|
+
slots: z92.record(z92.string(), z92.array(ExperienceSlotNodeSchema)).optional().describe("Optional slot node definitions keyed by slot ID"),
|
|
6323
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
6324
|
+
"Optional ExO metadata (tags, concepts)"
|
|
6325
|
+
)
|
|
6326
|
+
});
|
|
6327
|
+
function createFragmentTool(config) {
|
|
6328
|
+
async function tool2(args) {
|
|
6329
|
+
assertEnvironmentNotProtected(
|
|
6330
|
+
args.environmentId,
|
|
6331
|
+
config.protectedEnvironments
|
|
6332
|
+
);
|
|
6333
|
+
const contentfulClient = createToolClient(config, args);
|
|
6334
|
+
const fragment = await contentfulClient.fragment.create(
|
|
6335
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
6336
|
+
{
|
|
6337
|
+
name: args.name,
|
|
6338
|
+
description: args.description,
|
|
6339
|
+
componentType: args.componentType,
|
|
6340
|
+
viewports: args.viewports,
|
|
6341
|
+
designProperties: args.designProperties,
|
|
6342
|
+
...args.contentBindings && { contentBindings: args.contentBindings },
|
|
6343
|
+
...args.slots && { slots: args.slots },
|
|
6344
|
+
...args.metadata && { metadata: args.metadata }
|
|
6345
|
+
}
|
|
6346
|
+
);
|
|
6347
|
+
return createSuccessResponse("Fragment created successfully", {
|
|
6348
|
+
fragment
|
|
6349
|
+
});
|
|
6350
|
+
}
|
|
6351
|
+
return withErrorHandling(tool2, "Error creating fragment");
|
|
6352
|
+
}
|
|
6353
|
+
|
|
6354
|
+
// src/tools/exo/fragments/updateFragment.ts
|
|
6355
|
+
import { z as z93 } from "zod";
|
|
6356
|
+
var UpdateFragmentToolParams = BaseToolSchema.extend({
|
|
6357
|
+
fragmentId: z93.string().describe("The ID of the fragment to update"),
|
|
6358
|
+
version: z93.number().describe(
|
|
6359
|
+
"REQUIRED. The fragment's sys.version as returned by get_fragment. You must call get_fragment first to read the current state and version. The update is rejected if this does not match the current version, which means the fragment changed since you read it."
|
|
6360
|
+
),
|
|
6361
|
+
name: z93.string().optional().describe("The name of the fragment"),
|
|
6362
|
+
description: z93.string().optional().describe("Description of the fragment"),
|
|
6363
|
+
viewports: z93.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
6364
|
+
designProperties: z93.record(z93.string(), DimensionedDesignPropertyValueSchema).optional().describe("Design property values; replaces existing if provided"),
|
|
6365
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
6366
|
+
"Content bindings; replaces existing if provided"
|
|
6367
|
+
),
|
|
6368
|
+
slots: z93.record(z93.string(), z93.array(ExperienceSlotNodeSchema)).optional().describe("Slot node definitions; replaces existing if provided"),
|
|
6369
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
6370
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
6371
|
+
)
|
|
6372
|
+
});
|
|
6373
|
+
function updateFragmentTool(config) {
|
|
6374
|
+
async function tool2(args) {
|
|
6375
|
+
assertEnvironmentNotProtected(
|
|
6376
|
+
args.environmentId,
|
|
6377
|
+
config.protectedEnvironments
|
|
6378
|
+
);
|
|
6379
|
+
const params = {
|
|
6380
|
+
spaceId: args.spaceId,
|
|
6381
|
+
environmentId: args.environmentId,
|
|
6382
|
+
fragmentId: args.fragmentId
|
|
6383
|
+
};
|
|
6384
|
+
const contentfulClient = createToolClient(config, args);
|
|
6385
|
+
const current = await contentfulClient.fragment.get(params);
|
|
6386
|
+
if (args.version !== current.sys.version) {
|
|
6387
|
+
throw new Error(
|
|
6388
|
+
`Version conflict: the fragment has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the fragment with get_fragment and retry the update with the latest sys.version.`
|
|
6389
|
+
);
|
|
6390
|
+
}
|
|
6391
|
+
const fragment = await contentfulClient.fragment.upsert(params, {
|
|
6392
|
+
sys: {
|
|
6393
|
+
id: current.sys.id,
|
|
6394
|
+
type: "Fragment",
|
|
6395
|
+
version: current.sys.version
|
|
6396
|
+
},
|
|
6397
|
+
name: args.name ?? current.name,
|
|
6398
|
+
description: args.description ?? current.description,
|
|
6399
|
+
viewports: args.viewports ?? current.viewports,
|
|
6400
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
6401
|
+
...args.contentBindings ?? current.contentBindings ? { contentBindings: args.contentBindings ?? current.contentBindings } : {},
|
|
6402
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
6403
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {}
|
|
6404
|
+
});
|
|
6405
|
+
return createSuccessResponse("Fragment updated successfully", {
|
|
6406
|
+
fragment
|
|
6407
|
+
});
|
|
6408
|
+
}
|
|
6409
|
+
return withErrorHandling(tool2, "Error updating fragment");
|
|
6410
|
+
}
|
|
6411
|
+
|
|
6412
|
+
// src/tools/exo/fragments/deleteFragment.ts
|
|
6413
|
+
import { z as z94 } from "zod";
|
|
6414
|
+
var DeleteFragmentToolParams = BaseToolSchema.extend({
|
|
6415
|
+
fragmentId: z94.string().describe("The ID of the fragment to delete"),
|
|
6416
|
+
confirm: z94.boolean().optional().describe(
|
|
6417
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
6418
|
+
),
|
|
6419
|
+
confirmToken: z94.string().optional().describe(
|
|
6420
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
6421
|
+
)
|
|
6422
|
+
});
|
|
6423
|
+
function deleteFragmentTool(config) {
|
|
6424
|
+
async function tool2(args) {
|
|
6425
|
+
assertEnvironmentNotProtected(
|
|
6426
|
+
args.environmentId,
|
|
6427
|
+
config.protectedEnvironments
|
|
6428
|
+
);
|
|
6429
|
+
const params = {
|
|
6430
|
+
spaceId: args.spaceId,
|
|
6431
|
+
environmentId: args.environmentId,
|
|
6432
|
+
fragmentId: args.fragmentId
|
|
6433
|
+
};
|
|
6434
|
+
const contentfulClient = createToolClient(config, args);
|
|
6435
|
+
const fragment = await contentfulClient.fragment.get(params);
|
|
6436
|
+
const expectedToken = buildConfirmToken(
|
|
6437
|
+
"fragment",
|
|
6438
|
+
args.fragmentId,
|
|
6439
|
+
fragment.sys.version
|
|
6440
|
+
);
|
|
6441
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
6442
|
+
return createSuccessResponse(
|
|
6443
|
+
`${CONFIRMATION_MESSAGE_PREFIX} fragment`,
|
|
6444
|
+
buildConfirmationPreview(
|
|
6445
|
+
"fragment",
|
|
6446
|
+
args.fragmentId,
|
|
6447
|
+
{ fragment },
|
|
6448
|
+
expectedToken
|
|
6449
|
+
)
|
|
6450
|
+
);
|
|
6451
|
+
}
|
|
6452
|
+
await contentfulClient.fragment.delete(params);
|
|
6453
|
+
return createSuccessResponse("Fragment deleted successfully", {
|
|
6454
|
+
fragmentId: args.fragmentId
|
|
6455
|
+
});
|
|
6456
|
+
}
|
|
6457
|
+
return withErrorHandling(tool2, "Error deleting fragment");
|
|
6458
|
+
}
|
|
6459
|
+
|
|
6460
|
+
// src/tools/exo/fragments/publishFragment.ts
|
|
6461
|
+
import { z as z95 } from "zod";
|
|
6462
|
+
var PublishFragmentToolParams = BaseToolSchema.extend({
|
|
6463
|
+
fragmentId: z95.string().describe("The ID of the fragment to publish"),
|
|
6464
|
+
version: z95.number().describe(
|
|
6465
|
+
"REQUIRED. The fragment's sys.version as returned by get_fragment. You must call get_fragment first to read the current state and version. The publish is rejected if this does not match the current version, which means the fragment changed since you read it."
|
|
6466
|
+
)
|
|
6467
|
+
});
|
|
6468
|
+
function publishFragmentTool(config) {
|
|
6469
|
+
async function tool2(args) {
|
|
6470
|
+
assertEnvironmentNotProtected(
|
|
6471
|
+
args.environmentId,
|
|
6472
|
+
config.protectedEnvironments
|
|
6473
|
+
);
|
|
6474
|
+
const params = {
|
|
6475
|
+
spaceId: args.spaceId,
|
|
6476
|
+
environmentId: args.environmentId,
|
|
6477
|
+
fragmentId: args.fragmentId
|
|
6478
|
+
};
|
|
6479
|
+
const contentfulClient = createToolClient(config, args);
|
|
6480
|
+
const current = await contentfulClient.fragment.get(params);
|
|
6481
|
+
if (args.version !== current.sys.version) {
|
|
6482
|
+
throw new Error(
|
|
6483
|
+
`Version conflict: the fragment has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the fragment with get_fragment and retry with the latest sys.version.`
|
|
6484
|
+
);
|
|
6485
|
+
}
|
|
6486
|
+
const fragment = await contentfulClient.fragment.publish({
|
|
6487
|
+
...params,
|
|
6488
|
+
version: args.version
|
|
6489
|
+
});
|
|
6490
|
+
return createSuccessResponse("Fragment published successfully", {
|
|
6491
|
+
fragment
|
|
6492
|
+
});
|
|
6493
|
+
}
|
|
6494
|
+
return withErrorHandling(tool2, "Error publishing fragment");
|
|
6495
|
+
}
|
|
6496
|
+
|
|
6497
|
+
// src/tools/exo/fragments/unpublishFragment.ts
|
|
6498
|
+
import { z as z96 } from "zod";
|
|
6499
|
+
var UnpublishFragmentToolParams = BaseToolSchema.extend({
|
|
6500
|
+
fragmentId: z96.string().describe("The ID of the fragment to unpublish"),
|
|
6501
|
+
version: z96.number().describe(
|
|
6502
|
+
"REQUIRED. The fragment's sys.version as returned by get_fragment. You must call get_fragment first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the fragment changed since you read it."
|
|
6503
|
+
)
|
|
6504
|
+
});
|
|
6505
|
+
function unpublishFragmentTool(config) {
|
|
6506
|
+
async function tool2(args) {
|
|
6507
|
+
assertEnvironmentNotProtected(
|
|
6508
|
+
args.environmentId,
|
|
6509
|
+
config.protectedEnvironments
|
|
6510
|
+
);
|
|
6511
|
+
const params = {
|
|
6512
|
+
spaceId: args.spaceId,
|
|
6513
|
+
environmentId: args.environmentId,
|
|
6514
|
+
fragmentId: args.fragmentId
|
|
6515
|
+
};
|
|
6516
|
+
const contentfulClient = createToolClient(config, args);
|
|
6517
|
+
const current = await contentfulClient.fragment.get(params);
|
|
6518
|
+
if (args.version !== current.sys.version) {
|
|
6519
|
+
throw new Error(
|
|
6520
|
+
`Version conflict: the fragment has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the fragment with get_fragment and retry with the latest sys.version.`
|
|
6521
|
+
);
|
|
6522
|
+
}
|
|
6523
|
+
const fragment = await contentfulClient.fragment.unpublish({
|
|
6524
|
+
...params,
|
|
6525
|
+
version: args.version
|
|
6526
|
+
});
|
|
6527
|
+
return createSuccessResponse("Fragment unpublished successfully", {
|
|
6528
|
+
fragment
|
|
6529
|
+
});
|
|
6530
|
+
}
|
|
6531
|
+
return withErrorHandling(tool2, "Error unpublishing fragment");
|
|
6532
|
+
}
|
|
6533
|
+
|
|
6534
|
+
// src/tools/exo/fragments/register.ts
|
|
6535
|
+
function createFragmentTools(config) {
|
|
6536
|
+
const getFragment = getFragmentTool(config);
|
|
6537
|
+
const listFragments = listFragmentsTool(config);
|
|
6538
|
+
const createFragment = createFragmentTool(config);
|
|
6539
|
+
const updateFragment = updateFragmentTool(config);
|
|
6540
|
+
const deleteFragment = deleteFragmentTool(config);
|
|
6541
|
+
const publishFragment = publishFragmentTool(config);
|
|
6542
|
+
const unpublishFragment = unpublishFragmentTool(config);
|
|
6543
|
+
return {
|
|
6544
|
+
getFragment: {
|
|
6545
|
+
title: "get_fragment",
|
|
6546
|
+
description: "Get details about a specific ExO fragment (a reusable content unit that can be referenced across multiple Experiences and ComponentTypes).",
|
|
6547
|
+
inputParams: GetFragmentToolParams.shape,
|
|
6548
|
+
annotations: {
|
|
6549
|
+
readOnlyHint: true,
|
|
6550
|
+
destructiveHint: false,
|
|
6551
|
+
openWorldHint: false
|
|
6552
|
+
},
|
|
6553
|
+
tool: getFragment
|
|
6554
|
+
},
|
|
6555
|
+
listFragments: {
|
|
6556
|
+
title: "list_fragments",
|
|
6557
|
+
description: "List ExO fragments in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
6558
|
+
inputParams: ListFragmentsToolParams.shape,
|
|
6559
|
+
annotations: {
|
|
6560
|
+
readOnlyHint: true,
|
|
6561
|
+
destructiveHint: false,
|
|
6562
|
+
openWorldHint: false
|
|
6563
|
+
},
|
|
6564
|
+
tool: listFragments
|
|
6565
|
+
},
|
|
6566
|
+
createFragment: {
|
|
6567
|
+
title: "create_fragment",
|
|
6568
|
+
description: "Create a new ExO fragment.",
|
|
6569
|
+
inputParams: CreateFragmentToolParams.shape,
|
|
6570
|
+
annotations: {
|
|
6571
|
+
readOnlyHint: false,
|
|
6572
|
+
destructiveHint: false,
|
|
6573
|
+
idempotentHint: false,
|
|
6574
|
+
openWorldHint: false
|
|
6575
|
+
},
|
|
6576
|
+
tool: createFragment
|
|
6577
|
+
},
|
|
6578
|
+
updateFragment: {
|
|
6579
|
+
title: "update_fragment",
|
|
6580
|
+
description: "Update an existing ExO fragment. You MUST call get_fragment first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing fragment fields, so you only need to provide the fields you want to change. If the version is stale (the fragment changed since you read it), the update is rejected and you must re-fetch with get_fragment.",
|
|
6581
|
+
inputParams: UpdateFragmentToolParams.shape,
|
|
6582
|
+
annotations: {
|
|
6583
|
+
readOnlyHint: false,
|
|
6584
|
+
destructiveHint: false,
|
|
6585
|
+
idempotentHint: false,
|
|
6586
|
+
openWorldHint: false
|
|
6587
|
+
},
|
|
6588
|
+
tool: updateFragment
|
|
6589
|
+
},
|
|
6590
|
+
deleteFragment: {
|
|
6591
|
+
title: "delete_fragment",
|
|
6592
|
+
description: "Delete an ExO fragment. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same fragmentId, confirm: true, and the confirmToken from the preview.",
|
|
6593
|
+
inputParams: DeleteFragmentToolParams.shape,
|
|
6594
|
+
annotations: {
|
|
6595
|
+
readOnlyHint: false,
|
|
6596
|
+
destructiveHint: true,
|
|
6597
|
+
idempotentHint: false,
|
|
6598
|
+
openWorldHint: false
|
|
6599
|
+
},
|
|
6600
|
+
tool: deleteFragment
|
|
6601
|
+
},
|
|
6602
|
+
publishFragment: {
|
|
6603
|
+
title: "publish_fragment",
|
|
6604
|
+
description: "Publish an ExO fragment. You MUST call get_fragment first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_fragment.",
|
|
6605
|
+
inputParams: PublishFragmentToolParams.shape,
|
|
6606
|
+
annotations: {
|
|
6607
|
+
readOnlyHint: false,
|
|
6608
|
+
destructiveHint: true,
|
|
6609
|
+
idempotentHint: true,
|
|
6610
|
+
openWorldHint: false
|
|
6611
|
+
},
|
|
6612
|
+
tool: publishFragment
|
|
6613
|
+
},
|
|
6614
|
+
unpublishFragment: {
|
|
6615
|
+
title: "unpublish_fragment",
|
|
6616
|
+
description: "Unpublish an ExO fragment. You MUST call get_fragment first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_fragment.",
|
|
6617
|
+
inputParams: UnpublishFragmentToolParams.shape,
|
|
6618
|
+
annotations: {
|
|
6619
|
+
readOnlyHint: false,
|
|
6620
|
+
destructiveHint: true,
|
|
6621
|
+
idempotentHint: true,
|
|
6622
|
+
openWorldHint: false
|
|
6623
|
+
},
|
|
6624
|
+
tool: unpublishFragment
|
|
6625
|
+
}
|
|
6626
|
+
};
|
|
6627
|
+
}
|
|
6628
|
+
|
|
6629
|
+
// src/tools/exo/templates/getTemplate.ts
|
|
6630
|
+
import { z as z97 } from "zod";
|
|
6631
|
+
var GetTemplateToolParams = BaseToolSchema.extend({
|
|
6632
|
+
templateId: z97.string().describe("The ID of the template to retrieve details for")
|
|
6633
|
+
});
|
|
6634
|
+
function getTemplateTool(config) {
|
|
6635
|
+
async function tool2(args) {
|
|
6636
|
+
const contentfulClient = createToolClient(config, args);
|
|
6637
|
+
const template = await contentfulClient.template.get({
|
|
6638
|
+
spaceId: args.spaceId,
|
|
6639
|
+
environmentId: args.environmentId,
|
|
6640
|
+
templateId: args.templateId
|
|
6641
|
+
});
|
|
6642
|
+
return createSuccessResponse("Template retrieved successfully", {
|
|
6643
|
+
template
|
|
6644
|
+
});
|
|
6645
|
+
}
|
|
6646
|
+
return withErrorHandling(tool2, "Error retrieving template");
|
|
6647
|
+
}
|
|
6648
|
+
|
|
6649
|
+
// src/tools/exo/templates/listTemplates.ts
|
|
6650
|
+
import { z as z98 } from "zod";
|
|
6651
|
+
var ListTemplatesToolParams = BaseToolSchema.extend({
|
|
6652
|
+
limit: z98.number().optional().describe("Maximum number of templates to return (max 10)"),
|
|
6653
|
+
pageNext: z98.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
6654
|
+
pagePrev: z98.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
6655
|
+
order: z98.string().optional().describe("Order templates by this field (e.g. sys.createdAt)")
|
|
6656
|
+
});
|
|
6657
|
+
function listTemplatesTool(config) {
|
|
6658
|
+
async function tool2(args) {
|
|
6659
|
+
const contentfulClient = createToolClient(config, args);
|
|
6660
|
+
const templates = await contentfulClient.template.getMany({
|
|
6661
|
+
spaceId: args.spaceId,
|
|
6662
|
+
environmentId: args.environmentId,
|
|
6663
|
+
query: {
|
|
6664
|
+
limit: Math.min(args.limit || 10, 10),
|
|
6665
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
6666
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
6667
|
+
...args.order && { order: args.order }
|
|
6668
|
+
}
|
|
6669
|
+
});
|
|
6670
|
+
const summarized = summarizeData(templates, {
|
|
6671
|
+
maxItems: 10,
|
|
6672
|
+
remainingMessage: "To see more templates, ask me to retrieve the next page using the pageNext cursor."
|
|
6673
|
+
});
|
|
6674
|
+
return createSuccessResponse("Templates retrieved successfully", {
|
|
6675
|
+
templates: summarized,
|
|
6676
|
+
total: templates.total,
|
|
6677
|
+
limit: templates.limit,
|
|
6678
|
+
pages: templates.pages
|
|
6679
|
+
});
|
|
6680
|
+
}
|
|
6681
|
+
return withErrorHandling(tool2, "Error listing templates");
|
|
6682
|
+
}
|
|
6683
|
+
|
|
6684
|
+
// src/tools/exo/templates/createTemplate.ts
|
|
6685
|
+
import { z as z99 } from "zod";
|
|
6686
|
+
var CreateTemplateToolParams = BaseToolSchema.extend({
|
|
6687
|
+
name: z99.string().describe("The name of the template"),
|
|
6688
|
+
description: z99.string().describe("Description of the template"),
|
|
6689
|
+
viewports: z99.array(ViewportSchema).describe("Viewport definitions for the template (may be empty)"),
|
|
6690
|
+
contentProperties: z99.array(ContentPropertySchema).describe("Content property definitions (may be empty)"),
|
|
6691
|
+
designProperties: z99.array(DesignPropertySchema).describe("Design property definitions (may be empty)"),
|
|
6692
|
+
componentTree: z99.array(TreeNodeSchema).optional().describe("Optional component tree node definitions"),
|
|
6693
|
+
slots: z99.array(SlotDefinitionSchema).optional().describe("Optional slot definitions"),
|
|
6694
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
6695
|
+
"Optional ExO metadata (tags, concepts)"
|
|
6696
|
+
)
|
|
6697
|
+
});
|
|
6698
|
+
function createTemplateTool(config) {
|
|
6699
|
+
async function tool2(args) {
|
|
6700
|
+
assertEnvironmentNotProtected(
|
|
6701
|
+
args.environmentId,
|
|
6702
|
+
config.protectedEnvironments
|
|
6703
|
+
);
|
|
6704
|
+
const contentfulClient = createToolClient(config, args);
|
|
6705
|
+
const template = await contentfulClient.template.create(
|
|
6706
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
6707
|
+
{
|
|
6708
|
+
name: args.name,
|
|
6709
|
+
description: args.description,
|
|
6710
|
+
viewports: args.viewports,
|
|
6711
|
+
contentProperties: args.contentProperties,
|
|
6712
|
+
designProperties: args.designProperties,
|
|
6713
|
+
...args.componentTree && { componentTree: args.componentTree },
|
|
6714
|
+
...args.slots && { slots: args.slots },
|
|
6715
|
+
...args.metadata && { metadata: args.metadata }
|
|
6716
|
+
}
|
|
6717
|
+
);
|
|
6718
|
+
return createSuccessResponse("Template created successfully", {
|
|
6719
|
+
template
|
|
6720
|
+
});
|
|
6721
|
+
}
|
|
6722
|
+
return withErrorHandling(tool2, "Error creating template");
|
|
6723
|
+
}
|
|
6724
|
+
|
|
6725
|
+
// src/tools/exo/templates/upsertTemplate.ts
|
|
6726
|
+
import { z as z100 } from "zod";
|
|
6727
|
+
var UpsertTemplateToolParams = BaseToolSchema.extend({
|
|
6728
|
+
templateId: z100.string().describe("The ID of the template to update"),
|
|
6729
|
+
version: z100.number().describe(
|
|
6730
|
+
"REQUIRED. The template's sys.version as returned by get_template. You must call get_template first to read the current state and version. The update is rejected if this does not match the current version, which means the template changed since you read it."
|
|
6731
|
+
),
|
|
6732
|
+
name: z100.string().optional().describe("The name of the template"),
|
|
6733
|
+
description: z100.string().optional().describe("Description of the template"),
|
|
6734
|
+
viewports: z100.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
6735
|
+
contentProperties: z100.array(ContentPropertySchema).optional().describe("Content property definitions; replaces existing if provided"),
|
|
6736
|
+
designProperties: z100.array(DesignPropertySchema).optional().describe("Design property definitions; replaces existing if provided"),
|
|
6737
|
+
componentTree: z100.array(TreeNodeSchema).optional().describe("Component tree node definitions; replaces existing if provided"),
|
|
6738
|
+
slots: z100.array(SlotDefinitionSchema).optional().describe("Slot definitions; replaces existing if provided"),
|
|
6739
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
6740
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
6741
|
+
)
|
|
6742
|
+
});
|
|
6743
|
+
function upsertTemplateTool(config) {
|
|
6744
|
+
async function tool2(args) {
|
|
6745
|
+
assertEnvironmentNotProtected(
|
|
6746
|
+
args.environmentId,
|
|
6747
|
+
config.protectedEnvironments
|
|
6748
|
+
);
|
|
6749
|
+
const params = {
|
|
6750
|
+
spaceId: args.spaceId,
|
|
6751
|
+
environmentId: args.environmentId,
|
|
6752
|
+
templateId: args.templateId
|
|
6753
|
+
};
|
|
6754
|
+
const contentfulClient = createToolClient(config, args);
|
|
6755
|
+
const current = await contentfulClient.template.get(params);
|
|
6756
|
+
if (args.version !== current.sys.version) {
|
|
6757
|
+
throw new Error(
|
|
6758
|
+
`Version conflict: the template has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the template with get_template and retry the update with the latest sys.version.`
|
|
6759
|
+
);
|
|
6760
|
+
}
|
|
6761
|
+
const template = await contentfulClient.template.upsert(params, {
|
|
6762
|
+
sys: {
|
|
6763
|
+
id: current.sys.id,
|
|
6764
|
+
type: "Template",
|
|
6765
|
+
version: current.sys.version
|
|
6766
|
+
},
|
|
6767
|
+
name: args.name ?? current.name,
|
|
6768
|
+
description: args.description ?? current.description,
|
|
6769
|
+
viewports: args.viewports ?? current.viewports,
|
|
6770
|
+
contentProperties: args.contentProperties ?? current.contentProperties,
|
|
6771
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
6772
|
+
...args.componentTree ?? current.componentTree ? { componentTree: args.componentTree ?? current.componentTree } : {},
|
|
6773
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
6774
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {},
|
|
6775
|
+
...current.dataAssemblies ? { dataAssemblies: current.dataAssemblies } : {}
|
|
6776
|
+
});
|
|
6777
|
+
return createSuccessResponse("Template updated successfully", {
|
|
6778
|
+
template
|
|
6779
|
+
});
|
|
6780
|
+
}
|
|
6781
|
+
return withErrorHandling(tool2, "Error updating template");
|
|
6782
|
+
}
|
|
6783
|
+
|
|
6784
|
+
// src/tools/exo/templates/deleteTemplate.ts
|
|
6785
|
+
import { z as z101 } from "zod";
|
|
6786
|
+
var DeleteTemplateToolParams = BaseToolSchema.extend({
|
|
6787
|
+
templateId: z101.string().describe("The ID of the template to delete"),
|
|
6788
|
+
confirm: z101.boolean().optional().describe(
|
|
6789
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
6790
|
+
),
|
|
6791
|
+
confirmToken: z101.string().optional().describe(
|
|
6792
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
6793
|
+
)
|
|
6794
|
+
});
|
|
6795
|
+
function deleteTemplateTool(config) {
|
|
6796
|
+
async function tool2(args) {
|
|
6797
|
+
assertEnvironmentNotProtected(
|
|
6798
|
+
args.environmentId,
|
|
6799
|
+
config.protectedEnvironments
|
|
6800
|
+
);
|
|
6801
|
+
const params = {
|
|
6802
|
+
spaceId: args.spaceId,
|
|
6803
|
+
environmentId: args.environmentId,
|
|
6804
|
+
templateId: args.templateId
|
|
6805
|
+
};
|
|
6806
|
+
const contentfulClient = createToolClient(config, args);
|
|
6807
|
+
const template = await contentfulClient.template.get(params);
|
|
6808
|
+
const expectedToken = buildConfirmToken(
|
|
6809
|
+
"template",
|
|
6810
|
+
args.templateId,
|
|
6811
|
+
template.sys.version
|
|
6812
|
+
);
|
|
6813
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
6814
|
+
return createSuccessResponse(
|
|
6815
|
+
`${CONFIRMATION_MESSAGE_PREFIX} template`,
|
|
6816
|
+
buildConfirmationPreview(
|
|
6817
|
+
"template",
|
|
6818
|
+
args.templateId,
|
|
6819
|
+
{ template },
|
|
6820
|
+
expectedToken
|
|
6821
|
+
)
|
|
6822
|
+
);
|
|
6823
|
+
}
|
|
6824
|
+
await contentfulClient.template.delete(params);
|
|
6825
|
+
return createSuccessResponse("Template deleted successfully", {
|
|
6826
|
+
templateId: args.templateId
|
|
6827
|
+
});
|
|
6828
|
+
}
|
|
6829
|
+
return withErrorHandling(tool2, "Error deleting template");
|
|
6830
|
+
}
|
|
6831
|
+
|
|
6832
|
+
// src/tools/exo/templates/publishTemplate.ts
|
|
6833
|
+
import { z as z102 } from "zod";
|
|
6834
|
+
var PublishTemplateToolParams = BaseToolSchema.extend({
|
|
6835
|
+
templateId: z102.string().describe("The ID of the template to publish"),
|
|
6836
|
+
version: z102.number().describe(
|
|
6837
|
+
"REQUIRED. The template's sys.version as returned by get_template. You must call get_template first to read the current state and version. The publish is rejected if this does not match the current version, which means the template changed since you read it."
|
|
6838
|
+
)
|
|
6839
|
+
});
|
|
6840
|
+
function publishTemplateTool(config) {
|
|
6841
|
+
async function tool2(args) {
|
|
6842
|
+
assertEnvironmentNotProtected(
|
|
6843
|
+
args.environmentId,
|
|
6844
|
+
config.protectedEnvironments
|
|
6845
|
+
);
|
|
6846
|
+
const params = {
|
|
6847
|
+
spaceId: args.spaceId,
|
|
6848
|
+
environmentId: args.environmentId,
|
|
6849
|
+
templateId: args.templateId
|
|
6850
|
+
};
|
|
6851
|
+
const contentfulClient = createToolClient(config, args);
|
|
6852
|
+
const current = await contentfulClient.template.get(params);
|
|
6853
|
+
if (args.version !== current.sys.version) {
|
|
6854
|
+
throw new Error(
|
|
6855
|
+
`Version conflict: the template has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the template with get_template and retry with the latest sys.version.`
|
|
6856
|
+
);
|
|
6857
|
+
}
|
|
6858
|
+
const template = await contentfulClient.template.publish({
|
|
6859
|
+
...params,
|
|
6860
|
+
version: args.version
|
|
6861
|
+
});
|
|
6862
|
+
return createSuccessResponse("Template published successfully", {
|
|
6863
|
+
template
|
|
6864
|
+
});
|
|
6865
|
+
}
|
|
6866
|
+
return withErrorHandling(tool2, "Error publishing template");
|
|
6867
|
+
}
|
|
6868
|
+
|
|
6869
|
+
// src/tools/exo/templates/unpublishTemplate.ts
|
|
6870
|
+
import { z as z103 } from "zod";
|
|
6871
|
+
var UnpublishTemplateToolParams = BaseToolSchema.extend({
|
|
6872
|
+
templateId: z103.string().describe("The ID of the template to unpublish"),
|
|
6873
|
+
version: z103.number().describe(
|
|
6874
|
+
"REQUIRED. The template's sys.version as returned by get_template. You must call get_template first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the template changed since you read it."
|
|
6875
|
+
)
|
|
6876
|
+
});
|
|
6877
|
+
function unpublishTemplateTool(config) {
|
|
6878
|
+
async function tool2(args) {
|
|
6879
|
+
assertEnvironmentNotProtected(
|
|
6880
|
+
args.environmentId,
|
|
6881
|
+
config.protectedEnvironments
|
|
6882
|
+
);
|
|
6883
|
+
const params = {
|
|
6884
|
+
spaceId: args.spaceId,
|
|
6885
|
+
environmentId: args.environmentId,
|
|
6886
|
+
templateId: args.templateId
|
|
6887
|
+
};
|
|
6888
|
+
const contentfulClient = createToolClient(config, args);
|
|
6889
|
+
const current = await contentfulClient.template.get(params);
|
|
6890
|
+
if (args.version !== current.sys.version) {
|
|
6891
|
+
throw new Error(
|
|
6892
|
+
`Version conflict: the template has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the template with get_template and retry with the latest sys.version.`
|
|
6893
|
+
);
|
|
6894
|
+
}
|
|
6895
|
+
const template = await contentfulClient.template.unpublish({
|
|
6896
|
+
...params,
|
|
6897
|
+
version: args.version
|
|
6898
|
+
});
|
|
6899
|
+
return createSuccessResponse("Template unpublished successfully", {
|
|
6900
|
+
template
|
|
6901
|
+
});
|
|
6902
|
+
}
|
|
6903
|
+
return withErrorHandling(tool2, "Error unpublishing template");
|
|
6904
|
+
}
|
|
6905
|
+
|
|
6906
|
+
// src/tools/exo/templates/register.ts
|
|
6907
|
+
function createTemplateTools(config) {
|
|
6908
|
+
const getTemplate = getTemplateTool(config);
|
|
6909
|
+
const listTemplates = listTemplatesTool(config);
|
|
6910
|
+
const createTemplate = createTemplateTool(config);
|
|
6911
|
+
const upsertTemplate = upsertTemplateTool(config);
|
|
6912
|
+
const deleteTemplate = deleteTemplateTool(config);
|
|
6913
|
+
const publishTemplate = publishTemplateTool(config);
|
|
6914
|
+
const unpublishTemplate = unpublishTemplateTool(config);
|
|
6915
|
+
return {
|
|
6916
|
+
getTemplate: {
|
|
6917
|
+
title: "get_template",
|
|
6918
|
+
description: "Get details about a specific ExO template (a layout definition that backs template-based Experiences).",
|
|
6919
|
+
inputParams: GetTemplateToolParams.shape,
|
|
6920
|
+
annotations: {
|
|
6921
|
+
readOnlyHint: true,
|
|
6922
|
+
destructiveHint: false,
|
|
6923
|
+
openWorldHint: false
|
|
6924
|
+
},
|
|
6925
|
+
tool: getTemplate
|
|
6926
|
+
},
|
|
6927
|
+
listTemplates: {
|
|
6928
|
+
title: "list_templates",
|
|
6929
|
+
description: "List ExO templates in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
6930
|
+
inputParams: ListTemplatesToolParams.shape,
|
|
6931
|
+
annotations: {
|
|
6932
|
+
readOnlyHint: true,
|
|
6933
|
+
destructiveHint: false,
|
|
6934
|
+
openWorldHint: false
|
|
6935
|
+
},
|
|
6936
|
+
tool: listTemplates
|
|
6937
|
+
},
|
|
6938
|
+
createTemplate: {
|
|
6939
|
+
title: "create_template",
|
|
6940
|
+
description: "Create a new ExO template.",
|
|
6941
|
+
inputParams: CreateTemplateToolParams.shape,
|
|
6942
|
+
annotations: {
|
|
6943
|
+
readOnlyHint: false,
|
|
6944
|
+
destructiveHint: false,
|
|
6945
|
+
idempotentHint: false,
|
|
6946
|
+
openWorldHint: false
|
|
6947
|
+
},
|
|
6948
|
+
tool: createTemplate
|
|
6949
|
+
},
|
|
6950
|
+
upsertTemplate: {
|
|
6951
|
+
title: "upsert_template",
|
|
6952
|
+
description: "Update an existing ExO template. You MUST call get_template first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing template fields, so you only need to provide the fields you want to change. If the version is stale (the template changed since you read it), the update is rejected and you must re-fetch with get_template.",
|
|
6953
|
+
inputParams: UpsertTemplateToolParams.shape,
|
|
6954
|
+
annotations: {
|
|
6955
|
+
readOnlyHint: false,
|
|
6956
|
+
destructiveHint: false,
|
|
6957
|
+
idempotentHint: false,
|
|
6958
|
+
openWorldHint: false
|
|
6959
|
+
},
|
|
6960
|
+
tool: upsertTemplate
|
|
6961
|
+
},
|
|
6962
|
+
deleteTemplate: {
|
|
6963
|
+
title: "delete_template",
|
|
6964
|
+
description: "Delete an ExO template. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same templateId, confirm: true, and the confirmToken from the preview.",
|
|
6965
|
+
inputParams: DeleteTemplateToolParams.shape,
|
|
6966
|
+
annotations: {
|
|
6967
|
+
readOnlyHint: false,
|
|
6968
|
+
destructiveHint: true,
|
|
6969
|
+
idempotentHint: false,
|
|
6970
|
+
openWorldHint: false
|
|
6971
|
+
},
|
|
6972
|
+
tool: deleteTemplate
|
|
6973
|
+
},
|
|
6974
|
+
publishTemplate: {
|
|
6975
|
+
title: "publish_template",
|
|
6976
|
+
description: "Publish an ExO template. You MUST call get_template first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_template.",
|
|
6977
|
+
inputParams: PublishTemplateToolParams.shape,
|
|
6978
|
+
annotations: {
|
|
6979
|
+
readOnlyHint: false,
|
|
6980
|
+
destructiveHint: true,
|
|
6981
|
+
idempotentHint: true,
|
|
6982
|
+
openWorldHint: false
|
|
6983
|
+
},
|
|
6984
|
+
tool: publishTemplate
|
|
6985
|
+
},
|
|
6986
|
+
unpublishTemplate: {
|
|
6987
|
+
title: "unpublish_template",
|
|
6988
|
+
description: "Unpublish an ExO template. You MUST call get_template first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_template.",
|
|
6989
|
+
inputParams: UnpublishTemplateToolParams.shape,
|
|
6990
|
+
annotations: {
|
|
6991
|
+
readOnlyHint: false,
|
|
6992
|
+
destructiveHint: true,
|
|
6993
|
+
idempotentHint: true,
|
|
6994
|
+
openWorldHint: false
|
|
6995
|
+
},
|
|
6996
|
+
tool: unpublishTemplate
|
|
6997
|
+
}
|
|
6998
|
+
};
|
|
6999
|
+
}
|
|
7000
|
+
|
|
7001
|
+
// src/tools/exo/experiences/getExperience.ts
|
|
7002
|
+
import { z as z104 } from "zod";
|
|
7003
|
+
var GetExperienceToolParams = BaseToolSchema.extend({
|
|
7004
|
+
experienceId: z104.string().describe("The ID of the experience to retrieve")
|
|
7005
|
+
});
|
|
7006
|
+
function getExperienceTool(config) {
|
|
7007
|
+
async function tool2(args) {
|
|
7008
|
+
const contentfulClient = createToolClient(config, args);
|
|
7009
|
+
const experience = await contentfulClient.experience.get({
|
|
7010
|
+
spaceId: args.spaceId,
|
|
7011
|
+
environmentId: args.environmentId,
|
|
7012
|
+
experienceId: args.experienceId
|
|
7013
|
+
});
|
|
7014
|
+
return createSuccessResponse("Experience retrieved successfully", {
|
|
7015
|
+
experience
|
|
7016
|
+
});
|
|
7017
|
+
}
|
|
7018
|
+
return withErrorHandling(tool2, "Error retrieving experience");
|
|
7019
|
+
}
|
|
7020
|
+
|
|
7021
|
+
// src/tools/exo/experiences/listExperiences.ts
|
|
7022
|
+
import { z as z105 } from "zod";
|
|
7023
|
+
var ListExperiencesToolParams = BaseToolSchema.extend({
|
|
7024
|
+
limit: z105.number().optional().describe("Maximum number of experiences to return (max 10)"),
|
|
7025
|
+
pageNext: z105.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
7026
|
+
pagePrev: z105.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
7027
|
+
order: z105.string().optional().describe("Order experiences by this field (e.g. sys.createdAt)")
|
|
7028
|
+
});
|
|
7029
|
+
function listExperiencesTool(config) {
|
|
7030
|
+
async function tool2(args) {
|
|
7031
|
+
const contentfulClient = createToolClient(config, args);
|
|
7032
|
+
const experiences = await contentfulClient.experience.getMany({
|
|
7033
|
+
spaceId: args.spaceId,
|
|
7034
|
+
environmentId: args.environmentId,
|
|
7035
|
+
query: {
|
|
7036
|
+
limit: Math.min(args.limit || 10, 10),
|
|
7037
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
7038
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
7039
|
+
...args.order && { order: args.order }
|
|
7040
|
+
}
|
|
7041
|
+
});
|
|
7042
|
+
const summarized = summarizeData(experiences, {
|
|
7043
|
+
maxItems: 10,
|
|
7044
|
+
remainingMessage: "To see more experiences, ask me to retrieve the next page using the pageNext cursor."
|
|
7045
|
+
});
|
|
7046
|
+
return createSuccessResponse("Experiences retrieved successfully", {
|
|
7047
|
+
experiences: summarized,
|
|
7048
|
+
total: experiences.total,
|
|
7049
|
+
limit: experiences.limit,
|
|
7050
|
+
pages: experiences.pages
|
|
7051
|
+
});
|
|
7052
|
+
}
|
|
7053
|
+
return withErrorHandling(tool2, "Error listing experiences");
|
|
7054
|
+
}
|
|
7055
|
+
|
|
7056
|
+
// src/tools/exo/experiences/createExperience.ts
|
|
7057
|
+
import { z as z106 } from "zod";
|
|
7058
|
+
var TemplateResourceLinkSchema = z106.object({
|
|
7059
|
+
sys: z106.object({
|
|
7060
|
+
type: z106.literal("ResourceLink"),
|
|
7061
|
+
linkType: z106.literal("Contentful:Template"),
|
|
7062
|
+
urn: z106.string().describe("URN of the linked resource")
|
|
7063
|
+
})
|
|
7064
|
+
});
|
|
7065
|
+
var CreateExperienceToolParams = BaseToolSchema.extend({
|
|
7066
|
+
name: z106.string().describe("The name of the experience"),
|
|
7067
|
+
description: z106.string().describe("Description of the experience"),
|
|
7068
|
+
template: TemplateResourceLinkSchema.describe(
|
|
7069
|
+
"Resource link to the Template this experience is backed by"
|
|
7070
|
+
),
|
|
7071
|
+
viewports: z106.array(ViewportSchema).describe("Viewport definitions for the experience (may be empty)"),
|
|
7072
|
+
designProperties: z106.record(z106.string(), DimensionedDesignPropertyValueSchema).describe(
|
|
7073
|
+
"Design property values keyed by property ID. Each value is a dimensioned map (viewport ID \u2192 design value). May be an empty object."
|
|
7074
|
+
),
|
|
7075
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
7076
|
+
"Optional content bindings linking this experience to a data assembly"
|
|
7077
|
+
),
|
|
7078
|
+
slots: z106.record(z106.string(), z106.array(ExperienceSlotNodeSchema)).optional().describe(
|
|
7079
|
+
"Optional slot contents keyed by slot ID. Each value is an array of FragmentNode or InlineFragmentNode."
|
|
7080
|
+
),
|
|
7081
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
7082
|
+
"Optional ExO metadata (tags, concepts)"
|
|
7083
|
+
)
|
|
7084
|
+
});
|
|
7085
|
+
function createExperienceTool(config) {
|
|
7086
|
+
async function tool2(args) {
|
|
7087
|
+
assertEnvironmentNotProtected(
|
|
7088
|
+
args.environmentId,
|
|
7089
|
+
config.protectedEnvironments
|
|
7090
|
+
);
|
|
7091
|
+
const contentfulClient = createToolClient(config, args);
|
|
7092
|
+
const experience = await contentfulClient.experience.create(
|
|
7093
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
7094
|
+
{
|
|
7095
|
+
name: args.name,
|
|
7096
|
+
description: args.description,
|
|
7097
|
+
template: args.template,
|
|
7098
|
+
viewports: args.viewports,
|
|
7099
|
+
designProperties: args.designProperties,
|
|
7100
|
+
...args.contentBindings && { contentBindings: args.contentBindings },
|
|
7101
|
+
...args.slots && { slots: args.slots },
|
|
7102
|
+
...args.metadata && { metadata: args.metadata }
|
|
7103
|
+
}
|
|
7104
|
+
);
|
|
7105
|
+
return createSuccessResponse("Experience created successfully", {
|
|
7106
|
+
experience
|
|
7107
|
+
});
|
|
7108
|
+
}
|
|
7109
|
+
return withErrorHandling(tool2, "Error creating experience");
|
|
7110
|
+
}
|
|
7111
|
+
|
|
7112
|
+
// src/tools/exo/experiences/upsertExperience.ts
|
|
7113
|
+
import { z as z107 } from "zod";
|
|
7114
|
+
var UpsertExperienceToolParams = BaseToolSchema.extend({
|
|
7115
|
+
experienceId: z107.string().describe("The ID of the experience to update"),
|
|
7116
|
+
version: z107.number().describe(
|
|
7117
|
+
"REQUIRED. The experience's sys.version as returned by get_experience. You must call get_experience first to read the current state and version. The update is rejected if this does not match the current version, which means the experience changed since you read it."
|
|
7118
|
+
),
|
|
7119
|
+
name: z107.string().optional().describe("The name of the experience"),
|
|
7120
|
+
description: z107.string().optional().describe("Description of the experience"),
|
|
7121
|
+
viewports: z107.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
7122
|
+
designProperties: z107.record(z107.string(), DimensionedDesignPropertyValueSchema).optional().describe(
|
|
7123
|
+
"Design property values keyed by property ID; replaces existing if provided"
|
|
7124
|
+
),
|
|
7125
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
7126
|
+
"Content bindings linking this experience to a data assembly; replaces existing if provided"
|
|
7127
|
+
),
|
|
7128
|
+
slots: z107.record(z107.string(), z107.array(ExperienceSlotNodeSchema)).optional().describe(
|
|
7129
|
+
"Slot contents keyed by slot ID; replaces existing if provided"
|
|
7130
|
+
),
|
|
7131
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
7132
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
7133
|
+
)
|
|
7134
|
+
});
|
|
7135
|
+
function upsertExperienceTool(config) {
|
|
7136
|
+
async function tool2(args) {
|
|
7137
|
+
assertEnvironmentNotProtected(
|
|
7138
|
+
args.environmentId,
|
|
7139
|
+
config.protectedEnvironments
|
|
7140
|
+
);
|
|
7141
|
+
const params = {
|
|
7142
|
+
spaceId: args.spaceId,
|
|
7143
|
+
environmentId: args.environmentId,
|
|
7144
|
+
experienceId: args.experienceId
|
|
7145
|
+
};
|
|
7146
|
+
const contentfulClient = createToolClient(config, args);
|
|
7147
|
+
const current = await contentfulClient.experience.get(params);
|
|
7148
|
+
if (args.version !== current.sys.version) {
|
|
7149
|
+
throw new Error(
|
|
7150
|
+
`Version conflict: the experience has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience with get_experience and retry the update with the latest sys.version.`
|
|
7151
|
+
);
|
|
7152
|
+
}
|
|
7153
|
+
const experience = await contentfulClient.experience.upsert(params, {
|
|
7154
|
+
sys: {
|
|
7155
|
+
id: current.sys.id,
|
|
7156
|
+
type: "Experience",
|
|
7157
|
+
version: current.sys.version
|
|
7158
|
+
},
|
|
7159
|
+
name: args.name ?? current.name,
|
|
7160
|
+
description: args.description ?? current.description,
|
|
7161
|
+
viewports: args.viewports ?? current.viewports,
|
|
7162
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
7163
|
+
...args.contentBindings ?? current.contentBindings ? { contentBindings: args.contentBindings ?? current.contentBindings } : {},
|
|
7164
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
7165
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {}
|
|
7166
|
+
});
|
|
7167
|
+
return createSuccessResponse("Experience updated successfully", {
|
|
7168
|
+
experience
|
|
7169
|
+
});
|
|
7170
|
+
}
|
|
7171
|
+
return withErrorHandling(tool2, "Error updating experience");
|
|
7172
|
+
}
|
|
7173
|
+
|
|
7174
|
+
// src/tools/exo/experiences/deleteExperience.ts
|
|
7175
|
+
import { z as z108 } from "zod";
|
|
7176
|
+
var DeleteExperienceToolParams = BaseToolSchema.extend({
|
|
7177
|
+
experienceId: z108.string().describe("The ID of the experience to delete"),
|
|
7178
|
+
confirm: z108.boolean().optional().describe(
|
|
7179
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
7180
|
+
),
|
|
7181
|
+
confirmToken: z108.string().optional().describe(
|
|
7182
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
7183
|
+
)
|
|
7184
|
+
});
|
|
7185
|
+
function deleteExperienceTool(config) {
|
|
7186
|
+
async function tool2(args) {
|
|
7187
|
+
assertEnvironmentNotProtected(
|
|
7188
|
+
args.environmentId,
|
|
7189
|
+
config.protectedEnvironments
|
|
7190
|
+
);
|
|
7191
|
+
const params = {
|
|
7192
|
+
spaceId: args.spaceId,
|
|
7193
|
+
environmentId: args.environmentId,
|
|
7194
|
+
experienceId: args.experienceId
|
|
7195
|
+
};
|
|
7196
|
+
const contentfulClient = createToolClient(config, args);
|
|
7197
|
+
const experience = await contentfulClient.experience.get(params);
|
|
7198
|
+
const expectedToken = buildConfirmToken(
|
|
7199
|
+
"experience",
|
|
7200
|
+
args.experienceId,
|
|
7201
|
+
experience.sys.version
|
|
7202
|
+
);
|
|
7203
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
7204
|
+
return createSuccessResponse(
|
|
7205
|
+
`${CONFIRMATION_MESSAGE_PREFIX} experience`,
|
|
7206
|
+
buildConfirmationPreview(
|
|
7207
|
+
"experience",
|
|
7208
|
+
args.experienceId,
|
|
7209
|
+
{ experience },
|
|
7210
|
+
expectedToken
|
|
7211
|
+
)
|
|
7212
|
+
);
|
|
7213
|
+
}
|
|
7214
|
+
await contentfulClient.experience.delete(params);
|
|
7215
|
+
return createSuccessResponse("Experience deleted successfully", {
|
|
7216
|
+
experienceId: args.experienceId
|
|
7217
|
+
});
|
|
7218
|
+
}
|
|
7219
|
+
return withErrorHandling(tool2, "Error deleting experience");
|
|
7220
|
+
}
|
|
7221
|
+
|
|
7222
|
+
// src/tools/exo/experiences/publishExperience.ts
|
|
7223
|
+
import { z as z109 } from "zod";
|
|
7224
|
+
var PublishExperienceToolParams = BaseToolSchema.extend({
|
|
7225
|
+
experienceId: z109.string().describe("The ID of the experience to publish"),
|
|
7226
|
+
version: z109.number().describe(
|
|
7227
|
+
"REQUIRED. The experience's sys.version as returned by get_experience. You must call get_experience first to read the current state and version. The publish is rejected if this does not match the current version, which means the experience changed since you read it."
|
|
7228
|
+
)
|
|
7229
|
+
});
|
|
7230
|
+
function publishExperienceTool(config) {
|
|
7231
|
+
async function tool2(args) {
|
|
7232
|
+
assertEnvironmentNotProtected(
|
|
7233
|
+
args.environmentId,
|
|
7234
|
+
config.protectedEnvironments
|
|
7235
|
+
);
|
|
7236
|
+
const params = {
|
|
7237
|
+
spaceId: args.spaceId,
|
|
7238
|
+
environmentId: args.environmentId,
|
|
7239
|
+
experienceId: args.experienceId
|
|
7240
|
+
};
|
|
7241
|
+
const contentfulClient = createToolClient(config, args);
|
|
7242
|
+
const current = await contentfulClient.experience.get(params);
|
|
7243
|
+
if (args.version !== current.sys.version) {
|
|
7244
|
+
throw new Error(
|
|
7245
|
+
`Version conflict: the experience has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience with get_experience and retry with the latest sys.version.`
|
|
7246
|
+
);
|
|
7247
|
+
}
|
|
7248
|
+
const experience = await contentfulClient.experience.publish({
|
|
7249
|
+
...params,
|
|
7250
|
+
version: args.version
|
|
7251
|
+
});
|
|
7252
|
+
return createSuccessResponse("Experience published successfully", {
|
|
7253
|
+
experience
|
|
7254
|
+
});
|
|
7255
|
+
}
|
|
7256
|
+
return withErrorHandling(tool2, "Error publishing experience");
|
|
7257
|
+
}
|
|
7258
|
+
|
|
7259
|
+
// src/tools/exo/experiences/unpublishExperience.ts
|
|
7260
|
+
import { z as z110 } from "zod";
|
|
7261
|
+
var UnpublishExperienceToolParams = BaseToolSchema.extend({
|
|
7262
|
+
experienceId: z110.string().describe("The ID of the experience to unpublish"),
|
|
7263
|
+
version: z110.number().describe(
|
|
7264
|
+
"REQUIRED. The experience's sys.version as returned by get_experience. You must call get_experience first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the experience changed since you read it."
|
|
7265
|
+
)
|
|
7266
|
+
});
|
|
7267
|
+
function unpublishExperienceTool(config) {
|
|
7268
|
+
async function tool2(args) {
|
|
7269
|
+
assertEnvironmentNotProtected(
|
|
7270
|
+
args.environmentId,
|
|
7271
|
+
config.protectedEnvironments
|
|
7272
|
+
);
|
|
7273
|
+
const params = {
|
|
7274
|
+
spaceId: args.spaceId,
|
|
7275
|
+
environmentId: args.environmentId,
|
|
7276
|
+
experienceId: args.experienceId
|
|
7277
|
+
};
|
|
7278
|
+
const contentfulClient = createToolClient(config, args);
|
|
7279
|
+
const current = await contentfulClient.experience.get(params);
|
|
7280
|
+
if (args.version !== current.sys.version) {
|
|
7281
|
+
throw new Error(
|
|
7282
|
+
`Version conflict: the experience has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience with get_experience and retry with the latest sys.version.`
|
|
7283
|
+
);
|
|
7284
|
+
}
|
|
7285
|
+
const experience = await contentfulClient.experience.unpublish({
|
|
7286
|
+
...params,
|
|
7287
|
+
version: args.version
|
|
7288
|
+
});
|
|
7289
|
+
return createSuccessResponse("Experience unpublished successfully", {
|
|
7290
|
+
experience
|
|
7291
|
+
});
|
|
7292
|
+
}
|
|
7293
|
+
return withErrorHandling(tool2, "Error unpublishing experience");
|
|
7294
|
+
}
|
|
7295
|
+
|
|
7296
|
+
// src/tools/exo/experiences/register.ts
|
|
7297
|
+
function createExperienceTools(config) {
|
|
7298
|
+
const getExperience = getExperienceTool(config);
|
|
7299
|
+
const listExperiences = listExperiencesTool(config);
|
|
7300
|
+
const createExperience = createExperienceTool(config);
|
|
7301
|
+
const upsertExperience = upsertExperienceTool(config);
|
|
7302
|
+
const deleteExperience = deleteExperienceTool(config);
|
|
7303
|
+
const publishExperience = publishExperienceTool(config);
|
|
7304
|
+
const unpublishExperience = unpublishExperienceTool(config);
|
|
7305
|
+
return {
|
|
7306
|
+
getExperience: {
|
|
7307
|
+
title: "get_experience",
|
|
7308
|
+
description: "Get details about a specific ExO experience (a concrete page or screen that composes a root ComponentType with content and design settings, backed by a Template).",
|
|
7309
|
+
inputParams: GetExperienceToolParams.shape,
|
|
7310
|
+
annotations: {
|
|
7311
|
+
readOnlyHint: true,
|
|
7312
|
+
destructiveHint: false,
|
|
7313
|
+
openWorldHint: false
|
|
7314
|
+
},
|
|
7315
|
+
tool: getExperience
|
|
7316
|
+
},
|
|
7317
|
+
listExperiences: {
|
|
7318
|
+
title: "list_experiences",
|
|
7319
|
+
description: "List ExO experiences in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
7320
|
+
inputParams: ListExperiencesToolParams.shape,
|
|
7321
|
+
annotations: {
|
|
7322
|
+
readOnlyHint: true,
|
|
7323
|
+
destructiveHint: false,
|
|
7324
|
+
openWorldHint: false
|
|
7325
|
+
},
|
|
7326
|
+
tool: listExperiences
|
|
7327
|
+
},
|
|
7328
|
+
createExperience: {
|
|
7329
|
+
title: "create_experience",
|
|
7330
|
+
description: "Create a new ExO experience backed by a Template.",
|
|
7331
|
+
inputParams: CreateExperienceToolParams.shape,
|
|
7332
|
+
annotations: {
|
|
7333
|
+
readOnlyHint: false,
|
|
7334
|
+
destructiveHint: false,
|
|
7335
|
+
idempotentHint: false,
|
|
7336
|
+
openWorldHint: false
|
|
7337
|
+
},
|
|
7338
|
+
tool: createExperience
|
|
7339
|
+
},
|
|
7340
|
+
upsertExperience: {
|
|
7341
|
+
title: "upsert_experience",
|
|
7342
|
+
description: "Update an existing ExO experience. You MUST call get_experience first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing experience fields, so you only need to provide the fields you want to change. If the version is stale (the experience changed since you read it), the update is rejected and you must re-fetch with get_experience.",
|
|
7343
|
+
inputParams: UpsertExperienceToolParams.shape,
|
|
7344
|
+
annotations: {
|
|
7345
|
+
readOnlyHint: false,
|
|
7346
|
+
destructiveHint: false,
|
|
7347
|
+
idempotentHint: false,
|
|
7348
|
+
openWorldHint: false
|
|
7349
|
+
},
|
|
7350
|
+
tool: upsertExperience
|
|
7351
|
+
},
|
|
7352
|
+
deleteExperience: {
|
|
7353
|
+
title: "delete_experience",
|
|
7354
|
+
description: "Delete an ExO experience. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same experienceId, confirm: true, and the confirmToken from the preview.",
|
|
7355
|
+
inputParams: DeleteExperienceToolParams.shape,
|
|
7356
|
+
annotations: {
|
|
7357
|
+
readOnlyHint: false,
|
|
7358
|
+
destructiveHint: true,
|
|
7359
|
+
idempotentHint: false,
|
|
7360
|
+
openWorldHint: false
|
|
7361
|
+
},
|
|
7362
|
+
tool: deleteExperience
|
|
7363
|
+
},
|
|
7364
|
+
publishExperience: {
|
|
7365
|
+
title: "publish_experience",
|
|
7366
|
+
description: "Publish an ExO experience. You MUST call get_experience first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience.",
|
|
7367
|
+
inputParams: PublishExperienceToolParams.shape,
|
|
7368
|
+
annotations: {
|
|
7369
|
+
readOnlyHint: false,
|
|
7370
|
+
destructiveHint: true,
|
|
7371
|
+
idempotentHint: true,
|
|
7372
|
+
openWorldHint: false
|
|
7373
|
+
},
|
|
7374
|
+
tool: publishExperience
|
|
7375
|
+
},
|
|
7376
|
+
unpublishExperience: {
|
|
7377
|
+
title: "unpublish_experience",
|
|
7378
|
+
description: "Unpublish an ExO experience. You MUST call get_experience first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience.",
|
|
7379
|
+
inputParams: UnpublishExperienceToolParams.shape,
|
|
7380
|
+
annotations: {
|
|
7381
|
+
readOnlyHint: false,
|
|
7382
|
+
destructiveHint: true,
|
|
7383
|
+
idempotentHint: true,
|
|
7384
|
+
openWorldHint: false
|
|
7385
|
+
},
|
|
7386
|
+
tool: unpublishExperience
|
|
7387
|
+
}
|
|
7388
|
+
};
|
|
7389
|
+
}
|
|
7390
|
+
|
|
7391
|
+
// src/tools/exo/data-assemblies/getDataAssembly.ts
|
|
7392
|
+
import { z as z111 } from "zod";
|
|
7393
|
+
var GetDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7394
|
+
dataAssemblyId: z111.string().describe("The ID of the data assembly to retrieve")
|
|
7395
|
+
});
|
|
7396
|
+
function getDataAssemblyTool(config) {
|
|
7397
|
+
async function tool2(args) {
|
|
7398
|
+
const contentfulClient = createToolClient(config, args);
|
|
7399
|
+
const dataAssembly = await contentfulClient.dataAssembly.get({
|
|
7400
|
+
spaceId: args.spaceId,
|
|
7401
|
+
environmentId: args.environmentId,
|
|
7402
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7403
|
+
});
|
|
7404
|
+
return createSuccessResponse("Data assembly retrieved successfully", {
|
|
7405
|
+
dataAssembly
|
|
7406
|
+
});
|
|
7407
|
+
}
|
|
7408
|
+
return withErrorHandling(tool2, "Error retrieving data assembly");
|
|
7409
|
+
}
|
|
7410
|
+
|
|
7411
|
+
// src/tools/exo/data-assemblies/getPublishedDataAssembly.ts
|
|
7412
|
+
import { z as z112 } from "zod";
|
|
7413
|
+
var GetPublishedDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7414
|
+
dataAssemblyId: z112.string().describe("The ID of the published data assembly to retrieve")
|
|
7415
|
+
});
|
|
7416
|
+
function getPublishedDataAssemblyTool(config) {
|
|
7417
|
+
async function tool2(args) {
|
|
7418
|
+
const contentfulClient = createToolClient(config, args);
|
|
7419
|
+
const dataAssembly = await contentfulClient.dataAssembly.getPublished({
|
|
7420
|
+
spaceId: args.spaceId,
|
|
7421
|
+
environmentId: args.environmentId,
|
|
7422
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7423
|
+
});
|
|
7424
|
+
return createSuccessResponse("Published data assembly retrieved successfully", {
|
|
7425
|
+
dataAssembly
|
|
7426
|
+
});
|
|
7427
|
+
}
|
|
7428
|
+
return withErrorHandling(tool2, "Error retrieving published data assembly");
|
|
7429
|
+
}
|
|
7430
|
+
|
|
7431
|
+
// src/tools/exo/data-assemblies/listDataAssemblies.ts
|
|
7432
|
+
import { z as z113 } from "zod";
|
|
7433
|
+
var ListDataAssembliesToolParams = BaseToolSchema.extend({
|
|
7434
|
+
limit: z113.number().optional().describe("Maximum number of data assemblies to return (max 10)"),
|
|
7435
|
+
pageNext: z113.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
7436
|
+
pagePrev: z113.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
7437
|
+
sysIdIn: z113.string().optional().describe("Comma-separated list of data assembly IDs to filter by")
|
|
7438
|
+
});
|
|
7439
|
+
function listDataAssembliesTool(config) {
|
|
7440
|
+
async function tool2(args) {
|
|
7441
|
+
const contentfulClient = createToolClient(config, args);
|
|
7442
|
+
const dataAssemblies = await contentfulClient.dataAssembly.getMany({
|
|
7443
|
+
spaceId: args.spaceId,
|
|
7444
|
+
environmentId: args.environmentId,
|
|
7445
|
+
query: {
|
|
7446
|
+
limit: Math.min(args.limit || 10, 10),
|
|
7447
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
7448
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
7449
|
+
...args.sysIdIn && { "sys.id[in]": args.sysIdIn }
|
|
7450
|
+
}
|
|
7451
|
+
});
|
|
7452
|
+
const summarized = summarizeData(dataAssemblies, {
|
|
7453
|
+
maxItems: 10,
|
|
7454
|
+
remainingMessage: "To see more data assemblies, ask me to retrieve the next page using the pageNext cursor."
|
|
7455
|
+
});
|
|
7456
|
+
return createSuccessResponse("Data assemblies retrieved successfully", {
|
|
7457
|
+
dataAssemblies: summarized,
|
|
7458
|
+
total: dataAssemblies.total,
|
|
7459
|
+
pages: dataAssemblies.pages
|
|
7460
|
+
});
|
|
7461
|
+
}
|
|
7462
|
+
return withErrorHandling(tool2, "Error listing data assemblies");
|
|
7463
|
+
}
|
|
7464
|
+
|
|
7465
|
+
// src/tools/exo/data-assemblies/listPublishedDataAssemblies.ts
|
|
7466
|
+
import { z as z114 } from "zod";
|
|
7467
|
+
var ListPublishedDataAssembliesToolParams = BaseToolSchema.extend({
|
|
7468
|
+
limit: z114.number().optional().describe("Maximum number of published data assemblies to return (max 10)"),
|
|
7469
|
+
pageNext: z114.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
7470
|
+
pagePrev: z114.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
7471
|
+
sysIdIn: z114.string().optional().describe("Comma-separated list of data assembly IDs to filter by")
|
|
7472
|
+
});
|
|
7473
|
+
function listPublishedDataAssembliesTool(config) {
|
|
7474
|
+
async function tool2(args) {
|
|
7475
|
+
const contentfulClient = createToolClient(config, args);
|
|
7476
|
+
const dataAssemblies = await contentfulClient.dataAssembly.getManyPublished({
|
|
7477
|
+
spaceId: args.spaceId,
|
|
7478
|
+
environmentId: args.environmentId,
|
|
7479
|
+
query: {
|
|
7480
|
+
limit: Math.min(args.limit || 10, 10),
|
|
7481
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
7482
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
7483
|
+
...args.sysIdIn && { "sys.id[in]": args.sysIdIn }
|
|
7484
|
+
}
|
|
7485
|
+
});
|
|
7486
|
+
const summarized = summarizeData(dataAssemblies, {
|
|
7487
|
+
maxItems: 10,
|
|
7488
|
+
remainingMessage: "To see more published data assemblies, ask me to retrieve the next page using the pageNext cursor."
|
|
7489
|
+
});
|
|
7490
|
+
return createSuccessResponse("Published data assemblies retrieved successfully", {
|
|
7491
|
+
dataAssemblies: summarized,
|
|
7492
|
+
total: dataAssemblies.total,
|
|
7493
|
+
pages: dataAssemblies.pages
|
|
7494
|
+
});
|
|
7495
|
+
}
|
|
7496
|
+
return withErrorHandling(tool2, "Error listing published data assemblies");
|
|
7497
|
+
}
|
|
7498
|
+
|
|
7499
|
+
// src/tools/exo/data-assemblies/createDataAssembly.ts
|
|
7500
|
+
import { z as z116 } from "zod";
|
|
7501
|
+
|
|
7502
|
+
// src/types/dataAssemblySchemas.ts
|
|
7503
|
+
import { z as z115 } from "zod";
|
|
7504
|
+
var PointerExpressionValueSchema = z115.lazy(
|
|
7505
|
+
() => z115.union([
|
|
7506
|
+
z115.string(),
|
|
7507
|
+
z115.object({
|
|
7508
|
+
$from: z115.union([
|
|
7509
|
+
z115.string(),
|
|
7510
|
+
z115.object({
|
|
7511
|
+
source: z115.string(),
|
|
7512
|
+
select: PointerExpressionValueSchema.optional()
|
|
7513
|
+
})
|
|
7514
|
+
])
|
|
7515
|
+
}),
|
|
7516
|
+
z115.object({ $literal: z115.custom() }),
|
|
7517
|
+
z115.object({ $object: z115.record(z115.string(), PointerExpressionValueSchema) }),
|
|
7518
|
+
z115.object({
|
|
7519
|
+
$on: z115.object({
|
|
7520
|
+
type: z115.record(z115.string(), PointerExpressionValueSchema),
|
|
7521
|
+
default: PointerExpressionValueSchema.optional()
|
|
7522
|
+
})
|
|
7523
|
+
}),
|
|
7524
|
+
z115.record(z115.string(), PointerExpressionValueSchema)
|
|
7525
|
+
])
|
|
7526
|
+
);
|
|
7527
|
+
var CanonicalDataTypeArmSchema = z115.object({
|
|
7528
|
+
type: z115.enum([
|
|
7529
|
+
"String",
|
|
7530
|
+
"Number",
|
|
7531
|
+
"Integer",
|
|
7532
|
+
"Boolean",
|
|
7533
|
+
"RichText",
|
|
7534
|
+
"Array",
|
|
7535
|
+
"Record",
|
|
7536
|
+
"TypeRef",
|
|
7537
|
+
"Literal",
|
|
7538
|
+
"DiscriminatedUnion"
|
|
7539
|
+
]),
|
|
7540
|
+
id: z115.string().describe("Data type field identifier"),
|
|
7541
|
+
name: z115.string().describe("Human-readable name"),
|
|
7542
|
+
required: z115.boolean().optional()
|
|
7543
|
+
}).catchall(z115.unknown());
|
|
7544
|
+
var LegacyDataTypeArmSchema = z115.object({
|
|
7545
|
+
id: z115.string().describe("Data type field identifier"),
|
|
7546
|
+
name: z115.string().describe("Human-readable name"),
|
|
7547
|
+
type: z115.string(),
|
|
7548
|
+
required: z115.boolean().optional(),
|
|
7549
|
+
source: z115.string().optional(),
|
|
7550
|
+
ref: z115.unknown().optional()
|
|
7551
|
+
});
|
|
7552
|
+
var DataAssemblyDataTypeFieldSchema = z115.union([
|
|
7553
|
+
CanonicalDataTypeArmSchema,
|
|
7554
|
+
LegacyDataTypeArmSchema
|
|
7555
|
+
]);
|
|
7556
|
+
var SAME_SPACE_CONTENT_SOURCE = "crn:contentful:::content:spaces/$self/environments/$self";
|
|
7557
|
+
var DataAssemblyResourceLinkParameterSchema = z115.object({
|
|
7558
|
+
name: z115.string().optional(),
|
|
7559
|
+
description: z115.string().optional(),
|
|
7560
|
+
type: z115.literal("ResourceLink"),
|
|
7561
|
+
linkType: z115.literal("Contentful:Entry"),
|
|
7562
|
+
allowedResources: z115.array(
|
|
7563
|
+
z115.object({
|
|
7564
|
+
type: z115.literal("Contentful:Entry"),
|
|
7565
|
+
source: z115.literal(SAME_SPACE_CONTENT_SOURCE),
|
|
7566
|
+
allowedTypes: z115.array(z115.string())
|
|
7567
|
+
})
|
|
7568
|
+
)
|
|
7569
|
+
});
|
|
7570
|
+
var DataAssemblyParameterConfigSchema = z115.record(
|
|
7571
|
+
z115.string(),
|
|
7572
|
+
DataAssemblyResourceLinkParameterSchema
|
|
7573
|
+
);
|
|
7574
|
+
var DataAssemblyGraphQLResolverSchema = z115.object({
|
|
7575
|
+
source: z115.literal("Contentful:GraphQL"),
|
|
7576
|
+
query: z115.string().describe("GraphQL query string"),
|
|
7577
|
+
parameters: PointerExpressionValueSchema.optional()
|
|
7578
|
+
});
|
|
7579
|
+
var DataAssemblyNestedResolverSchema = z115.object({
|
|
7580
|
+
source: z115.literal("Contentful:DataAssembly"),
|
|
7581
|
+
dataAssembly: z115.object({
|
|
7582
|
+
sys: z115.object({
|
|
7583
|
+
type: z115.literal("ResourceLink"),
|
|
7584
|
+
linkType: z115.literal("Contentful:DataAssembly"),
|
|
7585
|
+
urn: z115.string()
|
|
7586
|
+
})
|
|
7587
|
+
}),
|
|
7588
|
+
parameters: PointerExpressionValueSchema.optional()
|
|
7589
|
+
});
|
|
7590
|
+
var DataAssemblyResolverDefinitionSchema = z115.union([
|
|
7591
|
+
DataAssemblyGraphQLResolverSchema,
|
|
7592
|
+
DataAssemblyNestedResolverSchema
|
|
7593
|
+
]);
|
|
7594
|
+
var DataAssemblyResolverConfigSchema = z115.record(
|
|
7595
|
+
z115.string(),
|
|
7596
|
+
DataAssemblyResolverDefinitionSchema
|
|
7597
|
+
);
|
|
7598
|
+
var DataAssemblyReturnMappingConfigSchema = PointerExpressionValueSchema;
|
|
7599
|
+
var DataAssemblyMetadataSchema = z115.object({
|
|
7600
|
+
tags: z115.array(
|
|
7601
|
+
z115.object({
|
|
7602
|
+
sys: z115.object({
|
|
7603
|
+
type: z115.literal("Link"),
|
|
7604
|
+
linkType: z115.literal("Tag"),
|
|
7605
|
+
id: z115.string()
|
|
7606
|
+
})
|
|
7607
|
+
})
|
|
7608
|
+
)
|
|
7609
|
+
});
|
|
7610
|
+
|
|
7611
|
+
// src/tools/exo/data-assemblies/createDataAssembly.ts
|
|
7612
|
+
var CreateDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7613
|
+
name: z116.string().describe("The name of the data assembly"),
|
|
7614
|
+
description: z116.string().describe("Description of the data assembly"),
|
|
7615
|
+
parameters: DataAssemblyParameterConfigSchema.describe(
|
|
7616
|
+
"Parameter definitions keyed by parameter name (may be empty object)"
|
|
7617
|
+
),
|
|
7618
|
+
resolvers: DataAssemblyResolverConfigSchema.describe(
|
|
7619
|
+
"Resolver definitions keyed by resolver name (may be empty object)"
|
|
7620
|
+
),
|
|
7621
|
+
return: DataAssemblyReturnMappingConfigSchema.describe(
|
|
7622
|
+
"Return mapping configuration specifying how to map resolved data"
|
|
7623
|
+
),
|
|
7624
|
+
dataType: z116.array(DataAssemblyDataTypeFieldSchema).describe("Data type field definitions for this data assembly (may be empty array)"),
|
|
7625
|
+
variant: z116.string().optional().describe("Optional variant identifier for this data assembly"),
|
|
7626
|
+
metadata: DataAssemblyMetadataSchema.optional().describe("Optional metadata (tags)")
|
|
7627
|
+
});
|
|
7628
|
+
function createDataAssemblyTool(config) {
|
|
7629
|
+
async function tool2(args) {
|
|
7630
|
+
assertEnvironmentNotProtected(
|
|
7631
|
+
args.environmentId,
|
|
7632
|
+
config.protectedEnvironments
|
|
7633
|
+
);
|
|
7634
|
+
const contentfulClient = createToolClient(config, args);
|
|
7635
|
+
const dataAssembly = await contentfulClient.dataAssembly.create(
|
|
7636
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
7637
|
+
{
|
|
7638
|
+
sys: {
|
|
7639
|
+
type: "DataAssembly",
|
|
7640
|
+
dataType: args.dataType,
|
|
7641
|
+
...args.variant && { variant: args.variant }
|
|
7642
|
+
},
|
|
7643
|
+
name: args.name,
|
|
7644
|
+
description: args.description,
|
|
7645
|
+
parameters: args.parameters,
|
|
7646
|
+
resolvers: args.resolvers,
|
|
7647
|
+
return: args.return,
|
|
7648
|
+
metadata: args.metadata ?? { tags: [] }
|
|
7649
|
+
}
|
|
7650
|
+
);
|
|
7651
|
+
return createSuccessResponse("Data assembly created successfully", {
|
|
7652
|
+
dataAssembly
|
|
7653
|
+
});
|
|
7654
|
+
}
|
|
7655
|
+
return withErrorHandling(tool2, "Error creating data assembly");
|
|
7656
|
+
}
|
|
7657
|
+
|
|
7658
|
+
// src/tools/exo/data-assemblies/updateDataAssembly.ts
|
|
7659
|
+
import { z as z117 } from "zod";
|
|
7660
|
+
var UpdateDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7661
|
+
dataAssemblyId: z117.string().describe("The ID of the data assembly to update"),
|
|
7662
|
+
version: z117.number().describe(
|
|
7663
|
+
"REQUIRED. The data assembly's sys.version as returned by get_data_assembly. You must call get_data_assembly first to read the current state and version. The update is rejected if this does not match the current version, which means the data assembly changed since you read it."
|
|
7664
|
+
),
|
|
7665
|
+
name: z117.string().optional().describe("The name of the data assembly"),
|
|
7666
|
+
description: z117.string().optional().describe("Description of the data assembly"),
|
|
7667
|
+
parameters: DataAssemblyParameterConfigSchema.optional().describe(
|
|
7668
|
+
"Parameter definitions; replaces existing if provided"
|
|
7669
|
+
),
|
|
7670
|
+
resolvers: DataAssemblyResolverConfigSchema.optional().describe(
|
|
7671
|
+
"Resolver definitions; replaces existing if provided"
|
|
7672
|
+
),
|
|
7673
|
+
return: DataAssemblyReturnMappingConfigSchema.optional().describe(
|
|
7674
|
+
"Return mapping configuration; replaces existing if provided"
|
|
7675
|
+
),
|
|
7676
|
+
dataType: z117.array(DataAssemblyDataTypeFieldSchema).optional().describe("Data type field definitions; replaces existing if provided"),
|
|
7677
|
+
variant: z117.string().optional().describe("Optional variant identifier; replaces existing if provided"),
|
|
7678
|
+
metadata: DataAssemblyMetadataSchema.optional().describe(
|
|
7679
|
+
"Metadata (tags); replaces existing if provided"
|
|
7680
|
+
)
|
|
7681
|
+
});
|
|
7682
|
+
function updateDataAssemblyTool(config) {
|
|
7683
|
+
async function tool2(args) {
|
|
7684
|
+
assertEnvironmentNotProtected(
|
|
7685
|
+
args.environmentId,
|
|
7686
|
+
config.protectedEnvironments
|
|
7687
|
+
);
|
|
7688
|
+
const params = {
|
|
7689
|
+
spaceId: args.spaceId,
|
|
7690
|
+
environmentId: args.environmentId,
|
|
7691
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7692
|
+
};
|
|
7693
|
+
const contentfulClient = createToolClient(config, args);
|
|
7694
|
+
const current = await contentfulClient.dataAssembly.get(params);
|
|
7695
|
+
if (args.version !== current.sys.version) {
|
|
7696
|
+
throw new Error(
|
|
7697
|
+
`Version conflict: the data assembly has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the data assembly with get_data_assembly and retry the update with the latest sys.version.`
|
|
7698
|
+
);
|
|
7699
|
+
}
|
|
7700
|
+
const dataAssembly = await contentfulClient.dataAssembly.update(params, {
|
|
7701
|
+
sys: {
|
|
7702
|
+
id: current.sys.id,
|
|
7703
|
+
type: "DataAssembly",
|
|
7704
|
+
version: current.sys.version,
|
|
7705
|
+
dataType: args.dataType ?? current.sys.dataType,
|
|
7706
|
+
...args.variant !== void 0 ? { variant: args.variant } : current.sys.variant !== void 0 ? { variant: current.sys.variant } : {}
|
|
7707
|
+
},
|
|
7708
|
+
name: args.name ?? current.name,
|
|
7709
|
+
description: args.description ?? current.description,
|
|
7710
|
+
parameters: args.parameters ?? current.parameters,
|
|
7711
|
+
resolvers: args.resolvers ?? current.resolvers,
|
|
7712
|
+
return: args.return ?? current.return,
|
|
7713
|
+
metadata: args.metadata ?? current.metadata
|
|
7714
|
+
});
|
|
7715
|
+
return createSuccessResponse("Data assembly updated successfully", {
|
|
7716
|
+
dataAssembly
|
|
7717
|
+
});
|
|
7718
|
+
}
|
|
7719
|
+
return withErrorHandling(tool2, "Error updating data assembly");
|
|
7720
|
+
}
|
|
7721
|
+
|
|
7722
|
+
// src/tools/exo/data-assemblies/deleteDataAssembly.ts
|
|
7723
|
+
import { z as z118 } from "zod";
|
|
7724
|
+
var DeleteDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7725
|
+
dataAssemblyId: z118.string().describe("The ID of the data assembly to delete"),
|
|
7726
|
+
confirm: z118.boolean().optional().describe(
|
|
7727
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
7728
|
+
),
|
|
7729
|
+
confirmToken: z118.string().optional().describe(
|
|
7730
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
7731
|
+
)
|
|
7732
|
+
});
|
|
7733
|
+
function deleteDataAssemblyTool(config) {
|
|
7734
|
+
async function tool2(args) {
|
|
7735
|
+
assertEnvironmentNotProtected(
|
|
7736
|
+
args.environmentId,
|
|
7737
|
+
config.protectedEnvironments
|
|
7738
|
+
);
|
|
7739
|
+
const params = {
|
|
7740
|
+
spaceId: args.spaceId,
|
|
7741
|
+
environmentId: args.environmentId,
|
|
7742
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7743
|
+
};
|
|
7744
|
+
const contentfulClient = createToolClient(config, args);
|
|
7745
|
+
const dataAssembly = await contentfulClient.dataAssembly.get(params);
|
|
7746
|
+
const expectedToken = buildConfirmToken(
|
|
7747
|
+
"dataAssembly",
|
|
7748
|
+
args.dataAssemblyId,
|
|
7749
|
+
dataAssembly.sys.version
|
|
7750
|
+
);
|
|
7751
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
7752
|
+
return createSuccessResponse(
|
|
7753
|
+
`${CONFIRMATION_MESSAGE_PREFIX} data assembly`,
|
|
7754
|
+
buildConfirmationPreview(
|
|
7755
|
+
"dataAssembly",
|
|
7756
|
+
args.dataAssemblyId,
|
|
7757
|
+
{ dataAssembly },
|
|
7758
|
+
expectedToken
|
|
7759
|
+
)
|
|
7760
|
+
);
|
|
7761
|
+
}
|
|
7762
|
+
await contentfulClient.dataAssembly.delete(params);
|
|
7763
|
+
return createSuccessResponse("Data assembly deleted successfully", {
|
|
7764
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7765
|
+
});
|
|
7766
|
+
}
|
|
7767
|
+
return withErrorHandling(tool2, "Error deleting data assembly");
|
|
7768
|
+
}
|
|
7769
|
+
|
|
7770
|
+
// src/tools/exo/data-assemblies/publishDataAssembly.ts
|
|
7771
|
+
import { z as z119 } from "zod";
|
|
7772
|
+
var PublishDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7773
|
+
dataAssemblyId: z119.string().describe("The ID of the data assembly to publish"),
|
|
7774
|
+
version: z119.number().describe(
|
|
7775
|
+
"REQUIRED. The data assembly's sys.version as returned by get_data_assembly. You must call get_data_assembly first to read the current state and version. The publish is rejected if this does not match the current version, which means the data assembly changed since you read it."
|
|
7776
|
+
)
|
|
7777
|
+
});
|
|
7778
|
+
function publishDataAssemblyTool(config) {
|
|
7779
|
+
async function tool2(args) {
|
|
7780
|
+
assertEnvironmentNotProtected(
|
|
7781
|
+
args.environmentId,
|
|
7782
|
+
config.protectedEnvironments
|
|
7783
|
+
);
|
|
7784
|
+
const params = {
|
|
7785
|
+
spaceId: args.spaceId,
|
|
7786
|
+
environmentId: args.environmentId,
|
|
7787
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7788
|
+
};
|
|
7789
|
+
const contentfulClient = createToolClient(config, args);
|
|
7790
|
+
const current = await contentfulClient.dataAssembly.get(params);
|
|
7791
|
+
if (args.version !== current.sys.version) {
|
|
7792
|
+
throw new Error(
|
|
7793
|
+
`Version conflict: the data assembly has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the data assembly with get_data_assembly and retry with the latest sys.version.`
|
|
7794
|
+
);
|
|
7795
|
+
}
|
|
7796
|
+
const dataAssembly = await contentfulClient.dataAssembly.publish({
|
|
7797
|
+
...params,
|
|
7798
|
+
version: args.version
|
|
7799
|
+
});
|
|
7800
|
+
return createSuccessResponse("Data assembly published successfully", {
|
|
7801
|
+
dataAssembly
|
|
7802
|
+
});
|
|
7803
|
+
}
|
|
7804
|
+
return withErrorHandling(tool2, "Error publishing data assembly");
|
|
7805
|
+
}
|
|
7806
|
+
|
|
7807
|
+
// src/tools/exo/data-assemblies/unpublishDataAssembly.ts
|
|
7808
|
+
import { z as z120 } from "zod";
|
|
7809
|
+
var UnpublishDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7810
|
+
dataAssemblyId: z120.string().describe("The ID of the data assembly to unpublish"),
|
|
7811
|
+
version: z120.number().describe(
|
|
7812
|
+
"REQUIRED. The data assembly's sys.version as returned by get_data_assembly. You must call get_data_assembly first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the data assembly changed since you read it."
|
|
7813
|
+
)
|
|
7814
|
+
});
|
|
7815
|
+
function unpublishDataAssemblyTool(config) {
|
|
7816
|
+
async function tool2(args) {
|
|
7817
|
+
assertEnvironmentNotProtected(
|
|
7818
|
+
args.environmentId,
|
|
7819
|
+
config.protectedEnvironments
|
|
7820
|
+
);
|
|
7821
|
+
const params = {
|
|
7822
|
+
spaceId: args.spaceId,
|
|
7823
|
+
environmentId: args.environmentId,
|
|
7824
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7825
|
+
};
|
|
7826
|
+
const contentfulClient = createToolClient(config, args);
|
|
7827
|
+
const current = await contentfulClient.dataAssembly.get(params);
|
|
7828
|
+
if (args.version !== current.sys.version) {
|
|
7829
|
+
throw new Error(
|
|
7830
|
+
`Version conflict: the data assembly has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the data assembly with get_data_assembly and retry with the latest sys.version.`
|
|
7831
|
+
);
|
|
7832
|
+
}
|
|
7833
|
+
const dataAssembly = await contentfulClient.dataAssembly.unpublish({
|
|
7834
|
+
...params,
|
|
7835
|
+
version: args.version
|
|
7836
|
+
});
|
|
7837
|
+
return createSuccessResponse("Data assembly unpublished successfully", {
|
|
7838
|
+
dataAssembly
|
|
7839
|
+
});
|
|
7840
|
+
}
|
|
7841
|
+
return withErrorHandling(tool2, "Error unpublishing data assembly");
|
|
7842
|
+
}
|
|
7843
|
+
|
|
7844
|
+
// src/tools/exo/data-assemblies/register.ts
|
|
7845
|
+
function createDataAssemblyTools(config) {
|
|
7846
|
+
const getDataAssembly = getDataAssemblyTool(config);
|
|
7847
|
+
const getPublishedDataAssembly = getPublishedDataAssemblyTool(config);
|
|
7848
|
+
const listDataAssemblies = listDataAssembliesTool(config);
|
|
7849
|
+
const listPublishedDataAssemblies = listPublishedDataAssembliesTool(config);
|
|
7850
|
+
const createDataAssembly = createDataAssemblyTool(config);
|
|
7851
|
+
const updateDataAssembly = updateDataAssemblyTool(config);
|
|
7852
|
+
const deleteDataAssembly = deleteDataAssemblyTool(config);
|
|
7853
|
+
const publishDataAssembly = publishDataAssemblyTool(config);
|
|
7854
|
+
const unpublishDataAssembly = unpublishDataAssemblyTool(config);
|
|
7855
|
+
return {
|
|
7856
|
+
getDataAssembly: {
|
|
7857
|
+
title: "get_data_assembly",
|
|
7858
|
+
description: "Get details about a specific ExO DataAssembly (a smart data recipe that specifies how to fetch and reshape data for a component or page in a single operation).",
|
|
7859
|
+
inputParams: GetDataAssemblyToolParams.shape,
|
|
7860
|
+
annotations: {
|
|
7861
|
+
readOnlyHint: true,
|
|
7862
|
+
destructiveHint: false,
|
|
7863
|
+
openWorldHint: false
|
|
7864
|
+
},
|
|
7865
|
+
tool: getDataAssembly
|
|
7866
|
+
},
|
|
7867
|
+
getPublishedDataAssembly: {
|
|
7868
|
+
title: "get_published_data_assembly",
|
|
7869
|
+
description: "Get details about a specific published ExO DataAssembly by ID.",
|
|
7870
|
+
inputParams: GetPublishedDataAssemblyToolParams.shape,
|
|
7871
|
+
annotations: {
|
|
7872
|
+
readOnlyHint: true,
|
|
7873
|
+
destructiveHint: false,
|
|
7874
|
+
openWorldHint: false
|
|
7875
|
+
},
|
|
7876
|
+
tool: getPublishedDataAssembly
|
|
7877
|
+
},
|
|
7878
|
+
listDataAssemblies: {
|
|
7879
|
+
title: "list_data_assemblies",
|
|
7880
|
+
description: "List ExO DataAssemblies in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
7881
|
+
inputParams: ListDataAssembliesToolParams.shape,
|
|
7882
|
+
annotations: {
|
|
7883
|
+
readOnlyHint: true,
|
|
7884
|
+
destructiveHint: false,
|
|
7885
|
+
openWorldHint: false
|
|
7886
|
+
},
|
|
7887
|
+
tool: listDataAssemblies
|
|
7888
|
+
},
|
|
7889
|
+
listPublishedDataAssemblies: {
|
|
7890
|
+
title: "list_published_data_assemblies",
|
|
7891
|
+
description: "List published ExO DataAssemblies in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
7892
|
+
inputParams: ListPublishedDataAssembliesToolParams.shape,
|
|
7893
|
+
annotations: {
|
|
7894
|
+
readOnlyHint: true,
|
|
7895
|
+
destructiveHint: false,
|
|
7896
|
+
openWorldHint: false
|
|
7897
|
+
},
|
|
7898
|
+
tool: listPublishedDataAssemblies
|
|
7899
|
+
},
|
|
7900
|
+
createDataAssembly: {
|
|
7901
|
+
title: "create_data_assembly",
|
|
7902
|
+
description: "Create a new ExO DataAssembly.",
|
|
7903
|
+
inputParams: CreateDataAssemblyToolParams.shape,
|
|
7904
|
+
annotations: {
|
|
7905
|
+
readOnlyHint: false,
|
|
7906
|
+
destructiveHint: false,
|
|
7907
|
+
idempotentHint: false,
|
|
7908
|
+
openWorldHint: false
|
|
7909
|
+
},
|
|
7910
|
+
tool: createDataAssembly
|
|
7911
|
+
},
|
|
7912
|
+
updateDataAssembly: {
|
|
7913
|
+
title: "update_data_assembly",
|
|
7914
|
+
description: "Update an existing ExO DataAssembly. You MUST call get_data_assembly first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing data assembly fields, so you only need to provide the fields you want to change. If the version is stale (the data assembly changed since you read it), the update is rejected and you must re-fetch with get_data_assembly.",
|
|
7915
|
+
inputParams: UpdateDataAssemblyToolParams.shape,
|
|
7916
|
+
annotations: {
|
|
7917
|
+
readOnlyHint: false,
|
|
7918
|
+
destructiveHint: false,
|
|
7919
|
+
idempotentHint: false,
|
|
7920
|
+
openWorldHint: false
|
|
7921
|
+
},
|
|
7922
|
+
tool: updateDataAssembly
|
|
7923
|
+
},
|
|
7924
|
+
deleteDataAssembly: {
|
|
7925
|
+
title: "delete_data_assembly",
|
|
7926
|
+
description: "Delete an ExO DataAssembly. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same dataAssemblyId, confirm: true, and the confirmToken from the preview.",
|
|
7927
|
+
inputParams: DeleteDataAssemblyToolParams.shape,
|
|
7928
|
+
annotations: {
|
|
7929
|
+
readOnlyHint: false,
|
|
7930
|
+
destructiveHint: true,
|
|
7931
|
+
idempotentHint: false,
|
|
7932
|
+
openWorldHint: false
|
|
7933
|
+
},
|
|
7934
|
+
tool: deleteDataAssembly
|
|
7935
|
+
},
|
|
7936
|
+
publishDataAssembly: {
|
|
7937
|
+
title: "publish_data_assembly",
|
|
7938
|
+
description: "Publish an ExO DataAssembly. You MUST call get_data_assembly first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_data_assembly.",
|
|
7939
|
+
inputParams: PublishDataAssemblyToolParams.shape,
|
|
7940
|
+
annotations: {
|
|
7941
|
+
readOnlyHint: false,
|
|
7942
|
+
destructiveHint: true,
|
|
7943
|
+
idempotentHint: true,
|
|
7944
|
+
openWorldHint: false
|
|
7945
|
+
},
|
|
7946
|
+
tool: publishDataAssembly
|
|
7947
|
+
},
|
|
7948
|
+
unpublishDataAssembly: {
|
|
7949
|
+
title: "unpublish_data_assembly",
|
|
7950
|
+
description: "Unpublish an ExO DataAssembly. You MUST call get_data_assembly first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_data_assembly.",
|
|
7951
|
+
inputParams: UnpublishDataAssemblyToolParams.shape,
|
|
7952
|
+
annotations: {
|
|
7953
|
+
readOnlyHint: false,
|
|
7954
|
+
destructiveHint: true,
|
|
7955
|
+
idempotentHint: true,
|
|
7956
|
+
openWorldHint: false
|
|
7957
|
+
},
|
|
7958
|
+
tool: unpublishDataAssembly
|
|
7959
|
+
}
|
|
7960
|
+
};
|
|
7961
|
+
}
|
|
7962
|
+
|
|
7963
|
+
// src/ContentfulMcpTools.ts
|
|
7964
|
+
var ContentfulMcpTools = class {
|
|
7965
|
+
config;
|
|
7966
|
+
constructor(config) {
|
|
7967
|
+
this.config = {
|
|
7968
|
+
...config,
|
|
7969
|
+
host: config.host ?? "api.contentful.com",
|
|
7970
|
+
environmentId: config.environmentId ?? "master"
|
|
7971
|
+
};
|
|
7972
|
+
}
|
|
7973
|
+
/**
|
|
7974
|
+
* Update the configuration after initialization
|
|
7975
|
+
*
|
|
7976
|
+
* @param updates - Partial configuration to merge with existing config
|
|
7977
|
+
*/
|
|
7978
|
+
updateConfig(updates) {
|
|
7979
|
+
this.config = { ...this.config, ...updates };
|
|
7980
|
+
}
|
|
7981
|
+
/**
|
|
7982
|
+
* Get AI action tools
|
|
7983
|
+
*/
|
|
7984
|
+
getAiActionTools() {
|
|
7985
|
+
return createAiActionTools(this.config);
|
|
7986
|
+
}
|
|
7987
|
+
/**
|
|
7988
|
+
* Get asset tools
|
|
7989
|
+
*/
|
|
7990
|
+
getAssetTools() {
|
|
7991
|
+
return createAssetTools(this.config);
|
|
7992
|
+
}
|
|
7993
|
+
/**
|
|
7994
|
+
* Get content type tools
|
|
7995
|
+
*/
|
|
7996
|
+
getContentTypeTools() {
|
|
7997
|
+
return createContentTypeTools(this.config);
|
|
7998
|
+
}
|
|
7999
|
+
/**
|
|
8000
|
+
* Get ExO component type tools
|
|
8001
|
+
*/
|
|
8002
|
+
getComponentTypeTools() {
|
|
8003
|
+
return createComponentTypeTools(this.config);
|
|
8004
|
+
}
|
|
8005
|
+
/**
|
|
8006
|
+
* Get ExO template tools
|
|
8007
|
+
*/
|
|
8008
|
+
getTemplateTools() {
|
|
8009
|
+
return createTemplateTools(this.config);
|
|
8010
|
+
}
|
|
8011
|
+
/**
|
|
8012
|
+
* Get ExO experience tools
|
|
8013
|
+
*/
|
|
8014
|
+
getExperienceTools() {
|
|
8015
|
+
return createExperienceTools(this.config);
|
|
8016
|
+
}
|
|
8017
|
+
/**
|
|
8018
|
+
* Get context tools
|
|
8019
|
+
*/
|
|
8020
|
+
getContextTools() {
|
|
8021
|
+
return createContextTools(this.config);
|
|
8022
|
+
}
|
|
8023
|
+
/**
|
|
8024
|
+
* Get editor interface tools
|
|
8025
|
+
*/
|
|
8026
|
+
getEditorInterfaceTools() {
|
|
8027
|
+
return createEditorInterfaceTools(this.config);
|
|
8028
|
+
}
|
|
8029
|
+
/**
|
|
8030
|
+
* Get entry tools
|
|
8031
|
+
*/
|
|
8032
|
+
getEntryTools() {
|
|
8033
|
+
return createEntryTools(this.config);
|
|
8034
|
+
}
|
|
8035
|
+
/**
|
|
8036
|
+
* Get environment tools
|
|
8037
|
+
*/
|
|
8038
|
+
getEnvironmentTools() {
|
|
8039
|
+
return createEnvironmentTools(this.config);
|
|
8040
|
+
}
|
|
8041
|
+
/**
|
|
8042
|
+
* Get locale tools
|
|
8043
|
+
*/
|
|
8044
|
+
getLocaleTools() {
|
|
8045
|
+
return createLocaleTools(this.config);
|
|
8046
|
+
}
|
|
8047
|
+
/**
|
|
8048
|
+
* Get organization tools
|
|
8049
|
+
*/
|
|
8050
|
+
getOrgTools() {
|
|
8051
|
+
return createOrgTools(this.config);
|
|
8052
|
+
}
|
|
8053
|
+
/**
|
|
8054
|
+
* Get space tools
|
|
8055
|
+
*/
|
|
8056
|
+
getSpaceTools() {
|
|
8057
|
+
return createSpaceTools(this.config);
|
|
8058
|
+
}
|
|
8059
|
+
/**
|
|
8060
|
+
* Get tag tools
|
|
8061
|
+
*/
|
|
8062
|
+
getTagTools() {
|
|
5764
8063
|
return createTagTools(this.config);
|
|
5765
8064
|
}
|
|
5766
8065
|
/**
|
|
@@ -5769,6 +8068,18 @@ var ContentfulMcpTools = class {
|
|
|
5769
8068
|
getTaxonomyTools() {
|
|
5770
8069
|
return createTaxonomyTools(this.config);
|
|
5771
8070
|
}
|
|
8071
|
+
/**
|
|
8072
|
+
* Get ExO fragment tools
|
|
8073
|
+
*/
|
|
8074
|
+
getFragmentTools() {
|
|
8075
|
+
return createFragmentTools(this.config);
|
|
8076
|
+
}
|
|
8077
|
+
/**
|
|
8078
|
+
* Get ExO data assembly tools
|
|
8079
|
+
*/
|
|
8080
|
+
getDataAssemblyTools() {
|
|
8081
|
+
return createDataAssemblyTools(this.config);
|
|
8082
|
+
}
|
|
5772
8083
|
/**
|
|
5773
8084
|
* Get job tools (space-to-space migration)
|
|
5774
8085
|
*/
|