phpClaw for OpenCart
The OpenCart adapter is an extension with separate builds for OpenCart 3 and 4. It adds admin pages, opened from its module entry phpClaw AI Agent, a CLI script, and 13 tools.
Install
Section titled “Install”| Requirement | Version |
|---|---|
| PHP | 8.1 or later |
| OpenCart | 3 or 4 |
Download for OpenCart 4 (.ocmod.zip)
Download for OpenCart 3 (.ocmod.zip)
Upload the ZIP for your version under Extensions → Installer, then install the module under
Extensions → Extensions → Modules. Installing creates phpclaw_conversations, phpclaw_messages
and phpclaw_memory, and gives the installing admin’s user group every phpClaw permission.
Then open phpClaw AI Agent from Extensions → Extensions → Modules and use its Settings button to choose a provider and enter the API key. The extension adds no entry to the admin menu.
Need a specific version? Browse all releases →

The Settings page shows when a newer version is available. Installing runs Plugin::runMigration(),
whose CREATE TABLE IF NOT EXISTS statements leave existing tables and rows in place.
Settings
Section titled “Settings”The Settings page stores provider, model, API key, Base URL (for the Custom provider; https://,
or http:// on localhost, 127.0.0.1 or ::1), system prompt, Store Messages (on by default), max
iterations (1 to 50, default 20), Remote Skill URLs and the phpClaw Cloud fields in OpenCart’s
settings. Cloud is used only while Store Messages is on.
Remote Skill URLs keeps only https:// URLs whose path ends in .md or .json.
With Store Messages off, the agent stores no message content. See Memory.
Seven more fields switch on the building blocks:
| Field | Notes |
|---|---|
| Fallback Provider | Off by default; lists only providers with the same tool format as the provider, never Custom |
| Fallback Model | empty uses the fallback provider’s default |
| Fallback API Key | hidden when Fallback Provider is Off or Ollama |
| Rate Limit (requests/min) | 0 to 600, default 0 (off) |
| Response Cache | off by default |
| Response Cache TTL (seconds) | shown when Response Cache is on; 60 to 86400, default 3600 |
| Max Token Budget | 0 to 10,000,000, default 0 (off) |
The rate limit and the response cache are kept as files in a phpclaw folder under OpenCart’s cache
directory. In Chat, a spent token budget
answers 422 with “Token budget reached for this run.” and a rate limit 429 with “Rate limit reached,
try again shortly.”; the CLI prints the same message.
Separately from the Rate Limit field, the extension always registers core’s rate limit guard at 60 messages per minute per client IP, counted in APCu (without APCu it counts per PHP process only). Past it, Chat answers “Request blocked by security guard.” with status 200.
Two fields set which tools the model is offered:
| Field | Notes |
|---|---|
| Max Tools Per Turn | default 0, the automatic per-turn limit; -1 turns the limit off, though the token budget can still drop tools; below -1 is saved as -1 |
| Always Include Tools | comma-separated tool names offered on every turn, outside the limit; a name that is not a tool on the store is skipped, and a tool in tool_deny stays denied |
The module’s config/phpclaw.php holds settings with no form field: workspace_root (default
phpclaw under OpenCart’s storage directory), shell_allowlist (core’s default), tool_deny,
guards, hooks, skills, events_bridge and update_server. Several can be set by defining a PHP constant, such
as PHPCLAW_SHELL_ALLOWLIST. shell_allowlist sets the commands a ShellTool added through the
phpclaw/extra/tools event may run.
Permissions
Section titled “Permissions”phpClaw uses OpenCart’s route permissions, set under System → Users → User Groups. On OpenCart 3
the route is extension/module/phpclaw; on OpenCart 4 it is extension/phpclaw/module/phpclaw.
| Permission | Allows |
|---|---|
access on the phpClaw route | the Chat, Analytics, Guide and About pages, and every OpenCart tool except raw SQL |
modify on the phpClaw route | sending messages from the Chat page |
access on the route followed by /manage_all | the Settings page, Test Connection, seeing every admin’s conversations, and db_query |
An OpenCart tool call without access returns a FORBIDDEN error. db_query without /manage_all
fails with an error saying raw SQL needs the manage-all permission. The CLI script skips both checks.
13 tools, plus core’s load_skill, which the chat and CLI agent get because core’s discovered
skills, at least php_best_practices, are always registered. The Guide page and the MCP server list the 13:
| Group | Tools |
|---|---|
| OpenCart | oc_product, oc_category, oc_manufacturer, oc_order, oc_customer, oc_review, oc_coupon, oc_shipping, db_query, read_log |
| Core | code_search, project_info, file_read |
db_query runs one read-only SELECT and refuses the setting table, where extensions keep their
credentials, and the phpclaw_conversations and phpclaw_messages tables. See Tools for the core tools.
| Tool | Does |
|---|---|
oc_product | searches and inspects products with stock and pricing |
oc_category | browses the category hierarchy |
oc_manufacturer | lists and searches manufacturers |
oc_order | searches and inspects orders with revenue and status |
oc_customer | searches and inspects customers with order history statistics |
oc_review | lists reviews by product, rating or status |
oc_coupon | lists active and expired coupons and their usage |
oc_shipping | searches and inspects shipping methods |
db_query | runs one read-only SELECT |
read_log | reads and searches system/storage/logs/error.log |
shell_exec, http_request, file_write and file_edit are not registered: core marks them
opt-in, and the module asks core only for its default tools. A listener for the phpclaw/extra/tools
event adds tools as objects or as class names. An object is used as it is. The class name
\PhpClaw\Tools\ShellTool::class is built with shell_allowlist, and FileWriteTool::class and
FileEditTool::class with workspace_root, both from config/phpclaw.php. Any other tool class
whose constructor needs no argument is built with new, and anything else is dropped. A ShellTool
a listener builds with no allowlist uses core’s default, ls, pwd, df, wc, date, uptime,
hostname and whoami, and the allowlist matches the first word of the command exactly, case
included.
Tools added through the phpclaw/extra/tools event are placed before the built-in tools.
Denying tools
Section titled “Denying tools”tool_deny in config/phpclaw.php removes tools by name or group:
| Group | Tools |
|---|---|
group:commerce | oc_product, oc_order, oc_customer, oc_coupon |
group:catalog | oc_category, oc_manufacturer, oc_review |
group:system | db_query, read_log, oc_shipping |
Approval and PHP files
Section titled “Approval and PHP files”Every agent is built with CliApprovalGate. In a terminal you are asked before a tool changes
something; in the admin there is nobody to ask, so the change is refused. See
Security: approval.
file_write, file_edit and shell_exec exist only when added through the phpclaw/extra/tools
event. That event fires only in admin requests, where the gate refuses every file_write and
file_edit call and any shell_exec command on the allowlist but outside core’s read-only command list. The CLI script
builds the agent without OpenCart’s registry, so no phpclaw/extra/* event fires there and those
tools are not added.
The same script ships for both versions. The installer places it at
extension/phpclaw/cli/phpclaw.php on OpenCart 4 and at system/library/phpclaw/cli/phpclaw.php on
OpenCart 3. From the OpenCart 4 root:
# interactive sessionphp extension/phpclaw/cli/phpclaw.php chatphp extension/phpclaw/cli/phpclaw.php chat --conv-id=01JXYZ...php extension/phpclaw/cli/phpclaw.php chat --continue
# one-shot sendphp extension/phpclaw/cli/phpclaw.php send "check low stock products"php extension/phpclaw/cli/phpclaw.php send "summarise today's orders" --stream --provider=groqphp extension/phpclaw/cli/phpclaw.php send "and which of them are out of stock?" --continue --trace
php extension/phpclaw/cli/phpclaw.php mcp-serversend takes --stream, --provider, --model, --conv-id, --continue and --trace, and runs
with every tool including raw SQL. chat opens an interactive session and takes --conv-id and
--continue.
One-shot options and the chat session
Section titled “One-shot options and the chat session”send prints the reply, then [provider:<p> model:<m> tokens:<n> iterations:<n> conversation:<id>] on
stderr; with --stream it prints the reply only. --conv-id=<id> continues that stored
conversation; an id with no stored conversation prints a warning and starts a new one. --continue
picks the last conversation, whose id is kept in phpclaw/.last-conversation in OpenCart’s storage
folder: one value per site, so every shell user continues the same conversation. The CLI reopens
only the conversations it created; another admin’s id prints Conversation <id> is not available to the console and starts a new one. --trace prints one line per tool call on stderr, the tool name
plus a short path or command, never the result.
chat keeps one conversation open, streams each reply and prints the tool calls as they run, then a
line with the provider, model, input and output tokens, the tools that ran and the conversation id.
It needs a terminal: with piped input it refuses and exits 1. A line starting with / is a
command and is never sent to the agent:
| Command | What it does |
|---|---|
/help | List these commands |
/tools | List the active tools |
/model <name> | Switch the model for this session only |
/provider <slug> | Switch the provider for this session only |
/new | Start a new conversation |
/conv | Print the conversation id |
/quiet | Turn the tool trace off or on |
/clear | Clear the screen |
/exit | Leave; Ctrl+D also leaves |
While the agent works, a Thinking... spinner shows until the first word of the reply arrives. It
is not shown when the output is not a terminal, and without the pcntl extension a still
Thinking... line is printed instead of the animation. A failed turn prints one line without the
exception text and the session goes on; the exception goes to the PHP error log, which is the
terminal’s stderr when PHP has no error_log set. On leaving it prints the command to resume.
/model and /provider never write the settings; a provider that cannot be built is named and the
session keeps the current one.
mcp-server serves the tools over stdio; see MCP.
PhpClaw\OpenCart\PhpClawLibrary is the OpenCart registry form. Its send() returns the reply text
and getEngine() returns the agent. It builds the agent with PhpClawFactory, which reads the
provider, model and message storage from PHP constants such as PHPCLAW_PROVIDER and
PHPCLAW_MODEL, not from the Settings page, so the seven fields above do not apply to it. It is
built with no database handle and no OpenCart registry, so no phpclaw/extra/* event fires for it,
and outside the CLI script every OpenCart tool returns FORBIDDEN.
$registry->set('phpClaw', new \PhpClaw\OpenCart\PhpClawLibrary());
$text = $registry->get('phpClaw')->send('Check order queue depth.');Admin pages
Section titled “Admin pages”| Page | Permission | Shows |
|---|---|---|
| Settings | /manage_all | the settings and Test Connection |
| Chat | access (modify to send) | the chat interface with the admin’s conversations |
| Analytics | access | conversation and message counts; store-wide with /manage_all, otherwise the admin’s own |
| Guide | access | the registered tools |
| About | access | extension information |
Conversations and ownership
Section titled “Conversations and ownership”Each conversation stores the creating admin’s user id in owner_id. Conversations created from the
CLI store 0. An admin sees and opens only their own conversations; opening another’s is refused.
The CLI reopens only the 0 conversations it created, never an admin’s.
Admins with /manage_all see every conversation.
The agent always uses the oc_router memory driver, OcRouterMemory, which sends conversations to
OcDbConversationMemory and everything else to OcDbMemory. oc_setting (OcSettingMemory) stores
in OpenCart’s settings table instead. With oc_router, conversations go to the conversation tables,
everything else in phpclaw_memory.
Extending
Section titled “Extending”Extensions register additions through OpenCart events named phpclaw/extra/tools,
phpclaw/extra/guards, phpclaw/extra/hooks, phpclaw/extra/skills, phpclaw/extra/memory and
phpclaw/extra/providers. These events, and the lifecycle events that events_bridge sends as
phpclaw/{event}, fire only in admin requests: the CLI script builds the agent without OpenCart’s
registry.