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.
Install
Section titled “Install”| Requirement | Version |
|---|---|
| PHP | 8.1 or later |
| Magento | 2.4 |
composer require phpclaw/phpclaw-magentobin/magento module:enable PhpClaw_Magentobin/magento setup:upgradebin/magento setup:di:compilebin/magento cache:flushsetup: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:
bin/magento config:set phpclaw/general/provider anthropicbin/magento config:set phpclaw/general/api_key sk-ant-...bin/magento cache:flushbin/magento phpclaw:run "check order queue status"
To update the module later:
composer update phpclaw/phpclaw-magento --with-dependenciesbin/magento setup:upgradebin/magento setup:di:compilebin/magento cache:flushSettings
Section titled “Settings”Settings are stored in core_config_data:
| Path | Default | Notes |
|---|---|---|
phpclaw/general/provider | empty | the provider to use |
phpclaw/general/model | empty | the provider’s default model |
phpclaw/general/api_key | empty | stored encrypted when saved from Settings, as are cloud_key and cloud_signing_secret |
phpclaw/general/base_url | empty | for the Custom provider; must be https:// and not an internal address |
phpclaw/general/system_prompt | empty | added to every request |
phpclaw/general/store_messages | 1 | |
phpclaw/general/max_iterations | empty, meaning 20 | |
phpclaw/general/remote_skill_urls | empty | HTTPS URLs of skill files |
phpclaw/general/cloud_key, cloud_signing_secret, cloud_disable | empty | configure phpClaw Cloud; the key is used only while store_messages is on |
phpclaw/security/shell_allowlist | empty | comma separated; empty uses core’s default allowlist |
phpclaw/security/tool_deny | empty | comma-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.
ACL resources
Section titled “ACL resources”etc/acl.xml declares a PhpClaw_Magento::phpclaw parent with one resource per page:
| Resource | Allows |
|---|---|
PhpClaw_Magento::phpclaw_settings | the Settings page and Test Connection, and seeing every admin’s conversations |
PhpClaw_Magento::phpclaw_chat | the Chat page, both REST routes, and every Magento tool |
PhpClaw_Magento::phpclaw_analytics | the Analytics page |
PhpClaw_Magento::phpclaw_guide | the Guide page |
PhpClaw_Magento::phpclaw_about | the About page |
Grant them to a role under System → Permissions → User Roles → Role Resources.
A tool call without the resource returns a FORBIDDEN error.
What counts as the console
Section titled “What counts as the console”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:
| Group | Tools |
|---|---|
| Magento | magento_products, magento_inventory, magento_categories, magento_stores, magento_report, magento_cache, read_log, magento_orders, magento_customer, db_query |
| Core | shell_exec, http_request, file_read, file_write, file_edit, code_search, project_info |
| Tool | Does |
|---|---|
magento_products | fetches a product by SKU or searches products |
magento_inventory | shows stock for a SKU, or lists products at or below a stock threshold |
magento_categories | walks the category tree: top level, children of a category, or products in one |
magento_stores | lists websites, store groups and store views as a hierarchy |
magento_report | sales report for a date range: revenue, orders, average order value or top products |
magento_cache | shows each cache type’s state; it never flushes |
read_log | reads the last lines of var/log/system.log |
magento_orders | fetches an order by increment id, or lists orders by status and date |
magento_customer | looks up a customer by email or id, or counts customers |
db_query | runs 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.
Denying tools
Section titled “Denying tools”| Group | Tools |
|---|---|
group:commerce | magento_products, magento_orders, magento_customer, magento_inventory |
group:catalog | magento_categories, magento_stores, magento_report |
group:system | magento_cache, db_query, read_log |
bin/magento config:set phpclaw/security/tool_deny "group:system,shell_exec"Approval
Section titled “Approval”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.
Commands
Section titled “Commands”bin/magento phpclaw:run "check order queue status"bin/magento phpclaw:run "summarise today's orders" --streambin/magento phpclaw:run "and yesterday?" --conv-id=01JQABCDE...
bin/magento phpclaw:mcp-serverphpclaw:run takes --stream and --conv-id. phpclaw:mcp-server serves the tools over stdio; see
MCP.
REST API
Section titled “REST API”Both routes need an admin bearer token whose user holds PhpClaw_Magento::phpclaw_chat:
curl -X POST "https://example.com/rest/V1/integration/admin/token" \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"..."}'| Method | Route | Body | Returns |
|---|---|---|---|
| POST | /rest/V1/phpclaw/send | message | text, provider, model, tokens, iterations |
| POST | /rest/V1/phpclaw/chat/stream | message, optional conversationId | Server-Sent Events |
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.
Conversations and ownership
Section titled “Conversations and ownership”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.
Using the agent in code
Section titled “Using the agent in code”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; }}Extending
Section titled “Extending”A module registers additions by observing these events and adding entries to the transport
object:
| Event | Adds |
|---|---|
phpclaw_extra_tools | tools; a tool with the same name as a built-in replaces it |
phpclaw_extra_skills | skills |
phpclaw_extra_guards | guards |
phpclaw_extra_hooks | lifecycle listeners |
phpclaw_extra_memory | memory drivers |
phpclaw_extra_providers | providers |
Lifecycle events
Section titled “Lifecycle events”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.