Skip to content

Building a CMS Adapter

A CMS adapter installs through the platform, keeps its settings in the platform’s own store, and adds a chat page and admin pages. This page compares how the six CMS adapters solve the same problems, so a new adapter can follow the closest one.

  • The same three tables: phpclaw_conversations, phpclaw_messages and phpclaw_memory, with the platform’s table prefix.
  • The same settings: provider, model, API key, base URL, system prompt, store messages, max iterations (default 20), remote skill URLs, and the three cloud fields.
  • A fixed memory driver. None of the six lets the site owner choose one.
  • A permission for using the chat, a higher tier for seeing every user’s conversations, and an owner column on phpclaw_conversations.
  • Two commands: one to send a message and one to start the MCP server. No command reads or deletes stored conversations.
  • Lifecycle events forwarded into the platform’s own event system, and a way for other extensions to add tools, guards, hooks, skills, memory drivers and providers.
PlatformSettings stored inMemory driver
WordPressthe phpclaw_settings optionwpdb_router
Joomlathe System - phpClaw plugin’s parametersjoomladb
Drupalthe phpclaw.settings config objectdatabase
Magentocore_config_data under phpclaw/router memory
PrestaShopConfiguration keys prefixed PHPCLAW_ps_router
OpenCartOpenCart’s settingsoc_router

There is no shared adapter base class. Each CMS builds the agent in its own classes:

PlatformClasses
WordPressPlugin::getInstance() and the static Engine\EngineFactory::build()
JoomlaEngine\EngineFactory::build(), with EngineBootstrapper and ToolBuilder
DrupalPhpClawRegistrar, and PhpClawServiceFactory::create() or createChat() for the two tool sets
MagentoFactory\PhpClawFactory::create() behind PhpClawFactoryInterface
PrestaShopPlugin::getInstance() and Engine\EngineFactory::build()
OpenCartPlugin::getInstance() and Engine\OcEngineFactory::build(); Factory\PhpClawFactory::create() for PhpClawLibrary

Drupal’s admin pages are the controllers PhpClawAboutController, PhpClawAnalyticsController, PhpClawChatController, PhpClawChatStreamController and PhpClawGuideController.

No CMS adapter runs agent work in the background: there is no queue or scheduled job for agent runs.

PlatformUse the chat and toolsSee every conversationOwner column
WordPressphpclaw_use_chat (derived from manage_options or edit_posts)phpclaw_manage_all_conversationsuser_id
Joomlaphpclaw.chat.use on com_phpclawphpclaw.chat.managealluser_id
Drupaluse phpclaw chatmanage all phpclaw conversationsuser_id
MagentoPhpClaw_Magento::phpclaw_chatPhpClaw_Magento::phpclaw_settingsadmin_user_id
PrestaShopview on the Chat tabthe SuperAdmin profileid_employee
OpenCartaccess on the phpClaw routeaccess on the route’s /manage_allowner_id

Conversations created from the command line store 0 as the owner in every adapter. When you write a check that spans adapters, take the owner column as a parameter.

In each adapter the chat permission reaches every platform tool, except raw SQL in PrestaShop (SuperAdmin) and OpenCart (/manage_all). Treat it as administrator-level.

PlatformRoutesAuthentication
WordPress/wp-json/phpclaw/send, /wp-json/phpclaw/chat/streamWordPress REST authentication
Joomlaapi/index.php/v1/phpclaw/chat, .../chat/streamJoomla API token
Drupal/api/phpclaw/send, /api/phpclaw/chat/streamDrupal authentication providers
Magento/rest/V1/phpclaw/send, /rest/V1/phpclaw/chat/streamadmin bearer token
PrestaShopthe module front controller, action=send or action=chat/streamper-employee bearer token or back office session
OpenCartnone; the chat uses admin routesadmin session

Admin-only actions stay off these routes. WordPress’s chat page and Test Connection use admin-ajax.php (phpclaw_send, phpclaw_stream, phpclaw_test_connection). Joomla’s settings save, plugin enable and Test Connection run through the component’s admin ApiController, behind core.admin.

PlatformSend a messageMCP server
WordPresswp phpclaw sendwp phpclaw mcp-server
Joomlaphp cli/joomla.php phpclawphp cli/joomla.php phpclaw:mcp-server
Drupaldrush phpclaw:rundrush phpclaw:mcp-server
Magentobin/magento phpclaw:runbin/magento phpclaw:mcp-server
PrestaShopphp modules/phpclaw/cli/phpclaw.php send... mcp-server
OpenCartphp cli/phpclaw.php send... mcp-server

An MCP server started from the command line must build file_write with PHP writes off and must not skip the raw-SQL permission just because it runs in a terminal. See the cautions on the PrestaShop and OpenCart pages.

PlatformLifecycle events forwarded asExtensions add through
WordPressaction phpclaw_{event}filters phpclaw_extra_tools, _guards, _hooks, _skills, _memory_drivers, _providers
Joomlaevent onPhpClaw{Event}, currently delivers nothingplugin events onPhpClawExtraTools, ...Guards, ...Hooks, ...Skills, ...MemoryDrivers, ...Providers
DrupalPhpClawEvent named phpclaw.{event}service tags phpclaw.tool, phpclaw.guard, phpclaw.skill, phpclaw.provider, phpclaw.memory_driver, phpclaw.hook_listener
Magentoevent phpclaw_{event} with dots as underscoresobservers of phpclaw_extra_tools, _skills, _guards, _hooks, _memory, _providers
PrestaShophook actionPhpClaw{Event}hooks actionPhpclawExtraTools, ...Guards, ...Hooks, ...Skills, ...Memory, ...Providers
OpenCartevent phpclaw/{event}events phpclaw/extra/tools, .../guards, .../hooks, .../skills, .../memory, .../providers

All forward the 40 events of PhpClaw\Hooks\LifecycleEvent, except Joomla, whose bridge delivers no event. See Hooks and Joomla: lifecycle events.

WordPress checks for updates on WordPress’s own pre_set_site_transient_update_plugins filter and caches the answer for 12 hours; OpenCart and PrestaShop show a notice from their own AutoUpdater. On PrestaShop 9, Controller::ajaxDie() no longer exists, so admin JSON goes through AdminPhpClawBaseController::respondJson(), which works on 8 and 9.

For each adapter’s full reference, see All Adapters.