Skip to content

Drupal CMS 2.x Baseline Stack

Authority: Thomas Towne, 2026-09-22
Bead: bc-5o48
Status: Canonical
Applies to: All Bluefly Drupal sites (ContextControl, bluefly.io, DrupalWorks projects)

Governing Principle

No pinned versions. Always let Composer resolve the newest compatible release.

No custom code until every upstream option is exhausted. The hierarchy is:

Core → Contrib → Recipes → Canvas/SDC → ECA/FlowDrop → Drupal AI → Tool API/MCP → only then custom code

Stability Configuration

Several important current projects are still beta/alpha — Tool API, MCP Server, AI Context, Canvas Builder, AI Search, Tool Belt. A truly versionless install needs minimum-stability: dev plus prefer-stable: true. The dev level is required because some packages (e.g., drupal/ai_search 2.0-alpha) depend on dev-branch versions of drupal/ai 2.x which has no tagged release yet. When drupal/ai 2.0 ships a tagged alpha, minimum-stability can be tightened to alpha.

Transitional note (2026-09-22): drupal/ai_search 2.0-alpha requires drupal/ai ^2.0 (dev-only). drupal/drupal_cms_ai requires drupal/ai ^1.2.6. Until the ecosystem converges, use drupal/ai_search:^1.0 (which works with AI 1.x) and track the 2.0 line for future upgrade.

composer config minimum-stability dev
composer config prefer-stable true

Canonical Dependency Set

composer require \
  'drupal/drupal_cms_ai' \
  \
  'drupal/ai' \
  'drupal/ai_agents' \
  'drupal/ai_agents_debugger' \
  'drupal/ai_agents_ossa' \
  'drupal/ai_context' \
  'drupal/ai_dashboard' \
  'drupal/ai_integration_eca' \
  'drupal/ai_policy_gateway' \
  'drupal/ai_content_suggestions' \
  'drupal/ai_content_strategy' \
  'drupal/ai_image_alt_text' \
  'drupal/ai_translate' \
  \
  'drupal/ai_provider_openai' \
  'drupal/ai_provider_anthropic' \
  'drupal/ai_provider_ollama' \
  \
  'drupal/tool' \
  'drupal/tool_belt' \
  \
  'drupal/mcp_server' \
  'drupal/mcp_tools' \
  \
  'drupal/canvas' \
  'drupal/canvas_builder' \
  'drupal/canvas_ai_seo' \
  'drupal/ai_playwright' \
  \
  'drupal/eca' \
  'drupal/ai_integration_eca' \
  'drupal/modeler_api' \
  'drupal/modeler' \
  'drupal/bpmn_io' \
  'drupal/flowdrop' \
  'drupal/flowdrop_ai_search' \
  'drupal/orchestration' \
  \
  'drupal/search_api' \
  'drupal/ai_search' \
  'drupal/ai_search_block' \
  'drupal/ai_vdb_provider_qdrant' \
  \
  'drupal/key' \
  'drupal/metatag' \
  'drupal/simple_sitemap' \
  \
  'drupal/sdc_critical_css' \
  'drupal/non_critical_css' \
  --no-update

composer update -W

Architecture Chain

Each layer builds on the one above. The baseline follows this composition:

Drupal CMS
  ↓
Canvas / SDC
  ↓
Drupal AI
  ↓
AI Agents
  ↓
Tool API
  ↓
MCP
  ↓
ECA / Modeler / FlowDrop
  ↓
AI Context
  ↓
Search API / AI Search / Qdrant
  ↓
Observability / Policy / Evidence

Layer Rationale

Layer Packages Why
Drupal AI ai, ai_agents, ai_agents_debugger, ai_agents_ossa, ai_dashboard Provider abstraction. Drupal CMS's official AI recipe already installs AI Core, AI Agents, AI Dashboard, AI Image Alt Text, Canvas, Key, Anthropic, and OpenAI.
AI Content ai_content_suggestions, ai_content_strategy, ai_image_alt_text, ai_translate Content-level AI capabilities via upstream contrib.
AI Providers ai_provider_openai, ai_provider_anthropic, ai_provider_ollama Provider plugins. No pinned versions.
Tool API tool, tool_belt Typed executable Drupal capabilities. Tool Belt provides reusable tools instead of writing them again.
MCP mcp_server, mcp_tools External agent/tool boundary. Use mcp_server, not build our own MCP layer. Drupal's older mcp project itself now recommends MCP Server as the direction of travel.
Canvas canvas, canvas_builder, canvas_ai_seo, ai_playwright Modern Drupal composition/UI. Canvas is now stable and actively shipping.
ECA / Workflows eca, ai_integration_eca, modeler_api, modeler, bpmn_io, flowdrop, flowdrop_ai_search, orchestration Event automation and visual workflows rather than custom workflow code. Modeler API exists to stop every project from building its own visual editor. Orchestration exposes Drupal capabilities to outside automation.
AI Context ai_context Governed context/memory layer instead of creating another custom memory framework.
Search search_api, ai_search, ai_search_block, ai_vdb_provider_qdrant Semantic search/RAG on the existing Search API architecture. Qdrant has an existing provider.
AI Policy ai_policy_gateway Governance, routing, privacy/redaction, budgets, and approvals rather than adding another model integration.
SEO / Performance key, metatag, simple_sitemap, sdc_critical_css, non_critical_css Standard baseline for all production Drupal sites.

Explicitly NOT Included

Package Reason
drupal/ai_logging Drupal AI now recommends its own AI Observability submodule instead. Avoids another database-heavy logging system and gives PSR-3/OpenTelemetry integration.
drupal/mcp_server, drupal/mcp_tools Deferred, not excluded. These are the canonical MCP packages but require mcp/sdk ^0.6+. Sites using bluefly/ai_agents_client (which pins mcp/sdk 0.2.x) will conflict. Upgrade ai_agents_client first, then add these.
Random "AI foo" modules Ultimate ≠ maximal dependencies. Own the smallest composition that gives the widest capability.

Applying to a New Site

# 1. Start from Drupal CMS
composer create-project drupal/cms my-site

# 2. Set stability
cd my-site
composer config minimum-stability alpha
composer config prefer-stable true

# 3. Require the baseline (copy the require block above)
composer require ... --no-update
composer update -W

# 4. Apply the DrupalWorks baseline recipe
php core/scripts/drupal recipe recipes/bluefly-baseline

DrupalWorks Recipe

The canonical recipe lives at drupalworks/recipes/bluefly-baseline/recipe.yml. Any new Bluefly Drupal site consumes this recipe to inherit the full baseline without manually running the Composer commands.

Maintenance

  • Adding packages: Propose via Bead. Must fit within an existing architecture layer. No orphan dependencies.
  • Removing packages: Only when upstream replaces the capability or the project is abandoned.
  • Version constraints: NONE. Let Composer resolve. If a specific version is required for compatibility, document the reason and set a reminder to remove the constraint.