Skip to content

phpClaw for Magento

The Magento adapter is the PhpClaw_Magento module. It adds admin pages under PhpClaw, two bin/magento commands, two REST routes, and 17 tools.


RequirementVersion
PHP8.1 or later
Magento2.4
Terminal window
composer require phpclaw/phpclaw-magento
bin/magento module:enable PhpClaw_Magento
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

setup:upgrade creates phpclaw_conversations, phpclaw_messages and phpclaw_memory, and grants the phpClaw ACL resources to every role that already has full admin access.

Set a provider and key on PhpClaw → Settings, or from the command line:

Terminal window
bin/magento config:set phpclaw/general/provider anthropic
bin/magento config:set phpclaw/general/api_key sk-ant-...
bin/magento cache:flush
bin/magento phpclaw:run "check order queue status"

phpClaw in a Magento store

To update the module later:

Terminal window
composer update phpclaw/phpclaw-magento --with-dependencies
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

Settings are stored in core_config_data:

PathDefaultNotes
phpclaw/general/provideremptythe provider to use
phpclaw/general/modelemptythe provider’s default model
phpclaw/general/api_keyemptystored encrypted when saved from Settings, as are cloud_key and cloud_signing_secret
phpclaw/general/base_urlemptyfor the Custom provider; must be https:// and not an internal address
phpclaw/general/system_promptemptyadded to every request
phpclaw/general/store_messages1
phpclaw/general/max_iterationsempty, meaning 20
phpclaw/general/remote_skill_urlsemptyHTTPS URLs of skill files
phpclaw/general/cloud_key, cloud_signing_secret, cloud_disableemptyconfigure phpClaw Cloud; the key is used only while store_messages is on
phpclaw/security/shell_allowlistemptycomma separated; empty uses core’s default allowlist
phpclaw/security/tool_denyemptycomma-separated tool names or groups

With store_messages off, the agent stores no message content. See Memory.

If provider and api_key are both empty, phpClaw core still detects a provider from the server’s environment variables, such as OPENAI_API_KEY. Set the provider explicitly.


etc/acl.xml declares a PhpClaw_Magento::phpclaw parent with one resource per page:

ResourceAllows
PhpClaw_Magento::phpclaw_settingsthe Settings page and Test Connection, and seeing every admin’s conversations
PhpClaw_Magento::phpclaw_chatthe Chat page, both REST routes, and every Magento tool
PhpClaw_Magento::phpclaw_analyticsthe Analytics page
PhpClaw_Magento::phpclaw_guidethe Guide page
PhpClaw_Magento::phpclaw_aboutthe About page

Grant them to a role under System → Permissions → User Roles → Role Resources.

A tool call without the resource returns a FORBIDDEN error.

The adapter treats every Magento area other than adminhtml and webapi_rest as the console. In those areas the tool check is skipped, conversations store no owner, and file_write may create PHP files. That includes bin/magento and cron, and also the frontend, graphql and webapi_soap areas.


All 17 are registered on every run:

GroupTools
Magentomagento_products, magento_inventory, magento_categories, magento_stores, magento_report, magento_cache, read_log, magento_orders, magento_customer, db_query
Coreshell_exec, http_request, file_read, file_write, file_edit, code_search, project_info
ToolDoes
magento_productsfetches a product by SKU or searches products
magento_inventoryshows stock for a SKU, or lists products at or below a stock threshold
magento_categorieswalks the category tree: top level, children of a category, or products in one
magento_storeslists websites, store groups and store views as a hierarchy
magento_reportsales report for a date range: revenue, orders, average order value or top products
magento_cacheshows each cache type’s state; it never flushes
read_logreads the last lines of var/log/system.log
magento_ordersfetches an order by increment id, or lists orders by status and date
magento_customerlooks up a customer by email or id, or counts customers
db_queryruns one read-only SELECT

See Tools for the core tools.

