--- name: download-marketplace-content description: "The full lifecycle of Mendix Marketplace modules and widgets from the CLI — search, download, install, detect local edits, and update. Use when adding a marketplace module or widget, upgrading one, or asking what an upgrade would overwrite." --- # Download, Install and Update Marketplace Content This skill covers the full lifecycle of Mendix Marketplace content (modules and widgets) from the command line: discover → download → install → check for local edits → update. These are **CLI commands**, not MDL statements. ## When to Use This Skill - User wants to add a marketplace module or widget to a project - User wants to upgrade a module that is already installed - User asks whether a marketplace module has been edited locally, or what an upgrade would overwrite - User asks to download a specific `.mpk` (e.g. for CI, or to import in Studio Pro) - User asks which versions of a marketplace item are compatible with their Mendix version - User reports `CE0463` or `CE6087` right after installing or updating a module ## Prerequisites: Authenticate Marketplace access needs a Mendix Personal Access Token (PAT), created at (Developer Settings → Personal Access Tokens). ```bash mxcli auth login # interactive prompt for the PAT mxcli auth login --token # non-interactive (CI) export MENDIX_PAT= # or via environment mxcli auth status # verify it validates ``` Credentials are stored at `~/.mxcli/auth.json` (mode `0600`). Module installs also need the mxbuild toolchain for the project's Mendix version: `mxcli setup mxbuild -p app.mpr`. ## Step 1 — Discover ```bash mxcli marketplace search "database connector" # find content by name/publisher mxcli marketplace info 2888 # details for a content id mxcli marketplace versions 2888 # available versions mxcli marketplace versions 2888 --min-mendix 10.24.0 # compatible versions only ``` The numeric **content id** (from `search`/`info`) is what every other command takes. **Search caching.** The Content API has no server-side search, so the first `search` fetches the whole catalog (tens of seconds) and caches it under `~/.mxcli/` for 24h; later searches are instant. If the first search seems slow, it is scanning the catalog — let it finish. Pass `--refresh` to bypass the cache (e.g. for a brand-new module). If `search` returns nothing, the content may be private or listed under a different name — look it up by id with `info ` (ids come from the marketplace URL `.../link/component/`). **The listing name is not the module name.** Content 23513 is listed as "Administration module" and installs a module called `Administration`; "Data Widgets" installs `DataWidgets`. Never match a module to its marketplace listing by name — the commands below identify it by the marketplace **version UUID** the project records per module. Content ids that come up often: | Content | Id | Installs module | |---|---|---| | Administration | 23513 | `Administration` | | Community Commons | 170 | `CommunityCommons` | | Data Widgets | 116540 | `DataWidgets` | | Atlas Core | 117187 | `Atlas_Core` (theme module) | | Atlas Web Content | 117183 | `Atlas_Web_Content` (theme module) | ## Step 2 — Download a `.mpk` to disk (optional) ```bash mxcli marketplace download 2888 # latest, CDN filename mxcli marketplace download 2888 --version 7.0.2 -o dbc.mpk # specific version + path ``` Use this when you only want the file (to commit to `mx-modules/`, or to import in Studio Pro yourself). `download` needs no project; `install` does. ## Step 3 — Install into a project ```bash mxcli marketplace install -p app.mpr [--version X.Y.Z] ``` `install` is **type-aware**: | Content type | Behaviour | |---|---| | **Widget** | Copied into `widgets/` (overwrites on update). | | **Module** (new) | Copied in with mxcli's own writer — every unit, plus everything else the package ships (`widgets/`, `themesource/`, `javasource/`, ...). Preserves the project's storage format, and works for theme modules. | | **Module** (already present) | **Reported, not modified.** Use `marketplace update` (step 5). | | Theme / Starter App / Sample | Downloaded with import instructions (import via Studio Pro). | Measured: CommunityCommons 11.5.1 into a vanilla 11.12.1 app — 128 units and 126 bundled files, `mprcontents/` grew from 369 to 497 `.mxunit` files, `mx check` reports 0 errors. ### Do not use `mx module-import` `mx module-import` rewrites an **MPR v2** project as v1: one import turned a 69 KB `.mpr` plus 341 `.mxunit` files into a single 14 MB SQLite blob with no `mprcontents/` (measured on 11.12.1 and again on 11.13.0). The conversion is one-way — `mx convert` targets Mendix *versions*, not storage formats — and it takes `mxcli diff-local`, per-document git diffs and mergeability with it. `mx module-import` also refuses theme modules outright ("Importing theme module is not supported"). `install` therefore copies the units itself. `--allow-format-change` selects the legacy `module-import` path; without it, that path refuses to run on a v2 project rather than converting silently. ### The latest version is usually NOT the one to install New releases are published against the newest Studio Pro patch within days of it shipping, and `install` with no `--version` resolves to the latest. On any project that is not on the very newest patch, the default is therefore routinely the one version that cannot be installed. Measured 2026-08-12 on an 11.12.1 project: the latest release of **all six** agent-stack modules required 11.12.2, published five days earlier. `install` and `update` refuse it up front and name the version to use instead: ```text Agent Commons 4.2.0 requires Mendix 11.12.2, and the project is 11.12.1 hint: install --version 4.1.0 (the newest release built for 11.12.1 or older) ``` Run `mxcli marketplace versions ` first and read the `MIN MENDIX` column, or just act on the refusal. ### Dependencies are not resolved `install` installs exactly the content you name, and its dependencies are neither fetched nor named. Read the check errors after each install — they identify what is missing by qualified name (`CommunityCommons.RandomHash`, `MCPClient.ConsumedMCPService`), which tells you the module to add next. The error count is **not monotonic**: adding a module can raise it before it falls, because a module brings its own unmet dependencies with it. Measured on a vanilla 11.12.1 app while installing the agent-editor stack: 0 → 15 → 0 → 18 → 1 → 22 → 1 → 1. A rising count is progress, not a regression. Dependencies include **widget content**, not only modules — `ConversationalUI` needs the `Markdown viewer` (230248) and `Events` (224259) widget packages, which surface as `CE0462 "Could not find widget ... in the 'widgets' directory"`. ### Module packages bundle their own widgets — install order used to matter A module's `.mpk` carries a copy of every widget its pages use, pinned to whatever its author had at release time, and different modules pin different versions of the **same** widget. Measured on the published packages: Atlas_Web_Content 4.3.0 ships five Data Widgets at **3.4.0** that DataWidgets 3.11.3 ships at **3.11.3**. `install` and `update` never roll a widget back: a bundled copy older than the one in the project is kept out and reported. ```text Kept 5 newer widget(s) the package would have rolled back: widgets/com.mendix.widget.web.Datagrid.mpk — kept 3.11.3, package ships 3.4.0 ... ``` Before this, updating modules in one order and then another silently downgraded widgets, and nothing surfaced it — an older widget is not a `mx check` error, so the app just ran old widget code. If you are on an older mxcli, check the versions by hand: ```bash for f in widgets/*.mpk; do printf "%-50s %s\n" "$(basename $f)" \ "$(unzip -p "$f" package.xml | grep -oP ']*version="\K[^"]+')" done ``` Read ``, not the `` on the root element — that one is the manifest schema and is `1.0` for every widget ever published. A package that ships a widget **twice** (as a `.mpk` and as an unpacked tree — FeedbackModule 5.0.0 does) installs only the `.mpk`; the unpacked twin is skipped and reported. ### When the installed version has been unpublished `update` and `diff` download the *installed* version to establish the "has anyone edited this?" baseline, so both fail when that version is gone from the marketplace. A blank 11.13 app ships NanoflowCommons 6.0.0 and the 6.x line now starts at 6.1.1, so the module most in need of updating is exactly the one whose baseline cannot be built. ```text version "6.0.0" not found; run 'mxcli marketplace versions ' to list available versions The installed version is the baseline for "has anyone edited this?", so it has to be downloadable. It is not, and --force does not help: there is nothing to compare against. hint: re-run with --no-baseline to update without that check (local edits are lost silently) ``` `--force` does not help — it overrides a *finding*, and here there is no finding. `--no-baseline` accepts that the question cannot be answered and updates anyway. Commit first: local edits to that module go without being named. ## Step 4 — Repair the model after the install (required, headless) ```bash mxcli fix widgets -p app.mpr # clears CE0463 mxcli fix design-properties -p app.mpr # clears CE6087 mxcli docker check -p app.mpr # confirm ``` A headless install leaves two things for Mendix's own tools to finish, and **neither is an mxcli defect**: - **CE0463** "the definition of this widget has changed" — the project's stored widget instances are older than the widget packages now sitting beside them. This is not the CE0463 that `.claude/skills/diagnose-ce0463.md` is about. - **CE6087** "design properties have been renamed in your theme" — a module references design properties an older Atlas spelled differently. Project-level: the location in the check output is empty, so the message alone does not say which module caused it. A third, **CE0066** "Entity access is out of date", is *not* left to you. The install and the update copy the incoming module's units in verbatim, so a package whose access rules do not cover every member of their entities used to land that error with nothing said about it ([mendixlabs/mxcli#1085](https://github.com/mendixlabs/mxcli/issues/1085)). Both now reconcile the module's rules for themselves and report the count; nothing is written when the rules already match. When the line does appear, the module's domain model now differs from the package, so `marketplace diff` reads it as a local edit — the same consequence Studio Pro's **Update security** button has. Repair it by hand, on a project updated by an older mxcli, with: ```bash mxcli -p app.mpr -c "update security UserCommons" ``` Measured end to end on a vanilla 11.12.1 app carrying the agent-editor stack: `mx check` reported **203 errors** (202 × CE0463 + 1 × CE6087) and **0** after the two commands, with the project still MPR v2 — 1,868 `.mxunit` files, a 249,856-byte index, before and after. ### Never run the bare `mx` commands on an MPR v2 project `mx update-widgets` and `mx rename-design-properties` each do the repair **and** rewrite the project into the single-file v1 format. Measured on 11.12.1: `update-widgets` took 369 `.mxunit` files to 0 and a 69,632-byte index to 14,405,632 bytes; `rename-design-properties` took 1,865 files to 0 and a 249,856-byte index to 39,895,040 bytes, while renaming 149 design properties across 41 documents. The conversion is one-way. `mxcli fix …` runs the same tool, reads its result back out, restores the v2 storage, and writes the changed units into it. It reports the storage count before and after for exactly that reason — a collapse shows up there as a zero. Re-running is free: the second run reports 0 units changed (ADR-0008 elision), so the `.mpr` is left byte-identical. An MPR v1 project is passed straight through, since these tools write v1 natively. ### Related commands, and when each is right | Command | Persists? | Use | |---|---|---| | `mxcli fix widgets` | **yes** | the fix — after any headless install | | `mxcli fix design-properties` | **yes** | the fix — after any headless install | | `mxcli docker check` | no | runs the widget resync under a snapshot so the *check* is not tripped by CE0463; the stored model stays stale | | `mxcli widget sync` | yes, partial | reconciles widget schemas in mxcli's own code; clears 7 of 40 on the reference fixture | ## Step 5 — Before updating: has the module been edited? Studio Pro's Marketplace **Update** replaces the module and discards local edits without asking. `marketplace diff` answers the question that decides whether that is safe: ```bash mxcli marketplace diff 23513 -p app.mpr # what have I changed? mxcli marketplace diff 23513 -p app.mpr --to 4.5.0 # ...and what would an upgrade touch? mxcli marketplace diff 23513 -p app.mpr --json # for a CI gate ``` ```text Administration — installed 4.3.2 (Mendix 11.12.1) Locally modified (1 of 21 elements): changed ENTITY Account Upgrading to 4.5.0 would touch 5 element(s), 1 of which you have modified: CONFLICT ENTITY Account ``` **Tell the user the first one is slow.** Answering needs a reference project — a blank app with the published module imported — and `--to` needs two. Measured on Administration at 11.12.1: **~47s** the first time, **~9s** afterwards, once `~/.mxcli/marketplace-refs/` holds the blank app and the built references. Run `diff` before `update` rather than instead of it: the `update` reuses the base reference the `diff` just built, so the pair costs little more than the `diff`. Set `MXCLI_NO_REF_CACHE=1` if a result looks stale and you want to rule the cache out — it rebuilds everything without deleting the evidence. It downloads the installed version's `.mpk`, imports it into a throwaway reference project built **at the project's own Mendix version** (a mismatch is refused, not warned about — Mendix's own conversions would otherwise read as your edits), and compares `DESCRIBE` output on both sides. **A "modified" verdict now means the difference is real.** Some element types DESCRIBE renders imperfectly — a snippet whose body comes out `{ }`, a building block under "Building blocks are read-only; they cannot be created via MDL" — and two imperfect renderings can differ for reasons that have nothing to do with you. Those are reported `unknown`, never `changed`, and `--save-edits` refuses to write them: replaying `create or modify snippet X folder 'Web' { }` would **empty** the snippet. **Read `verified`, not just `locallyModified`.** An element that cannot be described is reported as `unknown`, never as unchanged, and `verified: false` means "no modifications found" is not a conclusion: ```text No local modifications found, but 46 of 89 elements could not be read — this is not a clean bill of health. ``` Flags: `-p/--project` (required), `--to `, `--module ` (when the project records no marketplace version for it, i.e. a hand-imported copy), `--json`, `--profile`. ## Step 6 — Update an installed module ```bash # Refuses if you have edited the module, naming what it would discard mxcli marketplace update 23513 -p app.mpr --to 4.5.0 # Park those edits as re-executable MDL, then update over them mxcli marketplace update 23513 -p app.mpr --to 4.5.0 --save-edits ./local-edits mxcli marketplace update 23513 -p app.mpr --to 4.5.0 --force mxcli exec ./local-edits/entity-Account.mdl -p app.mpr ``` ```text Administration updated 4.3.2 → 4.5.0 28 units copied, 9 element identities preserved, 2 role grant(s) restored. ``` Flags: `-p/--project`, `--to ` (required), `--module `, `--save-edits `, `--force`, `--profile`. ### What it preserves, and why it matters - **Element identity (`GUID`).** The runtime keys entities and attributes on the model's `GUID` — `mendixsystem$entity.id` holds it verbatim. A module whose documents are replaced without carrying the old `GUID`s is a *different* module to the database, and its tables are dropped on the next deploy. `$ID` renumbering is irrelevant here; `GUID` is everything. This is why deleting a module and re-importing it is never a valid update. - **Role grants.** A user role's grant of a module role lives in the *project's* security document, not the module, so removing the module takes the grants with it and putting it back does not return them. - **Everything else the package ships.** Widget binaries under `widgets/`, styling and design-property declarations under `themesource/`, and so on — only `project.mpr` and `package.xml` are manifest rather than payload. DataWidgets 3.11.3 replaces 49 such files; skipping them leaves the app running old widget code and reporting `CE6083` for design properties the module itself declares. ### Limits — state these to the user before running it - **Local edits are not preserved.** `update` refuses when it finds any; `--save-edits` writes them out first; `--force` proceeds. Saved files are the element's **resulting state, not a diff**, so replaying restores additions and changes but not removals, and an element that could not be described has nothing to save (it is reported, not skipped). - **No rollback.** Work on a copy, or have the project committed to version control first. - **No dependency resolution** (same as `install`). - **`update` does not run `mx check` itself** — do step 4 afterwards. ### Afterwards ```bash mxcli fix widgets -p app.mpr # step 4 applies to updates too mxcli fix design-properties -p app.mpr mxcli docker check -p app.mpr # expect 0 errors mxcli diff-local -p app.mpr # review what landed, per document ``` Measured after the repair: Administration 4.3.2 → 4.5.0 (28 units, 9 identities, 2 grants) and DataWidgets 3.5.0 → 3.11.3 (49 files) both reach **0 errors**. ## Worked example: the agent-editor stack on a vanilla app Run end-to-end on 2026-08-12 against a fresh `mxcli new … --version 11.12.1` app. The modules in `.claude/skills/mendix/agents` must all be present before any `create agent` statement will build, and two of the dependencies are neither listed there nor modules. | Step | Content | Id | `--version` | Units | Errors after check | |---|---|---|---|---|---| | 0 | *(vanilla app)* | — | — | 370 files | 0 | | 1 | GenAI Commons | 239448 | 7.1.1 | 214 | 15 — needs CommunityCommons | | 2 | Community Commons | 170 | latest | 128 | 0 | | 3 | Mendix Cloud GenAI Connector | 239449 | 7.1.0 | 223 | 18 — needs Encryption | | 4 | Encryption | 1011 | latest | 61 | 1 — CE6087 | | 5 | Agent Commons | 240371 | 4.1.0 | 385 | 22 — needs MCPClient + ConversationalUI | | 6 | MCP Client | 244893 | 4.1.0 | 82 | — | | 7 | Conversational UI | 239450 | 7.1.0 | 345 | 22 — CE0462, missing widgets | | 8 | Markdown viewer *(widget)* | 230248 | latest | — | — | | 9 | Events *(widget)* | 224259 | latest | — | 1 — CE6087 | | 10 | Agent Editor | 257918 | 2.1.0 | 58 | 1 — CE6087 | ```bash mxcli new MyAgentApp --version 11.12.1 && cd MyAgentApp mxcli marketplace install 239448 --version 7.1.1 -p MyAgentApp.mpr mxcli docker check -p MyAgentApp.mpr # read the errors; they name what is missing # ...repeat per row... ``` Then authoring works — `create constant` + `create ai model` + `create agent` executed and added 3 units, with `list features in agent_documents` reporting all four document types available on 11.12.1. Four things this run established, none of them obvious from the command list: 1. **Install `AgentEditorCommons` last** — it depends transitively on the rest. 2. **`--version` is mandatory in practice.** Every agent-stack module's latest release required 11.12.2 against an 11.12.1 project. 3. **Two dependencies are widgets, and two more are modules the agent skill does not list** (CommunityCommons, and the widget packages). Let the check errors drive it. 4. **The install leaves the model needing repair, and step 4 is not optional.** A plain `mx check` on the finished project reported 203 errors (202 × CE0463, 1 × CE6087); `mxcli fix widgets` (62 units) and `mxcli fix design-properties` (42 units) took it to **0**. The project stays MPR v2 throughout: 1,868 `.mxunit` files, a 249,856-byte index. The ids are a convenience, not an authority: confirm with `search`/`info` rather than trusting them from memory, and note that the listing name never matches the module name. ## Notes - `install`/`update`/`diff` require `-p `; `download` does not. - All of them require `mxcli auth login` first; an expired or missing PAT gives an auth error with a login hint. - Marketplace CDN TLS handshakes time out occasionally. Retry once before reporting a failure. ## Platform authentication (`mxcli auth login/logout/status/list`) with PAT scheme for marketplace-api Platform authentication (`mxcli auth login/logout/status/list`) with PAT scheme for marketplace-api.mendix.com, marketplace.mendix.com, and catalog.mendix.com; credentials stored at ~/.mxcli/auth.json (mode 0600), MENDIX_PAT env override ## Marketplace download/install (`mxcli marketplace download/install`) — the content API now exposes a per-version downloadUrl (303→public CDN); install is type-aware (widget→widgets/, new module→`mx module-import`); existing-module updates are reported, not applied (entity-ID/local-edit safety — see PROPOSAL_marketplace_modules Marketplace download/install (`mxcli marketplace download/install`) — the content API now exposes a per-version downloadUrl (303→public CDN); install is type-aware (widget→widgets/, new module→`mx module-import`); existing-module updates are reported, not applied (entity-ID/local-edit safety — see PROPOSAL_marketplace_modules.md) ## Marketplace drift detection (`mxcli marketplace diff -p app.mpr [--to VERSION] [--json]`) reports **which elements of an installed marketplace module have been edited locally** — the question Studio Pro's Marketplace update never asks before replacing the module. The version's `.mpk` is downloaded and imported into a throwaway reference project built **at the consuming project's Mendix version** (a mismatch is refused, not warned about: Mendix's own conversions would read as user edits), then every element is described on both sides and the **DESCRIBE output** compared — not BSON, in which an *untouched* module differs from its own package in ~15,000 paths. `--to` adds what an upgrade would touch and which of those collide with local edits. Honesty rule: an element that cannot be described is reported **unknown, never unchanged**, and `verified:false` in the JSON means "no modifications found" is not a conclusion. Module + version are identified from the module's `AppStoreGuid`, which is the marketplace **version UUID** — matching on the version *number* is ambiguous (a blank project has Atlas_Web_Content 4.1.0 and Administration's content also published a 4.1.0). Measured on real content: Administration 4.3.2 in a blank 11.12.1 app → 21/21 unchanged; one added attribute → exactly `ENTITY Account`; `--to 4.3.2` (the installed version) touches nothing, which is the control for `--to 4.5.0`'s five. Package: `cmd/mxcli/marketplace/`. See `docs/11-proposals/PROPOSAL_marketplace_module_upgrade.md` **Not Yet Implemented:**