MCP Backend: How a Script Maps to Tool Calls
mxcli can apply an MDL script in two ways:
- File (MPR) backend — the default. mxcli opens the
.mprdirectly, mutates the BSON in process, and writes it back to disk. No network, no running Studio Pro. - MCP backend (
--mcp) — mxcli connects to a running Studio Pro’s embedded MCP server (“PED”) and applies each change through its tools, so edits land in the live, open model with no save/reload cycle.
The two backends produce the same model, but they have very different cost profiles. The file backend turns one statement into one in-process mutation — effectively free. The MCP backend turns one statement into one or more JSON-RPC tool calls to Studio Pro. This page explains that mapping for domain-model scripts and what it means for latency, token usage, and an LLM’s context window.
The numbers below trace the worked example
mdl-examples/doctype-tests/01-mcp-domain-model-examples.mdl— a ~20-statement domain-model script that stays entirely inside the MCP authoring surface. To see the surface for your connected version, runmxcli mcp capabilities -p app.mpr --mcp.
The mapping
Each MDL statement expands into a small, fixed choreography of PED tool calls. The choreography — not the statement count — drives the cost.
| MDL statement | PED tool calls | Calls |
|---|---|---|
create module | ped_create_module | 1 |
create enumeration | ped_create_document + ped_check_errors | 2 |
create entity (incl. extends) | ped_update_document (add) + ped_check_errors | 2 |
… plus each NOT NULL / UNIQUE rule | ped_read_document (locate entity) + ped_update_document (add rules) | +2 |
create association | 2× ped_read_document (resolve parent/child entity refs) + ped_update_document (add) + ped_check_errors | 4 |
alter entity (add / rename / set documentation) | 2× ped_read_document (locate + read live attrs) + ped_update_document + ped_check_errors | 4 |
show / describe of a just-modified module | ped_read_document (entities + associations) + an enrichment read for attribute types | 2 |
show enumerations (and other reads of unchanged docs) | served from the local .mpr | 0 |
one-time ped_get_schema per element type (entity, attribute, association, validation rule) | fetched once per session, then cached | ~4 total |
initialize handshake | once per connection | 1 |
For a ~20-statement domain-model script like the example, that’s on the order of
60 tool calls — overwhelmingly per-write validation and read-backs, not the
statement count. (Run it with --mcp-trace to see the exact tally for your
script; the precise number shifts as the example evolves.)
See it yourself. Run any script with
--mcp-trace(or--mcp-verbose) to print the actual PED calls each MDL command makes — the runtime view of this table. See Connecting to a Running Studio Pro.
Three things inflate the count
- Validation runs after every write.
ped_check_errorsfires once per write statement, so a large share of the calls are validation alone. This keeps the live model provably consistent at each step, but it is not free. ALTERis read-modify-write. Because PED cannot change an attribute’s type in place, mxcli first reads the live entity (to tell a rename from a drop+add, and to leave untouched attributes alone), then writes. EveryALTER ENTITYis ~4 calls even when it changes one thing.- Reading a module you just wrote costs 2 calls, not 0. After any write, that
module’s on-disk
.mpris stale, soSHOW/DESCRIBEof it is reconstructed live from Studio Pro (a structure read plus an enrichment read for attribute types) instead of being served locally.
What this means for performance
Every tool call is a synchronous JSON-RPC round trip to Studio Pro, executed sequentially. Wall-clock time is therefore roughly:
total ≈ (number of tool calls) × (round-trip latency)
So latency scales with the choreography-expanded call count, not the number of statements. The practical levers:
- Batch writes into one script run, not many small invocations — the
initializehandshake and schema fetches are paid once per connection. - Drop trailing
SHOW/DESCRIBEverification from production scripts. Each read-back of a just-written module costs ~2 calls, so the verification block is an easy chunk to cut when you don’t need it. - The file backend has zero round trips. If Studio Pro doesn’t need to be open
— e.g. CI, bulk generation, or scripted migrations — the file backend applies the
same script far faster. Reserve
--mcpfor when live, validated, no-reload edits in an open model are the point.
What this means for token cost and LLM context
This is the part that matters most when an AI agent is driving mxcli, and it hinges on a single question: who makes the tool calls?
Agent → mxcli (efficient)
When an agent runs mxcli exec script.mdl -p app.mpr --mcp (via the shell, the
REPL, or an editor command), the agent emits one action — the MDL script — and
receives one summarized result. The ~60 PED tool calls, and their often
verbose, schema-laden JSON responses, happen inside the mxcli process. They never
enter the model’s context window, and they don’t each cost a model turn.
What lands in context:
- the MDL script — compact and declarative (the example is ~150 readable lines), and
- mxcli’s textual summary of the run.
That is a few thousand tokens, regardless of how many PED round trips it took.
Agent → Studio Pro MCP directly (expensive)
An agent connected straight to Studio Pro’s MCP server has no such amortization. To build the same domain model it must issue each of the ~60 calls as its own tool call:
- every request and every response (schemas, validation output, read-backs) is written into the context window, and
- each call is a separate model turn — so the model “thinks” ~60 times instead of once, multiplying both latency and per-turn token cost.
The same work that is one declarative script for the mxcli path becomes dozens of imperative, stateful tool calls whose intermediate results accumulate in context.
The takeaway
calls in LLM context model turns tokens in context
Agent → mxcli (--mcp) 0 1 low (script + summary)
Agent → Studio Pro MCP ~60 ~60 high (every request + result)
mxcli’s MCP backend is, in effect, a compression layer over the PED tool surface: the LLM works in compact, reviewable MDL while mxcli absorbs the chatty, validation-heavy, read-modify-write round trips on the model’s behalf. For bulk authoring this is the difference between one cheap turn and dozens of expensive ones — and it is why, even though a script “costs” ~60 tool calls, running it through mxcli keeps that cost out of the model’s context.
See also
- Connecting to a Running Studio Pro (MCP) — how to set up the connection and run scripts against a live model.
mxcli mcp capabilities— what the MCP backend can author against your connected Studio Pro version.- System Architecture — the backend abstraction that lets the same MDL target either the file or the MCP backend.
- Storage Names vs Qualified Names — why the BSON the file backend writes differs from the names in the SDK docs.