acquia-source

GitHub

用于连接 Acquia Source CMS,通过 JSON:API、MCP 及 CLI 实现 OAuth2 认证、内容读取/写入、Canvas 组件构建与页面部署的集成技能。

skills/acquia-source/SKILL.md grasmash/drupal-claude-skills

Trigger Scenarios

需要连接或配置 Acquia Source CMS 站点 使用 API 读写 Drupal 内容或管理 Canvas 组件 部署 Landing Page 到 Acquia Source

Install

npx skills add grasmash/drupal-claude-skills --skill acquia-source -g -y
More Options

Use without installing

npx skills use grasmash/drupal-claude-skills@acquia-source

指定 Agent (Claude Code)

npx skills add grasmash/drupal-claude-skills --skill acquia-source -a claude-code -g -y

安装 repo 全部 skill

npx skills add grasmash/drupal-claude-skills --all -g -y

预览 repo 内 skill

npx skills add grasmash/drupal-claude-skills --list

SKILL.md

Frontmatter
{
    "name": "acquia-source",
    "description": "Connect to an Acquia Source (\"Source powered by Drupal CMS\") site — its JSON:API and MCP endpoints, OAuth2 auth, the @drupal-canvas CLI, and the Canvas Page API deploy workflow. Use when wiring an AI agent or app to a Source CMS site, building\/uploading Drupal Canvas Code Components, deploying landing pages via the Page API, or registering the Source MCP server with Claude Code\/Cursor."
}

Acquia Source

Acquia Source ("Source powered by Drupal CMS") is a managed SaaS CMS wrapping Drupal CMS 11+ and the Drupal Canvas page builder (drupal.org/project/canvas, formerly Experience Builder). You don't get server/SSH access or arbitrary contrib — you interact through its JSON:API, its MCP server, the Canvas Page API, and the @drupal-canvas CLI. Admin/login at https://source.acquia.com.

Acquia Source is a SaaS product, not Acquia Cloud Platform. The acli CLI manages Cloud Platform, not Source sites — don't reach for it here. Source is driven through the web admin + the APIs below.

Site identity & credentials

  • CMS URL looks like https://<uuid>.cms.acquia.site (auto-generated at site creation; a custom domain can be mapped later). This base URL is the JSON:API host and the OAuth host.
  • API clients (OAuth2 client_id/secret) are created in the admin UI under API → API clients → Add API client.
  • The @drupal-canvas CLI reads everything from a local .env (never committed):
    CANVAS_SITE_URL=https://<uuid>.cms.acquia.site
    CANVAS_CLIENT_ID=<client_id>
    CANVAS_CLIENT_SECRET=<client_secret>
    CANVAS_JSONAPI_PREFIX=api        # Source serves JSON:API under /api, not the Drupal default /jsonapi
    # CANVAS_ACCESS_TOKEN=<token>    # optional: a pre-issued Bearer token instead of client credentials
    

