UNPKG

aem-mcp-server

Version:

AEM MCP server. Chat with your AEM instance for content, component, and asset operations.

2 lines (1 loc) 22.6 kB
"use strict";import{z as e}from"zod";import{zodToJsonSchema as s}from"zod-to-json-schema";const t=e.enum(["summary","standard","full"]).default("standard").optional().describe("Response detail level: summary (paths/names only), standard (default, minus JCR internals), full (everything)"),p={getAllTextContent:e.object({pagePath:e.string().describe("Path to the page")}).passthrough(),getPageTextContent:e.object({pagePath:e.string().describe("Path to the page")}).passthrough(),getPageImages:e.object({pagePath:e.string().describe("Path to the page")}).passthrough(),updateImagePath:e.object({componentPath:e.string().describe("Path to the image component"),newImagePath:e.string().describe("New image path")}).passthrough(),getPageContent:e.object({pagePath:e.string().describe("Path to the page"),verbosity:t}).passthrough(),getNodeContent:e.object({path:e.string().describe("JCR node path"),depth:e.number().optional().describe("Depth to traverse"),verbosity:t}).passthrough(),listChildren:e.object({path:e.string().describe("Parent node path"),verbosity:t}).passthrough(),getPageProperties:e.object({pagePath:e.string().describe("Path to the page")}).passthrough()},c={fetchSites:e.object({}).passthrough(),fetchLanguageMasters:e.object({site:e.string().describe("Site name")}).passthrough(),fetchAvailableLocales:e.object({site:e.string().describe("Site name")}).passthrough()},l={listPages:e.object({siteRoot:e.string().optional().describe("Site root path"),depth:e.number().optional().describe("Depth to traverse"),limit:e.number().optional().describe("Maximum number of results"),verbosity:t}).passthrough(),createPage:e.object({parentPath:e.string().describe("Parent path"),title:e.string().describe("Page title"),template:e.string().describe("Template path"),resourceType:e.string().optional().describe("Optional: Will be extracted from template if not provided"),name:e.string().optional().describe("Page name"),properties:e.record(e.unknown()).optional().describe("Additional properties")}).passthrough(),deletePage:e.object({pagePath:e.string().describe("Path to the page to delete"),force:e.boolean().optional().describe("Force deletion")}).passthrough(),activatePage:e.object({pagePath:e.string().describe("Path to the page"),activateTree:e.boolean().optional().describe("Activate entire tree")}).passthrough(),deactivatePage:e.object({pagePath:e.string().describe("Path to the page"),deactivateTree:e.boolean().optional().describe("Deactivate entire tree")}).passthrough(),unpublishContent:e.object({contentPaths:e.array(e.string()).describe("Paths to unpublish"),unpublishTree:e.boolean().optional().describe("Unpublish tree")}).passthrough()},d={updateComponent:e.object({componentPath:e.string().describe("Path to the component"),properties:e.record(e.unknown()).describe("Properties to update")}).passthrough(),scanPageComponents:e.object({pagePath:e.string().describe("Path to the page to scan"),verbosity:t}).passthrough(),createComponent:e.object({pagePath:e.string().describe("Path to the page"),componentType:e.string().describe("Component type"),resourceType:e.string().describe("Resource type"),properties:e.record(e.unknown()).optional().describe("Component properties"),name:e.string().optional().describe("Component name")}).passthrough(),addComponent:e.object({pagePath:e.string().describe("Path to the existing page (e.g., /content/site/en/page)"),resourceType:e.string().describe("Sling resource type of the component (required)"),containerPath:e.string().optional().describe("Optional: specific container path (defaults to root/container)"),name:e.string().optional().describe("Optional: component node name (auto-generated if not provided)"),properties:e.record(e.unknown()).optional().describe("Optional: component properties to set")}).passthrough(),deleteComponent:e.object({componentPath:e.string().describe("Path to the component to delete"),force:e.boolean().optional().describe("Force deletion")}).passthrough(),getComponents:e.object({path:e.string().optional().describe("Optional: Component root path to fetch components from. If not provided, uses the configured default path."),verbosity:t}).passthrough(),bulkUpdateComponents:e.object({updates:e.array(e.object({componentPath:e.string(),properties:e.record(e.unknown())})).describe("Array of component updates"),validateFirst:e.boolean().optional().describe("Validate before updating"),continueOnError:e.boolean().optional().describe("Continue on individual failures")}).passthrough(),convertComponents:e.object({pagePath:e.string().describe("Path to the page containing components to convert"),sourceResourceType:e.string().describe("The resource type to search for and convert"),targetResourceType:e.string().describe("The resource type to convert to"),requiredProperties:e.record(e.unknown()).optional().describe("Optional: Required property values for the target component"),continueOnError:e.boolean().optional().describe("Optional: Continue converting even if some fail (default: true)")}).passthrough(),bulkConvertComponents:e.object({pagePaths:e.array(e.string()).optional().describe("Array of page paths to process"),searchPath:e.string().optional().describe("Optional: Base path to search for pages"),depth:e.number().optional().describe("Optional: Depth to search when using searchPath (default: 2)"),limit:e.number().optional().describe("Optional: Maximum number of pages to process (default: 50)"),sourceResourceType:e.string().describe("The resource type to search for and convert"),targetResourceType:e.string().describe("The resource type to convert to"),requiredProperties:e.record(e.unknown()).optional().describe("Optional: Required property values for the target component"),continueOnError:e.boolean().optional().describe("Optional: Continue processing pages even if some fail (default: true)")}).passthrough()},g={getAssetMetadata:e.object({assetPath:e.string().describe("Path to the asset")}).passthrough(),updateAsset:e.object({assetPath:e.string().describe("Path to the asset"),metadata:e.record(e.unknown()).optional().describe("Metadata to update"),fileContent:e.string().optional().describe("File content"),mimeType:e.string().optional().describe("MIME type")}).passthrough(),deleteAsset:e.object({assetPath:e.string().describe("Path to the asset to delete"),force:e.boolean().optional().describe("Force deletion")}).passthrough()},m={searchContent:e.object({type:e.string().optional().describe("Content type"),fulltext:e.string().optional().describe("Fulltext search term"),path:e.string().optional().describe("Search path"),limit:e.number().optional().describe("Maximum number of results")}).passthrough(),executeJCRQuery:e.object({query:e.string().describe("JCR query"),limit:e.number().optional().describe("Maximum number of results")}).passthrough(),enhancedPageSearch:e.object({searchTerm:e.string().describe("Search term"),basePath:e.string().describe("Base path for search"),includeAlternateLocales:e.boolean().optional().describe("Include alternate locales")}).passthrough()},u={getTemplates:e.object({sitePath:e.string().optional().describe("Site path")}).passthrough(),getTemplateStructure:e.object({templatePath:e.string().describe("Template path")}).passthrough()},h={listWorkflowModels:e.object({}).passthrough(),startWorkflow:e.object({modelId:e.string().describe('Workflow model ID (e.g., "request_for_activation")'),payload:e.string().describe("JCR path or URL to process"),payloadType:e.string().optional().describe('Type of payload (default: "JCR_PATH")')}).passthrough(),listWorkflowInstances:e.object({state:e.string().optional().describe("Optional: Filter by state (RUNNING, SUSPENDED, ABORTED, COMPLETED)")}).passthrough(),getWorkflowInstance:e.object({instanceId:e.string().describe("Workflow instance ID or full path")}).passthrough(),updateWorkflowInstanceState:e.object({instanceId:e.string().describe("Workflow instance ID or full path"),state:e.enum(["RUNNING","SUSPENDED","ABORTED"]).describe("New state for the workflow instance")}).passthrough(),getInboxItems:e.object({}).passthrough(),completeWorkItem:e.object({workItemPath:e.string().describe("Path to the work item"),routeId:e.string().optional().describe("Optional: Route ID to advance to"),comment:e.string().optional().describe("Optional: Comment for the completion")}).passthrough(),delegateWorkItem:e.object({workItemPath:e.string().describe("Path to the work item"),delegatee:e.string().describe("User or group to delegate to")}).passthrough(),getWorkItemRoutes:e.object({workItemPath:e.string().describe("Path to the work item")}).passthrough()},b={getContentFragment:e.object({path:e.string().describe("Path to the content fragment in DAM (e.g., /content/dam/site/cf/my-article)")}).passthrough(),listContentFragments:e.object({path:e.string().describe("Parent path to search under (e.g., /content/dam/site/cf)"),model:e.string().optional().describe("Filter by CF model path"),limit:e.number().optional().describe("Max results (default: 20)"),offset:e.number().optional().describe("Pagination offset (default: 0)")}).passthrough(),manageContentFragment:e.object({action:e.enum(["create","update","delete","mergeJsonField"]).describe("Action to perform"),fragmentPath:e.string().optional().describe("Path to existing CF (required for update/delete/mergeJsonField)"),parentPath:e.string().optional().describe("Parent folder in DAM (required for create)"),title:e.string().optional().describe("Fragment title (required for create)"),name:e.string().optional().describe("Node name (auto-generated from title if omitted)"),model:e.string().optional().describe("CF model path (required for create)"),fields:e.record(e.unknown()).optional().describe("Field values as { fieldName: value } (create/update)"),description:e.string().optional().describe("Fragment description"),force:e.boolean().optional().describe("Force delete even if referenced"),variation:e.string().optional().describe('Variation name to target (default: "master"); applies to update and mergeJsonField'),field:e.string().optional().describe("mergeJsonField: name of the field that holds a JSON-encoded string to patch"),jsonPointer:e.string().optional().describe('mergeJsonField: RFC-6901 pointer to the object to merge into (e.g. "/0/content/0/value"); default "" = field root'),merge:e.record(e.unknown()).optional().describe("mergeJsonField: keys to upsert into the resolved object (deep-merged; existing keys overwritten, untouched keys preserved)")}).passthrough(),manageContentFragmentVariation:e.object({action:e.enum(["create","update","delete"]).describe("Action to perform"),fragmentPath:e.string().describe("Path to the parent content fragment"),variationName:e.string().describe("Variation identifier"),title:e.string().optional().describe("Variation title (required for create)"),fields:e.record(e.unknown()).optional().describe("Field overrides as { fieldName: value }")}).passthrough()},f={getExperienceFragment:e.object({path:e.string().describe("Path to the experience fragment page")}).passthrough(),listExperienceFragments:e.object({path:e.string().optional().describe("Root path (default: /content/experience-fragments)"),template:e.string().optional().describe("Filter by template path"),limit:e.number().optional().describe("Max results (default: 20)"),offset:e.number().optional().describe("Pagination offset (default: 0)")}).passthrough(),manageExperienceFragment:e.object({action:e.enum(["create","update","delete"]).describe("Action to perform"),xfPath:e.string().optional().describe("Existing XF path (required for update/delete)"),parentPath:e.string().optional().describe("Parent path for new XF (required for create)"),name:e.string().optional().describe("Node name (auto-generated from title if omitted)"),title:e.string().optional().describe("XF title (required for create)"),template:e.string().optional().describe("XF template path (required for create)"),description:e.string().optional().describe("XF description"),tags:e.array(e.string()).optional().describe("Tags to apply"),force:e.boolean().optional().describe("Force delete even if referenced")}).passthrough(),manageExperienceFragmentVariation:e.object({action:e.enum(["create","update","delete"]).describe("Action to perform"),xfPath:e.string().describe("Parent experience fragment path"),variationName:e.string().describe("Variation identifier"),variationType:e.enum(["web","email","social","custom"]).optional().describe("Variation type (default: web)"),title:e.string().optional().describe("Variation title (required for create)"),template:e.string().optional().describe("Template for the variation"),force:e.boolean().optional().describe("Force deletion")}).passthrough()};export const toolSchemas={...p,...c,...l,...d,...g,...m,...u,...h,...b,...f},toolDescriptions={updateComponent:"Update component properties in AEM",scanPageComponents:"Scan a page to discover all components and their properties",fetchSites:"Get all top-level AEM site roots under /content. Returns site name, path, and language root structure.",fetchLanguageMasters:"Get language masters for a specific site",fetchAvailableLocales:"Get available locales for a site",getAllTextContent:"Get all text content from a page including titles, text components, and descriptions",getPageTextContent:"Get text content from a specific page",getPageImages:"Get all images from a page, including those within Experience Fragments",updateImagePath:"Update the image path for an image component and verify the update",getPageContent:"Get complete page content including resolved Experience Fragments and Content Fragments. Returns full content tree. For text-only extraction, use getPageTextContent. For raw JCR nodes, use getNodeContent.",listPages:"List child pages directly under a path (non-recursive, structural). For finding pages by content or name, use enhancedPageSearch instead.",getNodeContent:"Get raw JCR node properties at a specific path and depth. Low-level tool \u2014 use getPageContent for pages or scanPageComponents for component discovery.",listChildren:"Legacy: List child nodes",getPageProperties:"Get page properties",searchContent:"Structured content search with filters (type, property values, path scope, fulltext). More flexible than executeJCRQuery. Use for finding nodes by property values or content type.",executeJCRQuery:"Execute fulltext search on cq:Page nodes under /content. Uses QueryBuilder internally, NOT raw JCR-SQL2. For structured property-based queries, use searchContent instead.",getAssetMetadata:"Get DAM asset metadata including title, description, dimensions, format, tags, and custom properties. Path must be under /content/dam.",enhancedPageSearch:"Intelligent page search with comprehensive fallback strategies and cross-section search",createPage:"Create a new page in AEM. The resourceType will be automatically extracted from the template structure if not provided.",deletePage:"Delete a page from AEM",createComponent:"Create a component at a specific JCR path (you must know the exact container path). For automatic container detection and cq:template application, use addComponent instead.",addComponent:"Add a component to a page with automatic parsys/container detection and cq:template application. Preferred over createComponent for most use cases.",deleteComponent:"Delete a component from AEM",unpublishContent:"Unpublish content from the publish environment",activatePage:"Publish a page immediately via direct replication (synchronous). For approval-based publishing workflows, use startWorkflow with the request_for_activation model.",deactivatePage:"Deactivate (unpublish) a single page",updateAsset:"Update an existing asset in AEM DAM",deleteAsset:"Delete an asset from AEM DAM",getTemplates:"Get available page templates",getTemplateStructure:"Get detailed structure of a specific template",getComponents:"Get all components from the configured component root path (projectRoot1) or a specified path. Shows component name, title, description, resource type, and other metadata.",bulkUpdateComponents:"Update multiple components in a single operation with validation and rollback support",convertComponents:"Find all components of a specific resource type on a page, delete them, and create new components of another type at the same location. Returns required properties if target component needs them.",bulkConvertComponents:"Convert components across multiple pages. Find all components of a specific resource type on multiple pages, delete them, and create new components of another type at the same location.",listWorkflowModels:"List all available workflow models in AEM. Returns common workflows like request_for_activation (publish), request_for_deactivation (unpublish), request_for_deletion (delete pages), and others.",startWorkflow:"Start a workflow instance. Common workflows: request_for_activation (publish pages), request_for_deactivation (unpublish pages), request_for_deletion (delete pages).",listWorkflowInstances:"List workflow instances, optionally filtered by state",getWorkflowInstance:"Get details of a specific workflow instance by ID",updateWorkflowInstanceState:"Update workflow instance state (RUNNING, SUSPENDED, ABORTED)",getInboxItems:"Get all work items in the inbox (work items assigned to current user)",completeWorkItem:"Complete or advance a work item to the next step in the workflow",delegateWorkItem:"Delegate a work item to another user or group",getWorkItemRoutes:"Get available routes for a work item (to see what steps are available)",getContentFragment:"Get a content fragment with all fields, variations, and metadata",listContentFragments:"List content fragments under a path with optional model filter",manageContentFragment:'Create, update, or delete a content fragment, or merge keys into a JSON-encoded-string field (action "mergeJsonField"). mergeJsonField reads the current blob, deep-merges your keys at an optional RFC-6901 jsonPointer, and writes it back server-side \u2014 use it to upsert a few keys into a field that stores a whole key\u2192value map as one JSON string, without round-tripping the entire blob. Use action param to specify operation.',manageContentFragmentVariation:"Create, update, or delete a variation within a content fragment",getExperienceFragment:"Get an experience fragment with all variations, components, and metadata",listExperienceFragments:"List experience fragments under a path with optional template filter",manageExperienceFragment:"Create, update, or delete an experience fragment. Auto-creates master variation on create.",manageExperienceFragmentVariation:"Create, update, or delete a variation within an experience fragment"};function y(){return Object.keys(toolSchemas).map(o=>{const{$schema:a,...r}=s(toolSchemas[o],{target:"jsonSchema7"});return{name:o,description:toolDescriptions[o],inputSchema:r}})}export const tools=y();export function injectInstanceParam(o,a,r){return o.map(n=>{const i=n.inputSchema;return{...n,inputSchema:{...i,properties:{...i.properties||{},instance:{type:"string",description:`Target AEM instance. Available: ${a.join(", ")}. Default: "${r}"`,enum:a}}}}})}export const toolAnnotations={getAllTextContent:{group:"content",readOnly:!0,complexity:"low"},getPageTextContent:{group:"content",readOnly:!0,complexity:"low"},getPageImages:{group:"content",readOnly:!0,complexity:"low"},updateImagePath:{group:"content",readOnly:!1,complexity:"medium"},getPageContent:{group:"content",readOnly:!0,complexity:"low"},getPageProperties:{group:"content",readOnly:!0,complexity:"low"},fetchSites:{group:"sites",readOnly:!0,complexity:"low"},fetchLanguageMasters:{group:"sites",readOnly:!0,complexity:"low"},fetchAvailableLocales:{group:"sites",readOnly:!0,complexity:"low"},listPages:{group:"pages",readOnly:!0,complexity:"low"},createPage:{group:"pages",readOnly:!1,complexity:"medium"},deletePage:{group:"pages",readOnly:!1,complexity:"high"},activatePage:{group:"pages",readOnly:!1,complexity:"medium"},deactivatePage:{group:"pages",readOnly:!1,complexity:"medium"},unpublishContent:{group:"pages",readOnly:!1,complexity:"medium"},enhancedPageSearch:{group:"search",readOnly:!0,complexity:"low"},getNodeContent:{group:"content",readOnly:!0,complexity:"low"},listChildren:{group:"content",readOnly:!0,complexity:"low"},updateComponent:{group:"components",readOnly:!1,complexity:"medium"},scanPageComponents:{group:"components",readOnly:!0,complexity:"low"},createComponent:{group:"components",readOnly:!1,complexity:"high"},addComponent:{group:"components",readOnly:!1,complexity:"medium"},deleteComponent:{group:"components",readOnly:!1,complexity:"high"},getComponents:{group:"components",readOnly:!0,complexity:"low"},bulkUpdateComponents:{group:"components",readOnly:!1,complexity:"high"},convertComponents:{group:"components",readOnly:!1,complexity:"high"},bulkConvertComponents:{group:"components",readOnly:!1,complexity:"high"},getAssetMetadata:{group:"assets",readOnly:!0,complexity:"low"},updateAsset:{group:"assets",readOnly:!1,complexity:"medium"},deleteAsset:{group:"assets",readOnly:!1,complexity:"high"},searchContent:{group:"search",readOnly:!0,complexity:"low"},executeJCRQuery:{group:"search",readOnly:!0,complexity:"medium"},getTemplates:{group:"templates",readOnly:!0,complexity:"low"},getTemplateStructure:{group:"templates",readOnly:!0,complexity:"low"},listWorkflowModels:{group:"workflows",readOnly:!0,complexity:"low"},startWorkflow:{group:"workflows",readOnly:!1,complexity:"medium"},listWorkflowInstances:{group:"workflows",readOnly:!0,complexity:"low"},getWorkflowInstance:{group:"workflows",readOnly:!0,complexity:"low"},updateWorkflowInstanceState:{group:"workflows",readOnly:!1,complexity:"medium"},getInboxItems:{group:"workflows",readOnly:!0,complexity:"low"},completeWorkItem:{group:"workflows",readOnly:!1,complexity:"medium"},delegateWorkItem:{group:"workflows",readOnly:!1,complexity:"medium"},getWorkItemRoutes:{group:"workflows",readOnly:!0,complexity:"low"},getContentFragment:{group:"fragments-content",readOnly:!0,complexity:"low"},listContentFragments:{group:"fragments-content",readOnly:!0,complexity:"low"},manageContentFragment:{group:"fragments-content",readOnly:!1,complexity:"medium"},manageContentFragmentVariation:{group:"fragments-content",readOnly:!1,complexity:"medium"},getExperienceFragment:{group:"fragments-experience",readOnly:!0,complexity:"low"},listExperienceFragments:{group:"fragments-experience",readOnly:!0,complexity:"low"},manageExperienceFragment:{group:"fragments-experience",readOnly:!1,complexity:"medium"},manageExperienceFragmentVariation:{group:"fragments-experience",readOnly:!1,complexity:"medium"}};