Skip to content

Lookup material for the Source CMS MCP server: the connection spec, every resource and resource template, and every tool. For setup instructions, see the MCP quickstart (Claude Code, Claude Desktop, Cursor, VS Code, GitHub Copilot, OpenCode, Codex) and the MCP guide (those plus MCP Inspector).

Property Value
Server URL {DRUPAL_SITE_URL}/mcp: your site URL plus /mcp. Also shown under Configurations > Experimental features > MCP Server > Configure > MCP client configuration in the site admin UI.
Transport Streamable HTTP; responses arrive as SSE (text/event-stream) with a single data: event per response (verified)
Server identity Name Acquia Source MCP, version 1.0.0
Protocol version 2025-11-25, negotiated at initialize.
Capabilities logging, completions, prompts (listChanged), resources (subscribe + listChanged), tools (listChanged)
Session Responses carry an mcp-session-id header; every subsequent request must echo it back as Mcp-Session-Id.
Authentication OAuth 2.0 bearer token. The site’s API client tokens work: a client_credentials grant against {DRUPAL_SITE_URL}/oauth/token (no scope parameter needed). Interactive clients instead self-register via dynamic client registration and run the browser flow. See the authentication guide.
Token lifetime Access tokens expire in 300 seconds; clients refresh silently.
Discovery The site publishes /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server (authorization endpoint /oauth/authorize, token endpoint /oauth/token, JWKS at /.well-known/jwks.json, dynamic client registration at /oauth/register). An unauthenticated or expired request gets 401 whose WWW-Authenticate header is only Bearer realm="mcp_server" (verified 2026-07-03); read the resource metadata document at {DRUPAL_SITE_URL}/.well-known/oauth-protected-resource/mcp directly (16 scopes_supported, bearer_methods_supported: ["header"]).
Scopes The 16 supported scopes are listed in the resource metadata document (not in the 401 header) and under OAuth configuration in the Configure panel. Scope gating was not observable in verification: a client_credentials token issued without a scope parameter (so carrying every scope selected on its API client) called every tool successfully.
Availability Experimental; off by default, enabled per site under Configurations > Experimental features.
Debug client npx @modelcontextprotocol/inspector --transport http, connection type Direct.

The server registration per harness, with the values from the table above. Interactive clients complete the browser OAuth flow on first connection; headless setups pass a client_credentials token as an Authorization header instead (MCP guide, step 2).

Terminal window
claude mcp add acquia-source-mcp {DRUPAL_SITE_URL}/mcp \
--transport http --scope project

Authenticate from the /mcp panel.

Tool domains: Content Management (read/write content entities), Content Modeling (define and evolve content structure), Taxonomy & Menus, Media, Site Settings, Drupal Canvas pages and components, and Drafts & Publishing. Alongside the tools, the server exposes resources (read-only data) and resource templates (parameterized reads).

MCP runs over JSON-RPC 2.0, so failures surface at three levels:

  • HTTP. An unauthenticated or expired request gets 401 Unauthorized. The WWW-Authenticate header is only Bearer realm="mcp_server" (verified 2026-07-03: it does not point at the resource metadata or list scopes); the JSON-RPC body carries error -32001 Authentication required. The resource metadata lives at the well-known URL in Connection.
  • JSON-RPC (schema-level). Input that violates a tool’s schema is rejected before execution with code -32602: e.g. “Invalid parameters for tool ‘…’: Property ‘/workflow’: Invalid type. Expected string, but received null.”, plus a data.validation_errors array of {pointer, keyword, message} objects.
  • Tool-level. Failures during execution come back as a successful JSON-RPC response with isError: false (verified 2026-07-03); check structuredContent.success, not isError. Two failure forms exist: an error object of {code, message, retryable, details, requestId} (captured codes: validation for a nonexistent target, configuration for a missing integration), or, when entity validation fails, a populated violations array of {field_name, message, invalid_value, code} with no error object.

Successful tool calls return their JSON payload twice: as text in result.content[0].text and mirrored in result.structuredContent.

