Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
9b2d7d0
fix(test): a later passing @expect no longer clears an earlier failur…
claude Oct 28, 2026
be9dc02
fix(test): rename a lower-case `call`/`create` variable per test on t…
claude Oct 28, 2026
2f9b626
fix(security): keep a module role's description when create or modify…
claude Oct 28, 2026
7f0d71e
fix(modelsdk): declare AggregateFunction on Mendix 9, floor Reduce's …
claude Oct 28, 2026
57cb317
fix(canon): write no workflow PersistentId below Mendix 10.21
claude Oct 28, 2026
2c7876b
fix(canon): complete a workflow's state-change handlers on Mendix 9.24
claude Oct 28, 2026
4df889e
fix(canon): write a constant override flat below Mendix 10.9
claude Oct 28, 2026
de548c6
fix(canon): leave a $currentObject flow argument out below Mendix 10.10
claude Oct 28, 2026
baaeda1
fix(executor): gate create published odata service at Mendix 10.4
claude Oct 28, 2026
c190ea7
docs(wiki): a version refusal is not always an older shape
claude Oct 28, 2026
8af923f
Merge pull request #1764 from ako/claude/loving-clarke-qun7w5
ako Oct 28, 2026
42778ae
fix(test): git doctor tests no longer read the developer's git config
claude Oct 28, 2026
e29655c
Merge pull request #1765 from ako/claude/loving-clarke-qun7w5
ako Oct 28, 2026
a6f3dfa
fix(make): fmt-check uses the toolchain's gofmt, not the one on PATH
claude Oct 28, 2026
f4398e6
build(make): add ci-local, the build-and-test job run before pushing
claude Oct 28, 2026
880a284
docs(skills): add the steward skill, the loop from PR opened to merged
claude Oct 28, 2026
277bf8e
fix(git): doctor judges notes only once the remote's notes are fetched
claude Oct 28, 2026
61af7ee
fix(git): doctor judges the configured remote URL, not the insteadOf …
claude Oct 28, 2026
eac6fbf
fix(git): commit --dry-run leaves what the user staged as it was
claude Oct 28, 2026
6a79349
fix(git): commit leaves out only the project's own build folders
claude Oct 28, 2026
d7b8593
Merge pull request #1766 from ako/claude/loving-clarke-qun7w5
ako Oct 28, 2026
76e47b0
Merge pull request #1767 from ako/claude/optimistic-fermi-x62bln
ako Oct 28, 2026
58e8346
fix(widgets): read switch arms and statement-head guards in editorCon…
claude Oct 28, 2026
afe48e6
fix(describe): leave out a pluggable widget property it hides at its …
claude Oct 28, 2026
75ee548
fix(microflows): edit an activity replaced by one of the same kind in…
claude Oct 28, 2026
76efadf
docs(microflows): say what a same-kind replace keeps
claude Oct 28, 2026
35741a2
fix(canon): leave the end-of-path marker out of a parallel split belo…
claude Oct 28, 2026
761fab0
fix(modelsdk): give WidgetReturnType.assignableTo and GroupBox.header…
claude Oct 28, 2026
4939d51
fix(git): doctor judges only core.autocrlf — the mendix.* counters ar…
engalar Oct 29, 2026
6ddd5e5
fix(git): the staged-files summary lists what the commit holds, not t…
engalar Oct 29, 2026
4e961b2
feat(git): `git merge` reviews conflicts before they land — report bo…
engalar Oct 29, 2026
f759979
feat(git): per-unit conflict resolution — property-level report (mx d…
engalar Oct 29, 2026
e42dd94
Merge pull request #1675 from ako/main
ako Oct 29, 2026
2dc8aa2
Merge pull request #1770 from ako/claude/loving-clarke-qun7w5
ako Oct 29, 2026
61c38e1
fix(gitignore): ignore the unit-type index under testdata fixtures too
claude Oct 29, 2026
4335dff
fix(layout): an error handler's row reserves the lane under its activity
claude Oct 29, 2026
34d3787
fix(layout): a later @position no longer moves the statements before it
claude Oct 29, 2026
49dec83
fix(lint): MPR008 compares events and type splits
claude Oct 29, 2026
83f22ae
fix(executor): every nested flow body keeps the splice's member guard
claude Oct 29, 2026
8d3089e
fix(executor): type a stored retrieve over an association for a fragment
claude Oct 29, 2026
47ec0e0
fix(canon): store a user task's targeting as UserSource below Mendix …
claude Oct 29, 2026
f9fcc87
fix(canon): write a user task as a Workflows$UserTask below Mendix 10.12
claude Oct 29, 2026
3c69d95
fix(wfmutator): set a user task's targeting whichever key stores it
claude Oct 29, 2026
684a447
fix(executor): gate the user-task features older Mendix cannot store
claude Oct 29, 2026
b47de7e
test(doctype): write user tasks in the Mendix 10 workflow script
claude Oct 29, 2026
ee1a059
test(bug-tests): measure the 1771 user-task shapes on Mendix 10.11
claude Oct 29, 2026
f62863b
ci: add Mendix 11.16.0 to the nightly test matrix
claude Oct 29, 2026
316b482
Merge pull request #1772 from ako/claude/loving-clarke-qun7w5
ako Oct 29, 2026
7382ede
Merge branch 'mendixlabs:main' into main
ako Oct 29, 2026
cad9b08
Merge pull request #1779 from ako/claude/vibrant-knuth-3lhlkd
ako Oct 29, 2026
0377b76
Merge pull request #1677 from ako/main
ako Oct 29, 2026
2788811
fix(git): the git-merge fixtures run git hermetically and show what t…
engalar Oct 30, 2026
a5df7bf
Merge upstream/main: insteadOf-aware doctor, notes-fetch finding, pro…
engalar Oct 30, 2026
69a1fdf
fix(git): the model merge runs mx merge over three project folders, g…
engalar Oct 30, 2026
4fa453f
docs(skills): regenerate the teamserver-git section index after the m…
engalar Oct 30, 2026
6550296
Merge upstream/main: #1791 unit-index naming, #1789 catalog reads, #1…
engalar Oct 30, 2026
82188cf
feat(git-merge): parse the engine's -v conflict list
engalar Nov 1, 2026
6608d20
feat(git-merge): run mx merge over .mpr paths with MINE as a clean wo…
engalar Nov 1, 2026
7108409
feat(git-merge): drive the review material from the engine's conflict…
engalar Nov 1, 2026
e62ce46
test(git-merge): real-mx integration for the engine path (exit 0 and 2)
engalar Nov 1, 2026
b499c07
docs(git-merge): the engine is called with .mpr paths over clean work…
engalar Nov 1, 2026
2c118da
test(git-merge): pin the modified-on-both plan gate
engalar Nov 1, 2026
4169850
feat(mcp): drop Concord; delete, check and run through Studio Pro's MCP
ako Nov 1, 2026
475d08d
docs(proposals): playwright check through Studio Pro's MCP browser
ako Nov 1, 2026
270fa0a
Merge remote-tracking branch 'origin/main' into claude/festive-drisco…
ako Nov 1, 2026
418e6fb
Report every widget measured as CE0582 under the React client (MPR012)
ako Nov 1, 2026
d910b4d
Write an empty header for an uncaptioned custom-content data grid column
ako Nov 1, 2026
3bf444a
Add SEC011: a page XPath through an association the page's roles cann…
ako Nov 1, 2026
5f87783
Merge remote-tracking branch 'origin/main' into claude/festive-drisco…
ako Nov 1, 2026
1ae7673
Merge remote-tracking branch 'origin/main' into fix/564-react-unsuppo…
ako Nov 1, 2026
d54425d
Merge remote-tracking branch 'origin/main' into fix/535-empty-column-…
ako Nov 1, 2026
79beb6c
Format cmd_lint.go
ako Nov 1, 2026
009e4c4
Merge mendixlabs/mxcli#1674: mxcli git merge — model-aware merging fr…
claude Nov 1, 2026
a2b8331
test(git): git-merge fixtures commit with a fixed identity
claude Nov 1, 2026
c900834
fix(git-merge): a merge git refuses to start says why
claude Nov 1, 2026
6cc4ef4
feat(mpr): read and clear merge conflict markers in the unit index
claude Nov 1, 2026
dd08c8d
fix(git-merge): --plan resolves over the engine's result
claude Nov 1, 2026
e08a671
docs(plans): mark the git-merge folder-mode plan superseded in part
claude Nov 1, 2026
6c2c66c
Merge pull request #1870 from ako/fix/564-react-unsupported-widgets
ako Nov 1, 2026
bf4539d
Merge pull request #1871 from ako/fix/535-empty-column-caption
ako Nov 1, 2026
291df7d
Merge branch 'main' of https://github.com/ako/mxcli into claude/festi…
ako Nov 1, 2026
0448300
Merge branch 'main' of https://github.com/ako/mxcli into feature/945-…
ako Nov 1, 2026
17ad4fc
Merge pull request #1873 from ako/feature/945-xpath-association-access
ako Nov 1, 2026
f2267e7
Merge pull request #1874 from ako/claude/festive-driscoll-aa5aa4
ako Nov 1, 2026
dc68b2a
Merge pull request #1882 from ako/claude/optimistic-fermi-x62bln
ako Nov 1, 2026
33836f2
Merge pull request #1876 from ako/claude/gracious-turing-e85912
ako Nov 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/commands/mendix/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ mxcli lint -p app.mpr --baseline lint-baseline.json
| MPR005 | quality | ImageSource - IMAGE widgets with no source configured |
| MPR006 | quality | EmptyContainer - Empty layout containers |
| MPR007 | security | PageNavigationSecurity - Navigation pages need allowed roles (CE0557); every user role must be able to open its home page (at Production security, else CE2729 per widget) |
| MPR012 | correctness | LegacyImageWidget - staticimage/dynamicimage are unsupported by the React client (CE0582; info on the classic client) |
| MPR012 | correctness | ReactUnsupportedWidget - static/dynamic image, drop-down, legacy data grid and reference selector are unsupported by the React client (CE0582; info on the classic client) |
| MPR013 | correctness | SnippetCallAppearance - Class/Style/DynamicClasses/design properties on a snippet call never reach the page (it renders no element) |
| SEC001 | security | NoEntityAccessRules - Persistent entities need access rules |
| SEC002 | security | WeakPasswordPolicy - Password minimum length should be 8+ |
| SEC003 | security | DemoUsersActive - Demo users should be off at Production security |
| SEC010 | security | PageEntityNotReadable - A page data widget lists an entity the user roles that open the page cannot read; at Production it renders empty, silently (info when only row-scoped) |
| SEC011 | security | XPathAssociationNotReadable - A page data source's XPath crosses an association a role that opens the page may not read; at Production the page fails to open ("No access rights for …") |
| CONV011 | performance | NoCommitInLoop - Commits inside loops (commit actions, or create/change with commit) cause N+1 issues |
| CONV012 | quality | ExclusiveSplitCaption - Exclusive splits need meaningful captions |
| CONV013 | quality | ErrorHandlingOnCalls - External calls (REST/WS/Java) need custom error handling |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-01", "symptom": "Every `TestGitMerge_*` fixture and both real-mx `TestGitMergeIntegration_*` tests fail on a host named `vm` with `Committer identity unknown … unable to auto-detect email address (got 'root@vm.(none)')`, before the command under test runs; they pass on CI runners and developer machines", "cause": "The fixtures drop the global git config (GIT_CONFIG_GLOBAL=/dev/null) for hermeticity, but `gitInE` and the command's own in-process `git merge`/`git commit` in the integration fixture ran without the fixed identity `gitIn` sets, so git fell back to guessing one from the hostname — which works wherever the hostname has a domain", "file": "`cmd/mxcli/gitdoctor_test.go` (`gitInE` sets GIT_AUTHOR_*/GIT_COMMITTER_*), `cmd/mxcli/gitmerge_integration_test.go` (`mergeIntegrationRepo` sets them in the process environment)", "insight": "**Removing the global config is half of hermetic**: git still guesses an identity from the hostname, so a fixture that never sets one passes exactly where the hostname has a domain — every runner image and laptop — and fails in a bare container. `git merge` needs the identity even when it stops on a conflict. Pattern: docs-wiki/bug-patterns/the-platform-ci-does-not-run.md", "refs": ["mendixlabs/mxcli#1674"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-01", "symptom": "`mxcli git merge <ref> --plan <file>` commits a valid two-parent merge that has silently lost one side's change to a unit the plan never names: ours adds `MyFirstModule.OursOnly`, theirs adds `MyFirstModule.TheirsOnly`, both edit `FeedbackModule.Feedback`'s documentation; the engine exits 2, the template lists only FeedbackModule's domain model, and after `--plan` with take theirs `TheirsOnly` is gone — the hash gate passes and nothing in the output mentions the unit", "cause": "applyPlan resolved from git's two sides — ours for every model file git conflicted, theirs for the planned units — and never ran the engine. Once the template listed only the engine's ManualResolutionRequired units, a unit the engine merges by itself (MergeContents/AutoResolved: an entity added on each side of one domain model) was taken from ours wholesale", "file": "`cmd/mxcli/cmd_git_merge.go` (`applyPlan` re-runs the engine over `checkoutRevisions` worktrees, checks the plan against `engineDecisions`, copies the result back with `copyEngineResult`, takes each planned unit with `git checkout <sha> -- <unit>`, `clearDecidedMarkers`, then refuses anything `conflictMarkers` still lists); `modelsdk/mpr/merge_conflicts.go` (`Reader.UnitConflicts`, `Writer.ClearContentsConflicts`); tests `TestGitMerge_PlanKeepsWhatTheEngineMerged`, `TestGitMerge_PlanMustMatchTheEnginesDecisions` in `cmd/mxcli/gitmerge_test.go`, `TestGitMergeIntegration_PlanKeepsWhatTheEngineMerged` (real mx) in `cmd/mxcli/gitmerge_integration_test.go`", "insight": "**\"AutoResolved\" means merged in the engine's result, not merged in yours**: a step that rebuilds from the sides instead of the result has to re-decide every unit, and listing fewer units to it hides the ones it gets wrong. Change the review list and the resolution source together. **The engine's exit-2 result is usable**: MINE holds every auto-resolved unit merged and marks only the undecided ones, in `Unit.ContentsConflicts` (a JSON list where every other row holds '' — not NULL); `mx check` reports CE0137 while a marker is left, which makes it the headless oracle for 'did the clear read as resolved'. Take a planned unit from its side's commit, not from MINE: MINE's copy of an undecided unit is not byte-identical to ours'. Measured with mx 11.13 on the PedApp fixture and an `mx create-project` scaffold. Pattern: docs-wiki/bug-patterns/rewrite-drops-unauthored-state.md", "refs": ["mendixlabs/mxcli#1674"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-01", "symptom": "`mxcli git merge side -p App.mpr` on a working tree with an uncommitted change the merge would overwrite fails with `git merge side: Updating 5d6b73c..2c3fd47`, and without a git identity with `git merge side: ` and nothing after it; the same with `--plan`", "cause": "When git merge stopped before any conflict existed (no MERGE_HEAD), the error was built from `firstLineOf(mergeOut)` — git's stdout, which holds at most the fast-forward 'Updating a..b' line — while git's reason is on stderr, which gitOutIn already returns as the error", "file": "`cmd/mxcli/cmd_git_merge.go` (`mergeRun` and `applyPlan` report `mergeErr`); test `TestGitMerge_RefusedMergeSaysWhy` in `cmd/mxcli/gitmerge_test.go`", "insight": "**A wrapper that splits stdout from stderr has to pick the stream per outcome**: git writes progress to stdout and refusals to stderr, so the line that is right on success is the wrong one on failure. Found only because a fixture ran on a host where git could not guess an identity — the empty message was the first clue. Pattern: docs-wiki/bug-patterns/misleading-diagnostics.md", "refs": ["mendixlabs/mxcli#1674"]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"area": "mdl/backend/mcp", "date": "2026-11-01", "symptom": "Over `--mcp` on Studio Pro 11.16, every DROP of a standalone document (constant, enumeration, microflow, nanoflow, page, workflow, business-event service) demanded `--mcp-concord`, though 11.16 ships `ped_delete_document`. Separately, a PED tool whose handler throws answers `Error executing tool handler: …` with `isError:false`, which any caller trusting the flag reads as success", "cause": "`concordDeleteDocument` was the only DROP path, written when PED had no delete tool. `Client.CallTool` passed `isError` through verbatim, and only the create/update callers (`pedOpError`'s `SUCCESS` prefix) noticed failures reported in the text", "file": "`mdl/backend/mcp/delete.go` (new `deleteDocument`: native when `HasTool(\"ped_delete_document\")`, Concord fallback), `client.go` (`HasTool`, `handlerFailed` sets `IsError`), the seven `Delete*` call sites, `capabilities.yaml`/`.go` report text", "insight": "**Probe tool presence, never the version**: `serverInfo.version` was 1.0.0 on 11.12.0 and 11.16.0 reports itself, but the delete tool is the fact that matters. **On 11.16.0 the native delete fails for every caller outside Studio Pro's own agent session** (`Session 'mcp-server' not found`, measured from a devcontainer through four clientInfo names), so the success reply has never been seen. The code therefore settles an unrecognised reply by `ped_find_document` instead of guessing the text, and keeps Concord as a fallback. **Revert check**: stubbing `handlerFailed` fails `TestCallTool_HandlerErrorIsAnError`, and forcing the Concord path fails three `TestDeleteDocument_*`. Live runs are in mx-test-projects/runs/native-delete/"}
{"area": "mdl/backend/mcp", "date": "2026-11-01", "symptom": "Over `--mcp` on Studio Pro 11.16, every DROP of a standalone document (constant, enumeration, microflow, nanoflow, page, workflow, business-event service) demanded `--mcp-concord`, though 11.16 ships `ped_delete_document`. Separately, a PED tool whose handler throws answers `Error executing tool handler: …` with `isError:false`, which any caller trusting the flag reads as success", "cause": "`concordDeleteDocument` was the only DROP path, written when PED had no delete tool. `Client.CallTool` passed `isError` through verbatim, and only the create/update callers (`pedOpError`'s `SUCCESS` prefix) noticed failures reported in the text", "file": "`mdl/backend/mcp/delete.go` (new `deleteDocument`: native when `HasTool(\"ped_delete_document\")`, else an error naming 11.16+; Concord support removed in the same change), `client.go` (`HasTool`, `handlerFailed` sets `IsError`), the seven `Delete*` call sites, `capabilities.yaml`/`.go` report text", "insight": "**Probe tool presence, never the version**: `serverInfo.version` was 1.0.0 on 11.12.0 and 11.16.0 reports itself, but the delete tool is the fact that matters. **On 11.16.0 the native delete fails for every caller outside Studio Pro's own agent session** (`Session 'mcp-server' not found`, measured from a devcontainer through four clientInfo names), so the success reply has never been seen. The code therefore settles an unrecognised reply by `ped_find_document` instead of guessing the text. **Revert check**: stubbing `handlerFailed` fails `TestCallTool_HandlerErrorIsAnError`, and removing the `HasTool` gate fails `TestDeleteDocument_NoNativeToolNeeds1116`. Live runs are in mx-test-projects/runs/native-delete/"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-11-01", "symptom": "A Data grid 2 custom-content column written with `Caption: ''` (or no caption) through the generic `pluggablewidget 'com.mendix.widget.web.datagrid.Datagrid'` path showed its MDL column name (`colTriage`) as the header to end users; mx check, check and lint all passed.", "cause": "applyColumnHeaderFallback filled an empty header on an attribute-less column with the column's NAME, a name Mendix does not store for a column. It was written on the belief that an empty header is CE0463; that CE0463 was a null TextTemplate, and the empty Forms$ClientTemplate (ChipCoV8 #11) builds clean. The keyword `datagrid` path already wrote the empty header.", "file": "mdl/executor/widget_engine.go", "insight": "Read the widget's own bundle before reasoning about a render: Datagrid.mjs renders `header.trim() || ' '`, so no runtime fallback exists and the text had to come from the writer. Grepping the stored unit for the name settled which path wrote it. A CE0463 'fix' that substitutes a value should be re-measured once the null-vs-empty shape is known; this one outlived the shape fix by three months. Separately: create or replace does not clear a column caption to '' on either path (Unchanged page), so an app already holding the name needs the page dropped and recreated.", "issue": "ako/mxcli#535"}
21 changes: 11 additions & 10 deletions .claude/skills/mendix/assess-quality/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ description: "Audit a Mendix project against best practices for naming, security
|---|---|
| 29-36 | When to Use This Skill |
| 37-96 | Assessment Workflow |
| 97-354 | Quality Guidelines Reference |
| 355-365 | Assessment Report Template |
| 366-378 | Executive Summary |
| 379-389 | project Metrics |
| 390-402 | Automated Findings |
| 403-422 | Manual Review Findings |
| 423-438 | Recommendations |
| 439-449 | Sources |
| 97-355 | Quality Guidelines Reference |
| 356-366 | Assessment Report Template |
| 367-379 | Executive Summary |
| 380-390 | project Metrics |
| 391-403 | Automated Findings |
| 404-423 | Manual Review Findings |
| 424-439 | Recommendations |
| 440-450 | Sources |

<!-- /skill-index -->
# Assess Mendix Project Quality
Expand Down Expand Up @@ -152,14 +152,15 @@ After reviewing automated results, assess the following areas manually. The guid

### C. Security

**Enforced by rules:** SEC001-SEC010, CONV006, CONV007, CONV008, MPR007
**Enforced by rules:** SEC001-SEC011, CONV006, CONV007, CONV008, MPR007

#### C.1 Entity Access

| Guideline | Rule | Priority |
|-----------|------|----------|
| All persistent entities must have access rules | SEC001 | Critical |
| Every role that opens a page can read the entities its grids, galleries and combo boxes list (else it renders empty at Production) | SEC010 | High |
| Every association a page data source's XPath crosses is readable by the roles that open the page, on the entity the step starts from (else the page fails to open at Production) | SEC011 | High |
| Do not grant Create or Delete rights on entity access rules | CONV006 | High |
| All entity access rules should have XPath constraints | CONV007 | High |
| Set default access rights to None | Manual check | High |
Expand Down Expand Up @@ -441,7 +442,7 @@ Overall Score: [X]/100 (from `mxcli report`)
This skill incorporates guidelines from:
- **Conventions.pdf** — Squad Apps internal best practices (14 categories, 80+ guidelines)
- **CONV001-CONV017 lint rules** — Automated checks derived from Conventions.pdf
- **MPR001-MPR007, SEC001-SEC010** — Built-in linter rules
- **MPR001-MPR007, SEC001-SEC011** — Built-in linter rules
- **ARCH, DESIGN, QUAL series** — Starlark architecture/quality rules
- **Mendix Performance Best Practices** — Official Mendix documentation on performance optimization
- **Mendix Security Best Practices** — Official Mendix documentation on security configuration
Expand Down
36 changes: 17 additions & 19 deletions .claude/skills/mendix/live-edit-with-studio-pro/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ description: "Change the model through mxcli while Studio Pro has the project op
| 36-42 | How it works (hybrid: local reads, live writes) |
| 43-61 | Connect |
| 62-91 | What you can change via MCP — check first |
| 92-104 | Two MCP servers — use the built-in one by default |
| 105-114 | Caveats |
| 115-122 | Verify your change |
| 92-99 | The MCP server |
| 100-112 | Caveats |
| 113-120 | Verify your change |

<!-- /skill-index -->
# Live-Editing an Open Studio Pro Project with mxcli (MCP)
Expand Down Expand Up @@ -89,26 +89,24 @@ New modules and their dependents resolve within the same run, so
document in a folder at create time (`create microflow X.MF folder 'A/B'`), since
MOVE can't re-parent over MCP.

## Two MCP servers — use the built-in one by default
## The MCP server

The machine may run two MCP servers:

- **Studio Pro built-in (port 7782 by default)** — model authoring. **Use this by
default.** From **11.13** Studio Pro **auto-selects a free port** when 7782 is
taken, so multiple instances can run side by side. The active port is shown in
Studio Pro's **status bar** (and set under Preferences > AI > MCP Server) — read
it there rather than assuming 7782, and pass it to `--mcp-dial`.
- **Concord (port 7783)** — a temporary gap-filler with operational/refactor tools
(`delete_document`, `save_all`, `run_app`, `check_model`). **Only** reach for
Concord when the built-in server lacks the capability you need.
Studio Pro's built-in MCP server (port 7782 by default) is the only one mxcli
uses. From **11.13** Studio Pro **auto-selects a free port** when 7782 is taken, so
multiple instances can run side by side. The active port is shown in Studio Pro's
**status bar** (and set under Preferences > AI > MCP Server) — read it there rather
than assuming 7782, and pass it to `--mcp-dial`.

## Caveats

- **Writes are unsaved.** They land in Studio Pro's in-memory model (shown as
unsaved). Save in Studio Pro to persist to disk.
- **No DROP of standalone documents** (enumeration / microflow / page) through the
built-in server — it has no delete tool. Remove them in Studio Pro (or via
Concord's `delete_document`).
- **Writes are saved as they land.** PED writes each change to disk immediately
(measured on 11.12.0 and 11.16.0), so there is no save step.
- **DROP of standalone documents needs Studio Pro 11.16+** (`ped_delete_document`).
On 11.16.0 that tool fails with `Session 'mcp-server' not found` for callers
outside Studio Pro's own agent session; delete the document in Studio Pro then.
- **`--mcp-check`** runs Studio Pro's project-wide error check (11.15+), and
**`--mcp-run`** starts the app through the `mendix_app` handler and prints its URL
(11.16+).
- **`-p` must match the open project.** A mismatched `-p` silently reads the wrong
model.

Expand Down
15 changes: 12 additions & 3 deletions .claude/skills/mendix/manage-security/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ description: "Configure Mendix security in MDL — module and user roles, access
| 44-120 | The System-module ceiling — decide the role model around this FIRST |
| 121-560 | Syntax Reference |
| 561-575 | Starlark Lint Rule APIs |
| 576-628 | Common Workflow: Setting Up Module Security |
| 629-638 | Common Mistakes |
| 639-648 | Validation |
| 576-637 | Common Workflow: Setting Up Module Security |
| 638-647 | Common Mistakes |
| 648-657 | Validation |

<!-- /skill-index -->
# Security Management Skill
Expand Down Expand Up @@ -626,6 +626,15 @@ Audit members are the one case where naming a member cannot change its rights:
member access to write for it and a rule that carries one fails CE0066. Let the
rule's default cover it, or change the default.

**A page data source's XPath needs the association member too.** At Production the
runtime checks member access on every association step of a data-source XPath, on the
entity the step starts from: `database from M.Account where [M.Order_Account/M.Order/IsActive
= true()]` with `M.Order_Account` at None in Account's rule (owner Both) opens to an error
dialog, `No access rights for M$Account/M.Order_Account`, while mxbuild reports nothing.
A step from an entity the association is not a member of (the TO side of an `OWNER
Default` association) is not checked, and neither is an XPath inside an access rule
(measured, 11.15). `mxcli lint` reports it as SEC011.

## Common Mistakes

1. **Creating module roles before the module exists** — `create module` must come first
Expand Down
Loading
Loading