@contentful/mcp-tools 0.12.1 → 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.
Files changed (3) hide show
  1. package/dist/index.d.ts +5248 -1134
  2. package/dist/index.js +2513 -202
  3. package/package.json +3 -3
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 MCP_INSTRUCTIONS = `You are a helpful assistant integrated with Contentful through the Model Context Protocol (MCP).
2307
-
2308
- # Core Agent Principles
2309
-
2310
- ## IMPORTANT FIRST STEP:
2311
- - Always call get_initial_context first to initialize your connection before using any other tools
2312
- - This is required for all operations and will give you essential information about the current Contentful environment
2313
-
2314
- ## Key Principles:
2315
- - **Persistence**: Keep going until the user's query is completely resolved. Only end your turn when you are sure the problem is solved.
2316
- - **Tool Usage**: If you are not sure about content or schema structure, use your tools to gather relevant information. Do NOT guess or make up answers.
2317
- - **Planning**: Plan your approach before each tool call, and reflect on the outcomes of previous tool calls.
2318
- - **Resource Clarification**: ALWAYS ask the user which resource to work with if there are multiple resources available. Never assume or guess which resource to use.
2319
- - **Error Handling**: NEVER apologize for errors when making tool calls. Instead, immediately try a different approach or tool call. You may briefly inform the user what you're doing, but never say sorry.
2320
-
2321
- # Content Handling
2322
-
2323
- ## Content-Type-First Approach:
2324
- - **ALWAYS check the content type first** when users ask about finding or editing specific content types (e.g., "Where can I edit our pricing page?")
2325
- - Use get_content_types proactively to understand what content types exist before attempting queries
2326
- - This prevents failed queries and immediately reveals relevant content types (e.g., discovering a \`pricingPage\` type when asked about pricing)
2327
- - Match user requests to the appropriate content types in the entry
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 configInfo = `Current Contentful Configuration:
2426
- - Space ID: ${config.spaceId || "Not set"}
2427
- - Environment ID: ${config.environmentId || "master"}
2428
- - Organization ID: ${config.organizationId || "Not set"}`;
2429
- const todaysDate = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US");
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
- ${MCP_INSTRUCTIONS}
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
- This is the initial context for your Contentful instance:
2358
+ ${CORE_INVARIANTS}
2434
2359
 
2435
- <context>
2436
- ${configInfo}
2437
- </content>
2360
+ ${SEARCHING_GUIDANCE}
2438
2361
 
2439
- <todaysDate>${todaysDate}</todaysDate>
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/ContentfulMcpTools.ts
5683
- var ContentfulMcpTools = class {
5684
- config;
5685
- constructor(config) {
5686
- this.config = {
5687
- ...config,
5688
- host: config.host ?? "api.contentful.com",
5689
- environmentId: config.environmentId ?? "master"
5690
- };
5691
- }
5692
- /**
5693
- * Update the configuration after initialization
5694
- *
5695
- * @param updates - Partial configuration to merge with existing config
5696
- */
5697
- updateConfig(updates) {
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
- * Get editor interface tools
5726
- */
5727
- getEditorInterfaceTools() {
5728
- return createEditorInterfaceTools(this.config);
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
- * Get entry tools
5732
- */
5733
- getEntryTools() {
5734
- return createEntryTools(this.config);
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
- * Get environment tools
5738
- */
5739
- getEnvironmentTools() {
5740
- return createEnvironmentTools(this.config);
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
- * Get locale tools
5744
- */
5745
- getLocaleTools() {
5746
- return createLocaleTools(this.config);
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
- * Get organization tools
5750
- */
5751
- getOrgTools() {
5752
- return createOrgTools(this.config);
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
- * Get space tools
5756
- */
5757
- getSpaceTools() {
5758
- return createSpaceTools(this.config);
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
- * Get tag tools
5762
- */
5763
- getTagTools() {
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
  */