db_query runs one read-only SELECT, adds LIMIT 500 when the query has no limit, and refuses the core_config_data, phpclaw_conversations and phpclaw_messages tables. Modules keep credentials such as API keys in core_config_data, and no phpClaw tool reads that table.

GroupTools
group:commercemagento_products, magento_orders, magento_customer, magento_inventory
group:catalogmagento_categories, magento_stores, magento_report
group:systemmagento_cache, db_query, read_log
Terminal window
bin/magento config:set phpclaw/security/tool_deny "group:system,shell_exec"

Every agent is built with CliApprovalGate. In a terminal you are asked before a tool changes something; in the admin and the REST API there is nobody to ask, so the change is refused. See Security: approval. The MCP server does not use the approval gate, and its file_write cannot create PHP files.


Terminal window
bin/magento phpclaw:run "check order queue status"
bin/magento phpclaw:run "summarise today's orders" --stream
bin/magento phpclaw:run "and yesterday?" --conv-id=01JQABCDE...
bin/magento phpclaw:mcp-server

phpclaw:run takes --stream and --conv-id. phpclaw:mcp-server serves the tools over stdio; see MCP.


Both routes need an admin bearer token whose user holds PhpClaw_Magento::phpclaw_chat:

Terminal window
curl -X POST "https://example.com/rest/V1/integration/admin/token" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"..."}'
MethodRouteBodyReturns
POST/rest/V1/phpclaw/sendmessagetext, provider, model, tokens, iterations
POST/rest/V1/phpclaw/chat/streammessage, optional conversationIdServer-Sent Events
Terminal window
curl -X POST "https://example.com/rest/V1/phpclaw/send" \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{"message":"how many orders came in today?"}'

send starts a new conversation on every call. An empty message is a 400, a guard block 422, and any other failure 500.

chat/stream sends tool_before, tool_after, chunk, then done or error. Naming another admin’s conversation is refused before the stream starts.


Each conversation stores its creator’s admin user id in phpclaw_conversations.admin_user_id: from the admin session, or from the token for REST calls. Conversations created in a console area store 0. An admin sees and opens only their own conversations; opening another’s is refused with 403. Admins holding PhpClaw_Magento::phpclaw_settings see every conversation.

Model/IdentityResolver reads the backend session and, for REST calls, Magento’s user context, which it accepts only for admin tokens. A REST call made with an integration token is stored without a user, so authenticate as an admin user when each conversation should belong to a person. admin_user_id is written on insert and is not in the update columns, so a later save cannot change the owner. The index is PHPCLAW_CONV_USER_NS_UPDATED in etc/db_schema.xml. Analytics caches its counts under a key that includes the acting admin id, or all for the manage-all tier.

The agent always uses the database-backed router memory, RouterMemory: the conversations namespace goes to ConversationMemory, everything else to ResourceMemory and phpclaw_memory. RuntimeMemory resolves the configured driver on each call.

Inject PhpClaw\Magento\Factory\PhpClawFactoryInterface and call create(), which returns a fully configured PhpClaw\Contracts\ClawInterface. The module declares the preference in etc/di.xml. The module does not register PhpClaw\Claw itself, and building one by hand skips the settings, memory and Magento tools.

use PhpClaw\Magento\Factory\PhpClawFactoryInterface;
final class OrderSummary
{
public function __construct(private readonly PhpClawFactoryInterface $phpClawFactory) {}
public function summarise(): string
{
return $this->phpClawFactory->create()->send('Summarise today\'s orders.')->text;
}
}

A module registers additions by observing these events and adding entries to the transport object:

EventAdds
phpclaw_extra_toolstools; a tool with the same name as a built-in replaces it
phpclaw_extra_skillsskills
phpclaw_extra_guardsguards
phpclaw_extra_hookslifecycle listeners
phpclaw_extra_memorymemory drivers
phpclaw_extra_providersproviders

Every lifecycle event is also dispatched as a Magento event named phpclaw_ followed by the event name with dots replaced by underscores, such as phpclaw_agent_after, with the context under data. The event names are listed on the Hooks page.