Skip to main content
Version: 4.0 preview

Latest features: the MCP server

Version
4.0 preview
Updated
View markdown

An AI assistant can build your catalog — and run the store around it. CBX ships a Model Context Protocol server: the component exposed to an assistant as real, typed tools rather than described to it in prose. It reads every registered entity, authors products, pages, questions and answers, writes conditional rules and calculations, moves whole products between installs, and carries the admin operations that have no record to write — caches, migrations, charset, order status. It runs over stdio and over HTTP, where a scoped token decides what it may reach.

Back to Latest features


Two transports, one server

Over stdio, registered with a client rather than run by hand. It has to run under the site's own PHP — the same environment a web request gets — and --read-only is the sensible default, because it withholds every write tool. There is a per-host invocation for Joomla, WordPress and Magento 2.

claude mcp add configbox -- ddev exec php docroot/cli/joomla.php configbox:mcp --read-only

Over HTTP, at POST /cb-api/v1/mcp, authenticated with the same scoped bearer tokens the REST surface uses — so an assistant that is not on the machine can be given exactly the areas it needs and nothing else.

The two differ only in how trust arrives: shell access for stdio, a token's scopes over HTTP. Both call the same handler over the same tool registry, so they cannot drift apart.

What the tools do

Reads cover every registered entity — the same registry the HTTP API serves, so anything the REST surface lists can be described, listed and read here under the same name. Writes stay curated to the authoring entities.

ToolFor
cbx_describe_entityThe fields, their JSON types, which are required and read-only, the listing columns, the filters, the active languages — and, named explicitly, the fields this server cannot represent yet
cbx_list_entities / cbx_get_entityA page of records with the unfiltered total; one full record
cbx_create_entity / cbx_update_entity / cbx_delete_entityAuthoring, one record at a time; an update takes only the fields you want changed
cbx_delete_product_deepA product and its whole graph, with a dry_run that reports the same plan and blockers and changes nothing
cbx_describe_rules / cbx_describe_calculationsEverything needed to author one: the vocabulary, its schema, the operators, worked examples, and the product's questions and answers with ids and titles
cbx_get_calculation / cbx_set_calculationA calculation body as one coherent object
cbx_export_product / cbx_check_product_package / cbx_import_product_packageProduct transfer, end to end
cbx_describe_install / cbx_describe_customizationWhat this install is — version, host, languages — and what a customization has added across every seam
cbx_clear_cache, cbx_apply_migrations, cbx_unblock_migrations, cbx_convert_charset, cbx_purge_orphaned_strings, cbx_set_system_var, cbx_set_order_statusThe admin operations — the things with no record to write, one tool each

Writes run the real pipeline

A record written through MCP goes through prepareForStoragevalidateDatastore — the model's own pipeline, the same one an admin form runs. A rejection carries the same wording an operator would see ("Field Title cannot be empty."). That is not a nicety: it is why an assistant cannot put data in the catalog that the admin UI would have refused.

Worth reading before granting write access: writes go straight to the live store — no staging and no undo. What stands between a tool and the data is the scope check, and it is the same one on both transports.

The schemas are generated, not written

The tool schemas come from the same property definitions the admin forms and the OpenAPI document come from. A hand-written tool schema drifts from the model the first time somebody adds a field; a generated one cannot. This is also why cbx_describe_entity can state what it cannot represent — the generator knows.

Rules and calculations, in a form a model can actually emit

This is the part that took real design. CBX stores a rule as an infix token stream — conditions alternating with combinator items, brackets as bare nested arrays, negation as a positional sentinel. That is fine for an editor building a rule left to right and hostile to a model emitting one: every combinator is positional, a missing one changes the meaning silently, and a malformed rule does not throw — it evaluates to false, which quietly hides the question it governs. Authored wrongly, it looks exactly like authored correctly until a customer notices a missing option.

So the MCP surface speaks a nested form where the structure carries the meaning, and translates both ways:

{"all": [ {"question": 11, "operator": "==", "value": 22},
{"any": [ {"question": 13, "operator": "==", "value": 30},
{"question": 14, "operator": "==", "value": 40} ]} ]}

Calculations get the same treatment: the parent row is an ordinary entity, but the body — a formula's term list, a matrix with its axes and every cell, a code body parse-checked before it can be stored — moves as one coherent object, because row-level CRUD can validate rows and not the whole.

Moving products, and reading the assistant's journal

Two more things the server reaches: the product transfer tools, so an assistant can lift a product from one install and check what importing it elsewhere would do before doing it — and the chat advisor's conversations, turns and events as read-only entities, which is what lets an analysis agent read a store's assistant traffic as data.

Extending it

A customization that adds a model to the registry gets MCP coverage without writing a tool — the same registration that puts it on the HTTP API.


Next: the AI assistant · payments & commerce · back to Latest features