Authentication (OAuth2 via simple_oauth)

  • Token endpoint: POST https://<site>/oauth/token, Content-Type: application/x-www-form-urlencoded.
  • Grants: Authorization Code (user-present), Client Credentials (server/agent — use this for automation), Refresh Token.
  • Request header on API calls: Authorization: Bearer <access_token>.
  • Scopes: content scopes like content:read / content:write (examples — the full list isn't published); the Canvas CLI needs canvas:asset_library and canvas:js_component. Enable Client Credentials + add those scopes when creating the API client.

Client-credentials token, by hand:

curl -s -X POST "$CANVAS_SITE_URL/oauth/token" \
  -d grant_type=client_credentials \
  -d client_id="$CANVAS_CLIENT_ID" \
  -d client_secret="$CANVAS_CLIENT_SECRET" \
  -d scope="canvas:asset_library canvas:js_component" | jq -r .access_token

JSON:API

  • Base path is /api on Source (Drupal's default /jsonapi is overridden — set CANVAS_JSONAPI_PREFIX=api). So a collection is https://<site>/api/<entity_type>/<bundle> (e.g. /api/node/article).
  • Resource types are standard Drupal {entity_type}--{bundle} (node--article, media--image, taxonomy_term--tags, …). No Source-proprietary prefix confirmed.
  • The admin UI has a JSON:API Query Builder (API → JSON:API Query Builder) that generates live queries + code, and per-site OpenAPI documentation (API → OpenAPI documentation). Use those to discover exact bundles/fields for a given site.
curl -s -H "Authorization: Bearer $TOKEN" \
  "$CANVAS_SITE_URL/api/node/article?page[limit]=5" | jq '.data[].attributes.title'

MCP server (connect an AI agent)

Acquia Source ships an MCP server (HTTP transport, OAuth2 with dynamic client registration). It's experimental and per-site — enable it first.

  1. Enable: admin UI → Configurations → Experimental features → MCP Server toggle.
  2. Get the URL: copy the site's MCP URL from MCP Client Configuration in the Source admin (the endpoint URL is provisioned per site; there's no fixed public path to hardcode).
  3. Register in Claude Code:
    claude mcp add acquia-source-mcp <ACQUIA_SOURCE_SITE_MCP_URL>
    
    Then run /mcp, select acquia-source-mcp, and click Authenticate to complete the OAuth flow (dynamic client registration — no manual client_id needed).

What it exposes (read-only resources + write tools, via drupal:// and canvas:// URIs):

  • Content Management — content types, media types, vocabularies, text formats; create/update nodes, media, taxonomy terms.
  • Content Modeling — field storages, field types; create content types and add fields.
  • Drupal Canvas — components and pages; manage layouts and component properties.

Prefer the MCP server over hand-rolled JSON:API calls when an agent needs to model content or edit Canvas layouts conversationally; use JSON:API/the Page API for deterministic, scripted deploys.

Canvas Code Components — CLI workflow

Scaffold and manage React/JSX Code Components with the official tooling (install the official Canvas skills for the component-authoring rules — don't reinvent them):

  • npx @drupal-canvas/create@latest — scaffold a codebase (default template: acquia/nebula, which ships AGENTS.md + SETUP.md with the Page API reference and pitfalls).
  • npx canvas download / npx canvas upload -c <comp1,comp2> -y — pull/push components between repo and site. canvas.config.json (committed) defines structure; .env (uncommitted) holds the secrets above.

Canvas Page API — deploying a page

Pages are built by uploading components, then PATCHing the page with a full component tree. The hard-won rules (these cost hours otherwise):

  • Each PATCH replaces the ENTIRE page. Never build incrementally with multiple PATCHes — assemble the complete component tree and send it in one atomic request.
  • Version hashes change on every upload. Re-discover all component version hashes after each canvas upload; never hardcode them. Only changed components get new hashes.
  • FormattedText strips inline style attributes on the live site (works in Storybook, fails live). For text alignment add a layout prop (left_aligned/center_aligned/right_aligned) with CVA variants — never inline style="text-align:…".
  • The Image component needs Drupal media-pipeline URLs (with alternateWidths). External URLs / data URIs are accepted without error but render as invisible 0×0 images live. For logos use inline SVG/text; for content images upload as Drupal media first.
  • No raw hex colors as props — use CVA variants mapped to Tailwind theme tokens in global.css.
  • Padding stacks: section adds px-4, grid_container adds px-6 → ~80px on a 375px screen. Use responsive prefixes (px-0 md:px-6) on inner containers.
  • Empty slot containers need min-w-*/min-h-* so they stay interactive in the Canvas editor.
  • Deploy script pattern: read .env → client-credentials token → discover all version hashes in one pass → build the tree (parents before children, fresh UUID per instance, inputs as a json.dumps() string) → single PATCH. Keep a VERSIONS dict at the top.

Docs

Version History

  • eb9b3d3 Current 2026-07-25 05:35

Same Skill Collection

skills/canvas-contribution/SKILL.md
skills/drupal-at-your-fingertips/SKILL.md
skills/drupal-canvas-sdc/SKILL.md
skills/drupal-config-mgmt/SKILL.md
skills/drupal-config-reconcile/SKILL.md
skills/drupal-contrib-mgmt/SKILL.md
skills/drupal-ddev/SKILL.md
skills/drupal-search-api/SKILL.md
skills/drupal-simple-oauth/SKILL.md
skills/drupal-testing/SKILL.md
skills/ivangrynenko-cursorrules-drupal/SKILL.md
skills/skill-developer/SKILL.md
skills/drupal-canvas/SKILL.md

Metadata

Files
0
Version
eb9b3d3
Hash
75713c99
Indexed
2026-07-25 05:35

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-21 07:42
浙ICP备14020137号-1 $Гость$