Code / status Meaning Typical cause here
HTTP 401 Unauthorized Request carried no valid token OAuth flow not completed, token expired (300 s lifetime), or the MCP Server feature was disabled after connect
-32600 Invalid request Malformed JSON-RPC envelope (client bug)
-32601 Method not found Stale client capability cache or protocol-version mismatch
-32602 Invalid params Tool input doesn’t match its schema: details in data.validation_errors
-32603 Internal error Server-side failure while executing the call
-32001 Server-defined error Two captured uses: Authentication required on an unauthenticated request, and request timeouts on oversized queries or batches (narrow or split them)

Every entry below shares this error behavior; per-entry “Errors” notes list only what’s specific to that entry. Successful tool responses share success: true, a human-readable message, and a violations array (empty on success); per-entry Response lines list the distinctive members. MCP Inspector (Tools, List Resources, List Templates) shows the same shapes interactively.

Read-only lists at fixed URIs. Read them with the standard MCP resources/read request.

Lists the site’s content types with their schemas.

  • URI: drupal://content-types (no parameters)
  • Response: {usage, content_types: [{entity_type, bundle, label, description, workflow, schema_uri}]}: one entry per content type, each pointing at its drupal://content-types/{bundle} schema.
  • Errors: standard errors only.
  • Used in: MCP quickstart · MCP guide

Lists the site’s media types with their schemas. DAM-backed types are flagged with dam_type: true.

  • URI: drupal://media-types (no parameters)
  • Response: {media_types: [{entity_type, bundle, label, description, source, schema_uri, upload_supported, dam_type}]}. Captured: 12 types; the 8 DAM types are dam_type: true, upload_supported: false; image, document, and video are uploadable; remote_video is neither (OEmbed).
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the site’s taxonomy vocabularies.

  • URI: drupal://vocabularies (no parameters)
  • Response: {vocabularies: [{entity_type, vid, label, description, schema_uri}]}, each entry pointing at its drupal://vocabularies/{vid} schema (captured: categories and tags).
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the text filter formats available when creating or editing content with formatted text fields.

  • URI: drupal://filter-formats (no parameters)
  • Response: {formats: [{id, label, allowedHtml, allowedAttributes}]}. Captured: filtered_html (13 allowed tags) and plain_text; allowedAttributes maps attribute names to allowed values, with "on*": false blocking event handlers.
  • Errors: standard errors only.
  • Used in: MCP guide

Lists field storage definitions for the node entity type, with usage information: which storages exist and which bundles use them.

  • URI: drupal://content-types/fields (no parameters)
  • Response: {fields: [{field_name, type, target_type, cardinality, appears_on, translatable}], description}; appears_on lists the bundles using each storage (captured).
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the field types available for content modeling, organized by category.

  • URI: drupal://field-types (no parameters)
  • Response: the field-type catalog: plugin IDs usable as field_type in the modeling tools, including entries such as entity_reference and field_ui:entity_reference:media.
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the site’s menus. Each entry includes an items_uri pointing at the drupal://menus/{menu_name} template for that menu’s item tree.

  • URI: drupal://menus (no parameters)
  • Response: {menus: [{id, label, description, items_uri}]} (captured: one menu, main).
  • Errors: standard errors only.
  • Used in: MCP guide

Returns the site name and configured front/home page. Use its homepage object to identify the home page; never guess by path string-matching. If homepage is null, the site has no configured front page.

  • URI: drupal://site-info (no parameters)
  • Response: captured verbatim: {"site_name": "New Site", "homepage": {"path": "/homepage", "entity_type": "canvas_page", "entity_id": 1}}.
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the Drupal Canvas components available for composition.

  • URI: canvas://components (no parameters)
  • Response: array of {id, name, library, source, version, props, slots, detail_uri}; each prop is {required, schema, default_value} with JSON Schema types (enums for select-style props). Captured: one code component, js.text.
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the site’s editable Drupal Canvas pages with live and draft metadata.

  • URI: canvas://pages (no parameters)
  • Response: array of {id, hasDraftChanges, live: {title, status, path, internalPath, canonicalUrl}, draft}; draft is null when the page has no pending draft (captured).
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the global Canvas page regions (header, footer, and so on) shared across all pages for the active theme. Region IDs feed the page-region tools.

  • URI: canvas://page-regions (no parameters)
  • Response: array of {id, region, theme, label} with theme-prefixed IDs (captured: astral.header and astral.footer).
  • Errors: standard errors only.
  • Used in: MCP guide

