Just enough examples to let Your AI agent run PHP inside Magento without breaking anything.
Sometimes the fastest way to answer a question about a store is to just ask Magento. What does this repository return for that SKU? Which class does the ObjectManager give me in the frontend area? We all have a test.php in the root for exactly that. code-runner is the same idea, but built for agents and with guard rails.
code-runner(code, area="", allow_write=false, timeout=30, mode="execute")
| Parameter | Default | Description |
|---|---|---|
code |
required | PHP code, without <?php tags |
area |
"" |
frontend, adminhtml, webapi_rest, graphql, crontab, global |
allow_write |
false |
when false, DB changes are rolled back |
timeout |
30 |
max execution time in seconds |
mode |
execute |
execute runs code; define saves reusable functions for the session |
The safety model in short:
- every call runs inside a DB transaction that is always rolled back unless
allow_write=true, so You will seeread_only: trueeven for code that writes nothing - code is checked against 9 dangerous patterns: shell execution, file writes, superglobals, cURL, eval, header manipulation, global handler registration, long sleeps
- no network access for executed code
- disabled in production deploy mode, no way around it
- runs through PsySH when available (it ships as a dependency),
evalas a fallback;bricklayer verifytells You which one
Helpers and examples
Inside the executed code You get:
$get(ClassName::class)- singleton from the DI container$create(ClassName::class, ['arg' => val])- new instance$repo(RepositoryInterface::class)- alias for$get(), reads nicer for repositories$config('section/group/field')- system config valuequery('SELECT ...', $binds)- read-only SELECT, returns rowsrunLog($value, 'label')- capture values into the responselogkey
Full guide with variables, areas and examples is one call away: code-runner-help.
- Read a product through the service layer:
code-runner(code="return $repo(\Magento\Catalog\Api\ProductRepositoryInterface::class)->get('24-MB01')->getName();")
- Which implementation does the frontend area actually get?
code-runner(area="frontend", code="return get_class($get(\Magento\Checkout\Model\Session::class));")
- Config value and a quick query, both captured:
code-runner(code="runLog($config('web/secure/base_url'), 'base_url'); runLog(query('SELECT COUNT(*) AS c FROM catalog_product_entity'), 'products');")
- Reusable functions for the session (
mode=define, max 20, cleared onreinitialize):
code-runner(mode="define", code="function getProductBySku($sku) { return get(\Magento\Catalog\Api\ProductRepositoryInterface::class)->get($sku); }")
code-runner(code="$p = getProductBySku('24-MB01'); return $p->getName();")
Every response includes metrics: execution time, memory delta, peak memory and number of queries. Handy for a quick “how expensive is this load” check.
Writes and limits
Want the change to stick? Check both places:
tools.code-runner.allow_writein.bricklayer.jsonmust allow it (developer default isfalse)- the call itself must pass
allow_write=true
vendor/bin/bricklayer config:set tools.code-runner.allow_write true
My advice: leave writes off. If the agent needs to change data, the catalog, order and customer tools go through Magento’s service layer and each one can be switched on or off separately. code-runner is for looking.
tools.code-runner.max_timeoutcaps thetimeoutparameter (default 60)- in production
code-runneris hard-blocked, the config file can not enable it - functions defined with
mode=definelive until the session ends orreinitializeruns
Start coding!
Source: GitHub