Lists the current auto-saved drafts, with the identifiers the publish/discard tools need: publish_auto_saves takes both autosave_key and data_hash; discard_auto_saves takes the keys.

  • URI: canvas://auto-saves (no parameters)
  • Response: array of {autosave_key, entity_type, entity_id, label, data_hash, updated, owner, langcode, draft_published} (captured).
  • Errors: standard errors only.
  • Used in: MCP guide

Parameterized reads. Substitute the {placeholder} with a concrete value.

Loads one entity by entity type and ID. Supported entity types: node, taxonomy_term, media, user, canvas_page.

  • Parameters: entity_type_id: entity type machine name; id: the entity’s ID.
  • Example URI: drupal://entity/node/17
  • Response: the raw Drupal field-array representation, not the JSON:API shape: every field is an array of value objects ("title": [{"value": "…"}]), and references carry {target_id, target_uuid, target_type, url} (captured for drupal://entity/node/6).
  • Errors: standard errors; a nonexistent entity is a failed read.
  • Used in: MCP guide

Returns the JSON Schema for one content type.

  • Parameters: bundle: content type machine name.
  • Example URI: drupal://content-types/article
  • Response: the full JSON Schema (draft-04) for the bundle’s payload: the fields the create/update tools accept for that content type.
  • Errors: standard errors only.
  • Used in: MCP guide

drupal://content-types/{bundle}/fields/{field_name}

Section titled “drupal://content-types/{bundle}/fields/{field_name}”

Returns one field’s configuration on a content type: instance settings (label, description, required) and storage settings (type, cardinality, has_data, locked). Read it before changing a field with update_field_config.

  • Parameters: bundle: content type machine name; field_name: field machine name.
  • Example URI: drupal://content-types/article/fields/summary
  • Response: {field_name, bundle, label, description, required, default_value, field_settings, storage: {type, cardinality, translatable, storage_settings, has_data, locked}} (captured for article/body).
  • Errors: standard errors only.
  • Used in: MCP guide

Returns the JSON Schema for one media type.

  • Parameters: bundle: media type machine name (e.g. image).
  • Example URI: drupal://media-types/image
  • Response: the full JSON Schema (draft-04) for the media type’s payload, same structure as the content-type schemas (captured for image).
  • Errors: standard errors only.
  • Used in: MCP guide

Returns the JSON Schema for one taxonomy vocabulary.

  • Parameters: vid: vocabulary machine name.
  • Example URI: drupal://vocabularies/tags
  • Response: the full JSON Schema (draft-04) for term payloads in that vocabulary (captured for tags).
  • Errors: standard errors only.
  • Used in: MCP guide

Returns the item tree for one menu: enabled links in weight order, hierarchy represented by a depth field. Each item includes an id usable with update_menu_item and delete_menu_item.

  • Parameters: menu_name: menu machine name; discover IDs via drupal://menus.
  • Example URI: drupal://menus/main
  • Response: {menu_name, label, items} (captured for main; its items was []).
  • Errors: standard errors only.
  • Used in: MCP guide

Returns one Drupal Canvas component’s detailed schema and metadata, including the props and slots it declares.

  • Parameters: id: component ID exactly as listed by canvas://components; captured IDs are dotted, js.<machine_name> for code components (e.g. js.text).
  • Example URI: canvas://components/js.text
  • Response: everything the canvas://components entry lists for the component plus, per prop, source_type (e.g. static:field_item:string) and default_values: {source, resolved} (captured for js.text).
  • Errors: standard errors only.
  • Used in: MCP guide

Creates one content entry (node) of a given content type.

  • Input:
    • bundle (string, required): content type machine name; discover bundles via drupal://content-types.
    • fields (object, required): field names as keys, values as direct values ({"title": "My Title", "bio": "Text"}, not an array of name/value pairs). Must include a title key. Field names do not use the field_ prefix. Read drupal://content-types/{bundle} to discover the fields.
  • Response: {success, message, violations, warnings, entity_id, url, bundle, schema_uri} (captured). On a workflow-moderated bundle, warnings notes that draft content is not accessible or referenceable until published.
  • Errors: standard errors; -32602 when input doesn’t match the bundle’s schema (read drupal://content-types/{bundle} first).
  • Used in: MCP quickstart · MCP guide

Updates an existing node. Partial update: only the provided fields change.

  • Input:
    • entity_id (integer, required): node ID to update.
    • fields (object, required): field names as keys; only provided fields are updated. Entity references accept labels or IDs. Use a moderation_state key for workflow transitions (e.g. "moderation_state": "published"). Field names do not use the field_ prefix.
  • Response: same shape as create_node (captured). A value that fails entity validation returns success: false with the failure in violations[] (e.g. a moderation_state that doesn’t exist in the bundle’s workflow) and no error object.
  • Errors: standard errors.
  • Used in: MCP quickstart · MCP guide

Creates multiple nodes of the same content type in one call (the bulk-generation tool for content entries). Media and terms are created one call at a time.

  • Input:
    • bundle (string, required): content type machine name; all nodes in the batch share it.
    • nodes (array of objects, required, min 1): one field object per node, same format as create_node’s fields; every object must include title.
    • options (object): validate_only (boolean, dry-run validation without saving), stop_on_error (boolean, default false), return_details (boolean, default true; set false for token-efficient bulk runs).
  • Response: {total, successful, failed, results: [{index, success, title}], errors}; with options.validate_only: true the response adds validate_only: true and nothing is saved: a true dry run (both captured).
  • Errors: standard errors; -32001 on oversized batches: split them.
  • Used in: MCP quickstart · MCP guide

Lists entities with filtering and pagination: the general read used to fetch site content (e.g. recent articles). Supports node, taxonomy_term, media, user, and canvas_page.

  • Input:
    • entity_type (string, required): the entity type to list.
    • bundle (string): bundle/content type machine name to filter by.
    • filters (object): field names as keys, filter values as values. Operator suffixes: __contains, __starts_with, __ends_with, __gt, __gte, __lt, __lte, __not, __in, __not_in, __between, __not_between, __is_null, __is_not_null. label is an alias for the entity label field (e.g. {"label__contains": "News"}, {"created__gte": 1704067200}).
    • limit (integer, default 50): maximum results.
    • offset (integer, default 0): pagination offset.
  • Response: {entity_type, bundle, resource_template, total, items, pagination} where each item is {id, uuid, label, bundle, status, uri, path, canonicalUrl, revision_id}, uri is a ready-to-read drupal://entity/{entity_type_id}/{id} URI, and pagination is {limit, offset, has_more} (captured).
  • Errors: standard errors; -32001 on unfiltered sweeps of large sites: filter by content type or page the results.
  • Used in: MCP quickstart · MCP guide

Creates a new content type (node bundle) and returns the schema URI for it.

  • Input:
    • machine_name (string, required, max 32, ^[a-z][a-z0-9_]*$): the content type machine name.
    • label (string, required, max 255): human-readable label.
    • workflow (string, required): the workflow to assign to the content type; see the caution above.
    • description (string): optional description.
    • options (object): create_body_field (boolean, default true: add the standard body field), help (string: help text on the node add form).
  • Response: {machine_name, label, schema_uri, message} (captured).
  • Errors: standard errors; tool-level validation error Workflow "…" does not exist. when workflow names a workflow the site doesn’t have.
  • Used in: MCP quickstart · MCP guide

Adds a field to an existing content type. Supports field-storage reuse across bundles. Valid field types are listed by drupal://field-types.

  • Input:
    • content_type (string, required): the content type machine name.
    • field_name (string, required, max 32, ^[a-z][a-z0-9_]*$): unique machine name; do not prefix with field_.
    • field_type (string, required): field type plugin ID (e.g. string, integer, datetime) from drupal://field-types.
    • label (string, required, max 255): human-readable label.
    • description (string): optional help text.
    • required (boolean, default false).
    • cardinality (integer, default 1): number of values; -1 for unlimited.
    • storage_settings (object): e.g. max_length for string fields; for list_string/list_integer, pass allowed_values as {"gold": "Gold", "silver": "Silver"}.
    • field_settings (object): field instance settings.
    • default_value: optional default value.
  • Response: {success, field_name, content_type, field_type, storage_created, violations, message}; storage_created reports whether a new field storage was created rather than reused (captured).
  • Errors: standard errors; -32602 for a field type not present in drupal://field-types.
  • Used in: MCP quickstart · MCP guide

Adds multiple fields to one or more content types in a single call. Items are processed in order, so a field storage created by an earlier item can be reused by a later item on a different bundle.

  • Input:
    • fields (array of objects, required, min 1): each object takes the same parameters as add_field_to_content_type: content_type, field_name, field_type, label required; description, required, cardinality, storage_settings, field_settings, default_value optional.
  • Response: {total, successful, failed, results, errors}; each result is the add_field_to_content_type shape plus its index (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Updates an existing field’s configuration on a content type. Mutable: label, description, required, default_value, field_settings, cardinality, and (for list fields only) storage_settings.allowed_values. Other storage-level settings (target_type, max_length, …) cannot be changed with this tool.

  • Input:
    • content_type (string, required): the content type machine name.
    • field_name (string, required): field machine name; do not prefix with field_.
    • label (string): new label.
    • description (string): new help text.
    • required (boolean): set required or optional.
    • field_settings (object): instance settings to update.
    • default_value: new default value.
    • cardinality (integer): -1 for unlimited or a positive integer. Increasing is always safe; reducing is only allowed when no entities have values at higher deltas.
    • storage_settings (object): only allowed_values for list_string/list_integer field types.
  • Response: {success, field_name, content_type, violations, message}; the message names the keys that changed, e.g. "(label, required)" (captured).
  • Errors: standard errors. Inspect current settings first via drupal://content-types/{bundle}/fields/{field_name}.
  • Used in: MCP guide

Creates a taxonomy vocabulary. Idempotent: if the vocabulary already exists, returns the existing metadata without creating a duplicate.

  • Input:
    • vid (string, required, max 32, ^[a-z][a-z0-9_]*$): vocabulary machine name (e.g. tags, sponsor_tier).
    • name (string, required, max 255): human-readable label.
    • description (string): optional description.
    • weight (integer): optional display weight.
  • Response: {success, vid, name, description, schema_uri, existed, message}; existed: true on the idempotent path for the existing tags.
  • Errors: standard errors.
  • Used in: MCP guide

Returns an existing taxonomy term by exact name match (case-insensitive), or creates it if absent (idempotent tagging).

  • Input:
    • vid (string, required): vocabulary machine name; discover via drupal://vocabularies.
    • name (string, required): the exact term name to find or create.
    • additional_fields (object): optional extra field values (e.g. description, parent, weight).
  • Response: {success, entity_id, name, vid, existed, message, violations, warnings} (captured: an existing term returns existed: true with its entity_id).
  • Errors: standard errors.
  • Used in: MCP quickstart · MCP guide

Creates a new custom menu.

  • Input:
    • id (string, required, max 32, ^[a-z0-9_-]+$): menu machine name (e.g. footer-menu).
    • label (string, required, max 255): human-readable label.
    • description (string): optional description.
  • Response: {success, message, violations, id, label} (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Updates an existing menu’s label or description. At least one of label or description must be provided.

  • Input:
    • id (string, required): menu machine name.
    • label (string, max 255): new label.
    • description (string): new description.
  • Response: {success, message, violations, id, label} carrying the updated label (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Creates a menu link. The item is saved as an auto-save draft. Call publish_auto_saves with the returned autosave_key to make it visible in menus.

  • Input:
    • menu_name (string, required): menu machine name (e.g. main, footer).
    • title (string, required, max 255): link title.
    • link (string, required): link URI: internal:/path, https://example.com, entity:node/1, or route:route.name.
    • parent (string): parent menu link plugin ID (e.g. menu_link_content:<uuid>).
    • weight (integer): ordering weight; lower first (default 0).
    • enabled (boolean, default true) · expanded (boolean, default false) · description (string): optional tooltip text.
  • Response: {success, uuid, id, title, menu_name, autosave_key, message, violations, warnings}; autosave_key has the form menu_link_content:<id>:<langcode> (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Updates a menu item by entity ID. Partial update: only provided fields change; use weight to reorder. Changes are saved as an auto-save draft; publish them with publish_auto_saves.

  • Input:
    • id (integer, required): menu link content entity ID (from drupal://menus/{menu_name}).
    • title (string) · link (string) · parent (string; empty string removes the parent) · weight (integer) · enabled (boolean) · expanded (boolean) · description (string).
  • Response: same shape as create_menu_item, with a draft-state warning while the item is unpublished (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Deletes a menu item by entity ID. One of the catalog’s two delete tools (with delete_canvas_page). Nodes, media, and terms have no MCP delete.

  • Input:
    • id (integer, required): menu link content entity ID.
    • delete_children (boolean, default false): when false, existing children are re-parented to this item’s parent; when true, all descendants are also deleted.
  • Response: {success, id, title, children_deleted, message} (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Creates a file-based media entity (any file-based media type: image, document, video, …) and returns a signed upload URL. Upload the file afterwards with curl -X PUT <upload_url> -H "Content-Type: application/octet-stream" --data-binary @/path/to/file; the upload attaches the file and publishes the entity automatically. Reference the media in Canvas component props as the scalar MID (e.g. 42), and in Drupal entity reference fields as {"target_id": <mid>}. Don’t fetch the file URL from the media entity.

  • Input:
    • bundle (string, required): media type machine name; discover via drupal://media-types.
    • name (string, required): media name.
    • filename (string, required): target filename with extension (e.g. photo.jpg).
    • metadata (object): source-field metadata (e.g. {"alt": "Image description", "title": "Image title"} for images).
    • fields (object): additional field values keyed by field name; see drupal://media-types/{bundle}.
  • Response: {mid, upload_url, method: "PUT", expires_in: 300, message}; the entity stays an unpublished draft until the file is uploaded, and the upload URL expires in 300 seconds (captured).
  • Errors: standard errors.
  • Used in: MCP quickstart · MCP guide

Creates a remote-video media entity from an OEmbed URL (YouTube, Vimeo, …). Created and published immediately.

  • Input:
    • bundle (string, required): media type machine name (e.g. remote_video); any OEmbed-based bundle.
    • url (string, required): the OEmbed URL; must be from a supported provider.
    • name (string): media name; if omitted, Drupal auto-fetches the title from the OEmbed provider.
    • fields (object): additional field values keyed by field name.
  • Response: {mid, url, message}; created and published in one step (from a YouTube URL).
  • Errors: standard errors.
  • Used in: MCP guide

Creates a DAM-backed media entity by referencing an existing Acquia DAM asset: only the asset_id reference is stored; no file upload. Works only with DAM media types (dam_type: true in drupal://media-types).

  • Input:
    • bundle (string, required): a DAM-backed media type machine name.
    • asset_id (string, required): the Acquia DAM asset UUID; the asset must already exist in DAM.
    • name (string): media name; defaults to the asset filename from DAM.
    • version_id (string): optional DAM asset version UUID; empty uses the latest finalized version (the DAM CDN always serves the current published asset regardless).
    • external_id (string): optional DAM external ID.
  • Response: structuredContent carries mid (integer), url (string, the media entity’s absolute URL), and message (string), all three required. On a fresh import the message reads DAM media entity {mid} created and published successfully (asset_id: {asset_id}).; the tool is idempotent, so a repeat call for an already-imported asset returns the existing entity with message DAM media entity {mid} already exists for asset_id {asset_id}, returning existing entity. (shape from the tool’s outputSchema and kernel test against the DAM fixture, not a live DAM tenant). If the referenced asset is missing or not publicly available in DAM, the just-created entity saves unpublished, is deleted, and the tool returns code: "validation". On a site without the DAM integration the call fails with tool-level error code: "configuration", message Acquia DAM is not configured on this site….
  • Errors: standard errors.
  • Used in: MCP guide

Updates site settings such as the site name. Changes are staged and take effect when auto-saves are published.

  • Input:
    • site_name (string, required, min length 1): the new site name.
  • Response: {success, message, violations, site_name, already_set, staged}. When the requested name already matches, the tool is a no-op: already_set: true, staged: false, and no auto-save is created. A real change instead stages an auto-save (staged: true), applied by publish_auto_saves.
  • Errors: standard errors.
  • Used in: MCP guide

Uploads a new site logo and updates the theme configuration. Like create_media, it returns a signed upload URL: upload with curl -X PUT <upload_url> -H "Content-Type: application/octet-stream" --data-binary @/path/to/logo.png, after which the logo is immediately live.

  • Input:
    • filename (string, required): filename with extension. Supported formats: png, jpg, jpeg, gif, svg, webp, ico, apng.
  • Response: {upload_url, method: "PUT", expires_in: 300, message}: the same signed-upload envelope as create_media. Until a file is PUT to upload_url, nothing changes; the URL expires in 300 seconds.
  • Errors: standard errors.
  • Used in: MCP guide

Sets a Canvas page as the site homepage. If the page is unpublished, a published draft is staged. Takes effect when auto-saves are published.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
  • Response: {success, message, violations, page_id, page_title, page_url, auto_published, is_homepage, homepage_staged}. When the page is already the homepage, the tool is a no-op: is_homepage: true, homepage_staged: false. Setting a new homepage stages an auto-save (homepage_staged: true), and an unpublished target is auto-published.
  • Errors: standard errors.
  • Used in: MCP guide

Layout edits on Canvas pages write to the page’s draft (auto-save) channel. Make a page or its changes live with the draft and publishing tools.

Creates an unpublished Canvas page draft with optional metadata.

  • Input:
    • title (string, required, min length 1): page title.
    • path (string): optional URL alias, e.g. /acquia-engage.
    • description (string): optional page description.
  • Response: {success, message, violations, page_id, revision_reference, page}; page is the canvas://pages entry shape with both channels: live.status: false and a draft carrying revisionId, draftUrl, and dataHash (captured).
  • Errors: standard errors.
  • Used in: MCP quickstart · MCP guide

Updates page metadata (title/path/description/status) on an existing Canvas page draft. This changes the auto-save data_hash: if you publish via publish_auto_saves afterwards, use the page.draft.dataHash from this tool’s response, not a cached value.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • title (string) · path (string) · description (string): optional updated metadata.
    • status (boolean): optional publish status: true publishes the page when the draft is published; false keeps it unpublished.
  • Response: the same page envelope; the draft’s dataHash changes with every metadata update (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Deletes a Canvas page by ID. One of the catalog’s two delete tools (with delete_menu_item). Nodes, media, and terms have no MCP delete.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • force (boolean, default false): force deletion when true.
  • Response: {success, message, violations, page_id, deleted: true} (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Returns the native Canvas client-side layout/model representation for a page.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
  • Response: {success, message, violations, page_id, revision_reference, layout: {layout, model}}: layout is the component tree (nodes of {uuid, nodeType, type: "js.text@<version>", name, slots}) and model maps instance UUIDs to per-prop sources ({sourceType, expression}) (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Sets the native Canvas layout/model payload on the page’s draft channel, replacing the current draft layout.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • layout (object, required): native Canvas layout/model payload (same format as get_page_layout returns).
    • base_revision_id (integer or string): optional optimistic-lock token; a stale value returns a conflict.
  • Response: {success, message, violations, page_id, layout} echoing the saved layout; accepted with base_revision_id set to the revision_reference from get_page_layout (captured).
  • Errors: standard errors; conflict when base_revision_id is stale.
  • Used in: MCP quickstart · MCP guide

Adds a component instance at a slot/index target in a page’s draft layout. Available components and their IDs come from canvas://components.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • component_id (string, required): component ID to insert.
    • props (object): component props (static source only for Alpha).
    • parent_instance_id (string): instance ID of the parent component to nest inside; omit for top-level placement.
    • slot (string): target slot name on the parent; required when parent_instance_id is set (discover slot names via get_page_layout or canvas://components/{id}).
    • index (integer): insertion position within the page layout or the slot.
  • Response: {success, message, violations, page_id, new_instance_id, layout}; layout echoes the full updated draft layout/model (captured).
  • Errors: standard errors; -32602 for a component ID not listed by canvas://components.
  • Used in: MCP quickstart · MCP guide

Adds multiple component instances to a page’s draft layout in one call. All-or-nothing: if any component fails validation, the whole batch is rejected, no draft is written, and every per-component error is returned in failed_components so you can fix them all and retry.

Omit index on every item to append in batch order. Parents being created in the same batch get a temp_id starting with @ that children reference via parent_instance_id (e.g. {"temp_id": "@hero", …} then {"parent_instance_id": "@hero", "slot": "body", …}). Each parent must appear before its children.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • components (array of objects, required, min 1): each item: component_id (required), plus optional props, temp_id (^@.+), parent_instance_id, slot, index.
  • Response: on success {success, message, violations, page_id, total, successful, failed, new_instance_ids, component_results, layout}; each component_results entry is {index, component_id, instance_id, parent_instance_id, slot} (captured).
  • Errors: standard errors; validation failures list every failing component in failed_components.
  • Used in: MCP guide

Moves a component instance to a new slot/index target in the draft layout.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • instance_id (string, required): component instance ID to move.
    • parent_instance_id (string): target parent component instance ID.
    • slot (string): target slot name under the parent.
    • index (integer): target index in the region/slot component list.
  • Response: {success, message, violations, page_id, instance_id, layout} with the full layout echo (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Removes a component instance (including nested descendants) from the draft layout.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • instance_id (string, required): component instance ID to remove.
  • Response: {success, message, violations, page_id, removed_instance_id, layout} (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Partially updates the props of a component instance in a page’s draft layout.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
    • instance_id (string, required): component instance ID to update.
    • props (object, required): partial props patch (static source only for Alpha). Prop names and types for a given component come from canvas://components/{id}.
  • Response: {success, message, violations, page_id, instance_id, layout} (captured).
  • Errors: standard errors; -32602 for prop values that don’t match the component’s declared types.
  • Used in: MCP quickstart · MCP guide

Returns the current layout of a global Canvas page region (e.g. header or footer). Regions are shared across all pages for the active theme.

  • Input:
    • region_id (string, required): page region config entity ID (e.g. astral.header); list regions via canvas://page-regions.
  • Response: {success, message, violations, region_id, layout: {layoutVersion, regions: [{id, components}], componentCount}} (captured for astral.header).
  • Errors: standard errors.
  • Used in: MCP guide

Replaces the full layout of a global Canvas page region (e.g. header or footer).

  • Input:
    • region_id (string, required): page region config entity ID; list regions via canvas://page-regions.
    • layout (object, required): layout payload in the same format get_page_region_layout returns.
  • Response: the same shape, echoing the saved region layout (captured). Verified: region layout edits apply directly to the region; they do not appear in canvas://auto-saves.
  • Errors: standard errors.
  • Used in: MCP guide

Adds a component instance to a global Canvas page region (e.g. header or footer).

  • Input:
    • region_id (string, required): page region config entity ID; list regions via canvas://page-regions.
    • component_id (string, required): component ID to insert.
    • props (object): component props (static source only for Alpha).
    • parent_instance_id (string) · slot (string) · index (integer): optional placement, as in add_component_to_page.
  • Response: {success, message, violations, region_id, new_instance_id, layout}; region components carry {instanceId, componentId, name, props, region, parent, slot, index, slots} with resolved props values, unlike the page model representation (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Sets a Canvas page to published (publicly visible) and commits all pending draft changes. Use it to make a page live; to commit layout or content changes on an already-published page without changing its visibility, use publish_auto_saves instead.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
  • Response: the page envelope after publishing: live.status: true, draft: null, hasDraftChanges: false (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Publishes one or more auto-saved drafts to their canonical entities: Canvas layout edits, menu items, staged site settings.

  • Input:
    • autosaves (array of objects, required): each entry requires autosave_key (string) and data_hash (string), both from the canvas://auto-saves resource; the hash verifies you are publishing the version you expect.
  • Response: {success, message, violations, results: [{autosave_key, success, message}]} (captured).
  • Errors: standard errors; a stale data_hash is rejected: re-read canvas://auto-saves (or use the dataHash returned by the tool that changed the draft).
  • Used in: MCP guide

Discards one or more auto-saved drafts without publishing. Accepts individual keys for granular discard.

  • Input:
    • autosave_keys (array of strings, required): auto-save keys from the canvas://auto-saves resource.
  • Response: {success, message, violations, results: [{autosave_key, success, message}]} (captured). Verified caveat: discarding the auto-save of a newly created menu item leaves the disabled entity behind; remove it with delete_menu_item.
  • Errors: standard errors.
  • Used in: MCP guide

Generates a signed URL for previewing a Canvas page’s draft/auto-save without a Drupal login session. The URL is preview-only and expires in 5 minutes.

  • Input:
    • page_id (integer, required, ≥ 1): Canvas page entity ID.
  • Response: {success, message, violations, preview_url, expires_at, expires_in_seconds: 300} (captured).
  • Errors: standard errors.
  • Used in: MCP guide

Was this page helpful?