Agent skill

Write Microflows

by mendixlabs in mendixlabs/mxcli

Microflow syntax reference in MDL — every activity type, control flow, expressions, and the mistakes that fail mxcli check.

Apache-2.0Auto-check passedDevelopment

Install Write Microflows

skills CLI
$ npx skills add mendixlabs/mxcli --skill write-microflows -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install mendixlabs/mxcli write-microflows --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/mendix/write-microflows .claude/skills/write-microflows && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
write-microflows
GitHub stars
128
Token cost
~7.1k tokens
SKILL.md length
2,534 words
Files
5
Skills in repo
75
Repo updated
First seen
Licence
Apache-2.0

At a glance

Microflow syntax reference in MDL — every activity type, control flow, expressions, and the mistakes that fail mxcli check.

  • Works in 9 steps: Always use fully qualified names:… → Test incrementally: Create simple… → Check entity definitions: Ensure all… → …
  • Development work in your project
  • SKILL.md covers Reference files, When to Use This Skill, Changing an Existing Microflow and When to Use a Microflow vs a…, plus 9 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Write Microflows is an agent skill from mendixlabs/mxcli. Microflow syntax reference in MDL — every activity type, control flow, expressions, and the mistakes that fail mxcli check. Use before writing any CREATE MICROFLOW, and when debugging a microflow syntax error.

Its SKILL.md is about 7.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files (for example `reference/control-flow.md`, `reference/data-operations.md` and `reference/integration.md`).

It sits in Development. The repository describes itself as: Mendix cli tool, a headless way to work with Mendix projects. Enables Mendix projects for use with 3rd party agentic coding tools like Claude Code and Copilot. Includes a… The licence is Apache-2.0.

When your agent uses it

  • Development work in your project

Example prompts

  • “/write-microflows”

Workflow steps

9 steps, taken from the first numbered list in SKILL.md.

  1. Always use fully qualified names: Module.Entity, Module.Association
  2. Test incrementally: Create simple microflows first, then add complexity
  3. Check entity definitions: Ensure all attributes exist before referencing
  4. Use meaningful variable names: $Customer not $c, $ProductList not $list
  5. Comment complex logic: Use -- for inline comments
  6. Log important events: Help with debugging and auditing
  7. Handle empty cases: Check for = empty before using objects
  8. Use WITHOUT EVENTS appropriately: Only when handlers must be skipped (events are on by default)
  9. Validate before executing: Use mxcli check script.mdl -p app.mpr --references to catch errors

What it can do on your machine

Read from SKILL.md and the folder at commit a924d11. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are mdl).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • docs.mendix.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Write Microflows loads about 7.1k tokens when it runs. Until then it costs about 57 tokens; SKILL.md has 2,534 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~57
When it runs · the whole SKILL.md, loaded when a task matches
~7.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from mendixlabs/mxcli at commit a924d11, republished under its Apache-2.0 licence (© mendixlabs). 2,534 words, ~7,120 tokens.

Download SKILL.mdSave it as .claude/skills/write-microflows/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.
name
write-microflows
description
Microflow syntax reference in MDL — every activity type, control flow, expressions, and the mistakes that fail `mxcli check`. Use before writing any CREATE MICROFLOW, and when debugging a microflow syntax error.

Mendix Microflow Skill

Reference files

SKILL.md covers the shape of a microflow and the decisions. The detail lives beside it:

  • reference/control-flow.md — every form of if, case, split type, loop and while, plus error handling (try/custom handlers) and the @position / @merge / @anchor activity annotations.
  • reference/data-operations.md — create, change, commit, delete; list operations and aggregates; retrieve from database, association and list; XPath navigation.
  • reference/integration.md — rest call and send rest request, legacy SOAP, calling Java actions (including the empty argument and microflow-typed parameters), execute database query, file downloads.
  • reference/pitfalls.md — read this when mxcli check rejects something you believe is correct. The anti-patterns, the CE0111 duplicate-variable trap, the syntax that looks plausible and does not parse, and the Studio Pro errors each one produces.

When to Use This Skill

Use this skill when:

  • Writing CREATE MICROFLOW statements
  • Debugging microflow syntax errors
  • Converting Studio Pro microflows to MDL
  • Understanding microflow control flow and structure

If you're not sure whether the logic belongs in a microflow or a nanoflow, read the next section first. The mirror lives in write-nanoflows — keep both copies in sync.

Changing an Existing Microflow

Choose the mode by who owns the microflow (choose-edit-mode):

  • Created by your MDL scripts, and not edited in Studio Pro since: edit the script (or fresh describe output) and re-run create or modify.
  • Authored in Studio Pro: prefer alter microflow X { insert/replace/drop … } (targets from describe microflow X with handles). create or modify of describe output patches too: unchanged writes nothing; a statement (even one whose handler returns), guard clause, return value, if condition, header clause, parameter (added/retyped; removed only if unused) or stated @position/@start change is patched in place (a move keeps the node's flows). A redrawn @anchor/@curve, loop body, error handler or other return added/taken away rebuilds under mdl 0 (MDL-V1-REBUILD: IDs renumbered, merges and curves lost) and is refused under mdl 1;. To change a loop body, alter … replace the whole loop — neither mode edits inside one (pitfalls). To rebuild deliberately, drop and create in ONE script — the grants carry only within it (pitfalls).

When to Use a Microflow vs a Nanoflow

ScenarioUse
Querying the databaseMicroflow
Calling REST services or external actions, or sending email (send email, 11.13+)Microflow
Running Java actionsMicroflow
File generation or downloadMicroflow
Transactional commits (rollback on error)Microflow
Background scheduled logicMicroflow
Client-side form validation before saveNanoflow
UI navigation and page routingNanoflow
Calling device features (GPS, phone, camera)Nanoflow
Offline data access and local storageNanoflow
Calling JavaScript actions (NanoflowCommons)Nanoflow
Showing progress indicators / confirmation dialogsNanoflow

Rule of thumb: A nanoflow runs before the server call. A microflow IS the server call.

Key Differences from Nanoflows

AspectMicroflowNanoflow
ExecutionServer-sideClient-side (browser/mobile)
Database accessFullNo direct access
TransactionsSupportedNot supported
Java actionsSupportedNot supported
JavaScript actionsNot supportedSupported
SYNCHRONIZENot availableAvailable (offline sync)
File downloadsSupportedNot supported
Error handlingFull ON ERROR blocks; RAISE ERROR inside a handler only (main flow = MDL084 / CE0710)Per-action ON ERROR supported; RAISE ERROR / ErrorEvent forbidden
OfflineNot availableAvailable
Binary return typeSupportedNot supported

For nanoflow-specific authoring guidance, see write-nanoflows.

Microflow Structure

CRITICAL: All microflows MUST have JavaDoc-style documentation

mdl
/**
 * Microflow description explaining what it does
 *
 * Detailed explanation of the business logic, use cases,
 * and any important implementation notes.
 *
 * @param $Parameter1 Description of first parameter
 * @param $Parameter2 Description of second parameter
 * @returns Description of return value
 * @since 1.0.0
 * @author Team Name
 */
create microflow Module.MicroflowName (
  $Parameter1: type,
  $Parameter2: type
)
returns ReturnType as $ReturnVariable
[folder 'FolderPath']
begin
  -- Microflow logic here
  return $ReturnVariable;
end;
exposed as … action — putting a microflow in the toolbox

Studio Pro can show a microflow in its toolbox, so whoever drags it onto a flow does not need to know it is a microflow rather than a Java action. A microflow has two such entries — one for the microflow editor, one for the workflow editor — so the clause names which:

mdl
mdl 1;
create microflow Module.FormatCode ($Raw: String)
returns String
exposed as microflow action 'Format code' in 'Toolbox demo'
  icon 'assets/format-64.png'
  icon dark 'assets/format-64-dark.png'
  image 'assets/format-256.png'
exposed as workflow action 'Format code' in 'Toolbox demo'
begin
  return trim($Raw);
end;

The icon should be a 64x64 PNG and the image 256x192; paths resolve against the directory of the .mdl file, so a script and its artwork travel together. A different size is written with a warning; a file that is not a PNG is refused.

An omitted clause preserves what is stored — it does not clear it:

You writeWhat happens
exposed as microflow action 'X' in 'Y'Caption and category from MDL; icon and image carried from what was stored
(no clause)Both entries preserved, bitmaps included
not exposed as workflow actionRemoves that one entry; the microflow entry is untouched
… drop icon darkClears one bitmap; the other three are untouched

Rewriting a microflow's body must not cost it the icon a designer set in Studio Pro, and saying nothing about the toolbox is not asking to be taken out of it. Nothing below Studio Pro sees the difference — mx check reports 0 errors either way — so the preserve rule is the only thing protecting it.

Nanoflows and rules cannot be exposed. Only Microflows$Microflow stores a toolbox entry; the clause is refused on the other two with a message naming the alternative. Java and JavaScript actions have one entry each and use the shorter exposed as 'Caption' in 'Category' — see the java-actions skill.

@excluded — documents excluded from the project

@excluded before a create microflow marks the document "Exclude from project" (the same checkbox Studio Pro offers). The document stays in the .mpr, does not build, and list microflows reports it in the Excluded column.

mdl
mdl 1;
@excluded
create microflow MyModule.LegacyCalc ()
returns Integer
begin
  return 7;
end;

The sibling document annotation is @applyentityaccess — runs the flow under the current user's entity access rules rather than with full access, with the same absent-preserves rule and an explicit (false) to turn it off (pitfalls).

Two rules follow, and both are enforced rather than documented-and-hoped:

  • An absent @excluded never un-excludes. It means "the script does not say", not "make this active" — so re-running a create or modify you wrote before the document was excluded leaves the exclusion alone. Un-exclude in Studio Pro. (Before #914 the rewrite cleared it, which is how a valid project ended up failing CE0122 — see the next rule.)
  • A name is not unique when a twin is excluded. Mendix allows two documents of the same name in one module as long as at most one is active — verified on 11.13.0: the excluded pair builds at 0 errors, the same pair both active is [error] CE0122 "Duplicate document name". create or modify, describe and the other by-name lookups therefore target the live document; the excluded twin is neither rewritten nor deleted.

The same applies to every document type that carries the flag — nanoflows, pages, snippets, enumerations, queues, workflows, Java/JavaScript actions, mappings, JSON structures, REST/OData services, image collections and the agent documents.

FOLDER Option

Place microflows in folders for organization:

mdl
mdl 1;
create microflow MyModule.ACT_ProcessOrder ($Order: MyModule.Order)
returns boolean as $success
folder 'Orders/Processing'
begin
  -- logic
  return true;
end;

Key Rules:

  • Parameters start with $ prefix
  • Return variable must be declared or used
  • Every microflow must end with return statement
  • Every body statement ends with a semicolon ; — required, not optional. This includes block terminators: end if;, end loop;, end while;, end case;. A missing one is a parse error (missing ';' at 'return'), not a warning.
  • Microflow ends with / separator
Parameter Types
mdl
-- Primitive types
$Name: string
$count: integer
$Amount: decimal
$IsActive: boolean
$date: datetime

-- Entity types
$Customer: Module.Entity

-- List types
$ProductList: list of Module.Product

-- Enumeration types
$status: enum Module.OrderStatus

Variable Declarations

✅ CORRECT Syntax
mdl
-- Primitive types with initialization
declare $Counter integer = 0;
declare $message string = 'Hello';
declare $IsValid boolean = true;
declare $Today datetime = [%CurrentDateTime%];
declare $status Enumeration(Module.OrderStatus) = Module.OrderStatus.Open;

You cannot declare an object (entity) variable. declare becomes a Create Variable activity, which Mendix only allows to hold primitive types (String, Integer/Long, Decimal, Boolean, DateTime, Enumeration). An object type is rejected by Studio Pro/mxbuild with CE0053 ("Selected type is not allowed"), plus CE0038 ("Value required") and CE7247 on any following set — whether or not you give it an initializer. mxcli check now flags it as MDL043. There is no "empty object variable" activity. Get objects from one of these:

  • a microflow parameter: create microflow M.Save ($Product: Test.Product) ...
  • a retrieve: retrieve $Product from Test.Product where Code = $c first;
  • a create object: $Product = create Test.Product (Name = $n);
  • a loop iterator: loop $Product in $Products ...

You cannot declare a list either. Same Create Variable restriction — Studio Pro rejects a list with CE0053/CE0038, and mxcli check flags it as MDL040. Get lists from:

  • a microflow parameter: create microflow M.Process ($Items: list of Test.Product) ...
  • a retrieve: retrieve $Products from Test.Product where IsActive = true;
  • a create list: $Products = create list of Test.Product;

Decimal values into an integer/long fail CE0117. Integer division ($a div $b) is always a Decimal even for two integers, and so are random() and the duration *Between functions (secondsBetween, minutesBetween, hoursBetween, daysBetween, weeksBetween). Assigning any of them straight to an integer/long variable fails mx check with CE0117 (mxcli check now flags it as MDL041). Either declare the target decimal, or round it:

mdl
declare $Avg decimal = $Total div $Count;          -- ✅ Decimal target
declare $Whole integer = round($Total div $Count); -- ✅ rounded to Integer
declare $Secs integer = round(secondsBetween($a,$b)); -- ✅ rounded to Integer
declare $Bad integer = $Total div $Count;          -- ❌ CE0117 / MDL041

The calendar*Between functions (calendarMonthsBetween, calendarYearsBetween) return whole units (Integer) and are fine to assign directly.

Changing a variable: always set

set $Counter = $Counter + 1; changes a variable. $x = … without set is an activity that creates $x — required under mdl 1; (MDL-V1-SET otherwise). List operations and aggregates are one statement per activity and never nest: $Open = filter $Orders by Status = M.Status.Open; then $N = count $Open; — see reference/data-operations.md.

❌ INCORRECT Syntax
mdl
-- WRONG: Declaring an object/entity variable (CE0053/CE0038, MDL043)
declare $Product Test.Product;            -- bare object declare is invalid
declare $Product Test.Product = $someObj; -- initialized object declare is also invalid

-- WRONG: Declaring a list variable (CE0053/CE0038, MDL040)
declare $ProductList list of Test.Product = empty;  -- use a parameter, retrieve, or create list

-- WRONG: Using AS keyword (not supported in mxcli)
declare $Product as Test.Product;  -- ERROR: parse error

-- WRONG: No value (CE0038, MDL061)
declare $X string;  -- a Create Variable activity requires a value

-- WRONG: Missing type
declare $Counter = 0;  -- Type inference not always supported

-- WRONG: Using 'OF' instead of 'of'
declare $list list of Test.Product;  -- Case sensitive

Operators

Arithmetic
mdl
set $Result = $A + $B;      -- Addition
set $Result = $A - $B;      -- Subtraction
set $Result = $A * $B;      -- Multiplication
set $Result = $A div $B;    -- Division (use 'div', not '/')

Important: Use div for division, NOT /. In a Mendix expression / is the member/association separator ($obj/Attr), so $A / $B is not division — mxcli check rejects it as MDL045 (it would fail the build with CE0117). Integer/decimal division always yields a Decimal; wrap it in round()/trunc() for an Integer result (else MDL041).

Comparison
mdl
$A = $B       -- Equals
$A != $B      -- Not equals
$A > $B       -- Greater than
$A >= $B      -- Greater than or equal
$A < $B       -- Less than
$A <= $B      -- Less than or equal
$A = empty    -- Check if empty/null
$A != empty   -- Check if not empty
Boolean Logic
mdl
set $Result = $A and $B;    -- Logical AND
set $Result = $A or $B;     -- Logical OR
set $Result = not $A;       -- Logical NOT

-- Complex expressions
if $IsActive and $IsValid and $HasStock then
  set $CanProcess = true;
end if;
Show full SKILL.md (1,028 more words)Show less
Date construction

dateTime(...) / dateTimeUTC(...) build a date from literal numeric constants only — a variable or computed argument fails the build with CE0117 (mxcli check flags it as MDL046). To build a date from variables, step off a literal anchor with addDays() / addMonths() (which do take variables):

mdl
-- WRONG: variable args to dateTime() (CE0117 / MDL046)
set $D = dateTime(2026, $Month, $Day);

-- RIGHT: anchor on a literal, then step with addMonths/addDays
set $D = addDays(addMonths(dateTime(2026, 1, 1), $Month - 1), $Day - 1);

Logging

mdl
-- Log levels
log info 'Information message';
log warning 'Warning message';
log error 'Error message';

-- With node name
log info node 'OrderService' 'Processing order';
log warning node 'ValidationService' 'Invalid data detected';

-- With variables (use concatenation)
log info node 'OrderService' 'Order processed: ' + $OrderNumber;
log error node 'Service' 'Error: ' + $ErrorMessage;

Special Values

mdl
empty                      -- Null/empty value
[%CurrentDateTime%]        -- Current date/time
[%CurrentUser%]            -- Current user object
toString($value)           -- Convert to string

No randomInt. Mendix has no randomInt function. Use random() (returns a Decimal in [0,1)) and round to an integer range — e.g. a value in 0..8 is round(random() * 8). Because random() is a Decimal, assigning it (or div, secondsBetween(), and the other duration *Between functions) directly to an integer variable fails the build with CE0117 — wrap it in round()/floor()/ceil(). mxcli check now flags an unknown expression function like randomInt as MDL044 (with a "did you mean random()?" hint), and a Decimal assigned to an integer target as MDL041 — before the build does.

MDL044 also blocks mxcli exec, not just check: a call to a name Mendix has no built-in for is CE0117 at build time, so exec refuses to write the microflow or nanoflow (log messages included). Not real: currentDeviceType(), [%CurrentDeviceType%] (a CE0117 check misses) and trunc() (use round/floor/ceil). If exec rejects a function you believe IS a Mendix built-in, build it once and — if mxbuild accepts it — add it to funcTable in mdl/exprcheck/func_checker.go; that table is the rule's only allow-list.

Complete Example

mdl
mdl 1;
/**
 * Process order with validation and status update.
 *
 * @param $OrderNumber The order to process
 * @returns true when the order was found and marked processed
 */
create microflow Shop.ProcessOrder (
  $OrderNumber: string
)
returns boolean as $success
begin
  declare $success boolean = false;

  -- Find the order (the retrieve establishes $Order — objects are never declared)
  retrieve $Order from Shop.Order
    where OrderNumber = $OrderNumber;

  -- Validate order exists
  if $Order = empty then
    log warning node 'OrderService' 'Order not found: ' + $OrderNumber;
    return false;
  end if;

  -- Validate customer association
  if $Order/Shop.Order_Customer = empty then
    log error node 'OrderService' 'Order has no customer';
    return false;
  end if;

  -- Update order status
  change $Order (
    status = 'PROCESSING',
    ProcessedDate = [%CurrentDateTime%]);

  commit $Order;

  -- Log success
  log info node 'OrderService' 'Order processed: ' + $OrderNumber;
  set $success = true;
  return $success;
end;

Calling Microflows

✅ CORRECT Syntax
mdl
-- Call with result assignment (no SET keyword)
$Result = call microflow Module.ProcessOrder(Order = $Order);

-- Call without result (void microflow)
call microflow Module.SendNotification(message = $message);

-- Call with error handling
$Result = call microflow Module.ExternalService(data = $data) on error continue;

-- Run the call on a task queue (background execution). The clause goes after
-- the arguments and before any ON ERROR, and works on CALL JAVA ACTION too.
call microflow Module.ACT_Refresh() in queue Module.RefreshQueue;
call java action Module.RefreshData(Url = $Url) in queue Module.RefreshQueue;

Queued calls — the queue must already exist (create task queue Module.RefreshQueue (Parallelism: 2)), and the called flow must return nothing: a queued microflow with a returns clause fails the build with CE7033 (mxcli check: MDL088), a queued Java action must returns void or it fails with CE7038. Rewriting a microflow that has a queued call must restate the in queue clause; a rewrite that omits it is refused rather than silently dropping the binding. See .claude/skills/mendix/scheduled-events-and-queues.

❌ INCORRECT Syntax
mdl
-- WRONG: Do NOT use SET with CALL MICROFLOW
set $Result = call microflow Module.ProcessOrder(Order = $Order);  -- ERROR!

-- CORRECT: Direct variable assignment
$Result = call microflow Module.ProcessOrder(Order = $Order);

Important: The set keyword is for changing existing variable values, NOT for capturing microflow return values. Use direct assignment ($var = call microflow ...).

Parameter Name Matching

CRITICAL: Parameter names in call microflow must exactly match the parameter names declared in the target microflow's signature (without the $ prefix). A mismatch causes a build error (MxBuild) but may fail silently at MDL execution time.

mdl
-- Target microflow declaration:
create microflow Module.SendEmail ($Recipient: string, $Subject: string)
begin ... end;

-- CORRECT: parameter names match the declaration
call microflow Module.SendEmail(Recipient = $Email, Subject = $title);

-- WRONG: parameter name does not match (EmailAddress vs Recipient)
call microflow Module.SendEmail(EmailAddress = $Email, Subject = $title);  -- BUILD ERROR!

When calling microflows, always check the target's parameter list. Use describe microflow Module.Name to see the exact parameter names.

Page Navigation

SHOW PAGE
mdl
-- Open page with parameter
show page Module.EditPage(Product = $Product);

Every call site binds an argument as Param = expression, with no $ on the parameter name: call microflow, show page, and widget actions (action: show page Module.Page(Param = $value)) alike. $Param = $value and Param: $value still parse but are deprecated (MDL-DEPR006/007); mxcli fmt --upgrade rewrites them.

CLOSE PAGE
mdl
close page;
SHOW HOME PAGE
mdl
show home page;

Validation Checklist

Before executing a microflow script, verify:

  • No object (entity) or list is declared — objects come from a parameter, retrieve, create object, or loop iterator (MDL043); lists from a parameter, retrieve, or create list (MDL040)
  • All primitive variables are declared before SET (declare $var type = value;)
  • XPath association navigation uses qualified names (Module.AssociationName)
  • All referenced attributes exist in entity definitions
  • Every flow path ends with return
  • No code appears after return statements
  • Division uses div operator (not /)
  • All entity/association names are fully qualified
  • CALL MICROFLOW parameter names exactly match target signature (use describe microflow to verify)
  • Microflow ends with / separator
  • Parameters start with $ prefix
  • Proper closing for control structures (end if, end loop)

Tips for Success

  1. Always use fully qualified names: Module.Entity, Module.Association
  2. Test incrementally: Create simple microflows first, then add complexity
  3. Check entity definitions: Ensure all attributes exist before referencing
  4. Use meaningful variable names: $Customer not $c, $ProductList not $list
  5. Comment complex logic: Use -- for inline comments
  6. Log important events: Help with debugging and auditing
  7. Handle empty cases: Check for = empty before using objects
  8. Use WITHOUT EVENTS appropriately: Only when handlers must be skipped (events are on by default)
  9. Validate before executing: Use mxcli check script.mdl -p app.mpr --references to catch errors

Quick Reference

Variable Declaration Pattern
mdl
declare $primitive type = value;              -- Primitives (String/Integer/Decimal/Boolean/DateTime)
declare $status Enumeration(Module.Enum) = …; -- Enumerations are primitives too
-- Objects: never declare. Use a parameter, retrieve (… first), `$obj = create Module.Entity(...)`, or a loop iterator.
-- Lists:   never declare. Use a parameter, retrieve, or `$list = create list of Module.Entity;`
Object Operation Pattern
mdl
$var = create Module.Entity (attr = value);
change $var (attr = value);
commit $var [without events] [refresh];
Flow Control Pattern
mdl
if condition then ... [else ...] end if;
loop $var in $list begin ... end loop;
return $value;
XPath Pattern
mdl
$var/attributename                      -- Attribute
$var/Module.AssociationName             -- Association
$var/Module.AssociationName/attribute   -- Chained
Annotation Pattern
mdl
@position(200, 200)          -- optional: omit it and mxcli lays the flow out; to re-arrange an existing flow run `mxcli layout flows`
@caption 'Persist order'
@color Green
@annotation 'Note about the next activity'
commit $Order;                                          -- Annotations apply here
Annotations Are Notes, and a Note Can Be Shared

A note is a node with edges in Mendix, not a property of the activity it documents. So @annotation is repeatable — one activity can carry several, each its own note — and one note can be attached to several activities:

mdl
@annotation(id: n1, text: 'both of these touch the same record')
commit $Order;
@annotation(id: n1)                     -- attaches THAT note, does not copy it
commit $Invoice;

id: is scoped to the flow you are writing and is not stored in the model; it exists only so a second mention can point at the first. Without it, two lines with identical text are two separate notes — mxcli never merges on text.

A note's own canvas geometry is position: (x, y) and size: (w, h), e.g. @annotation(text: 'note', position: (175, -40), size: (260, 70)). Omit them and the note goes 100px above the activity at 200×50, stacking 60px per extra note; DESCRIBE omits them again whenever they match, so an ordinary note keeps the short @annotation 'text' form.

Page Navigation Pattern
mdl
show page Module.Page(Param = $value);
close page;
show home page;
Error Handling Pattern
mdl
call microflow ... on error continue;                  -- Ignore error
call microflow ... on error rollback;                  -- Rollback on error
call microflow ... on error begin log ...; return ...; end error;  -- Custom handler
call microflow ... on error without rollback begin ... end error;  -- No rollback

The clause goes on whichever activity may fail, not only on calls:

mdl
declare $Name String = 'default' on error begin return 'could not initialise'; end error;
set $Name = $Other/Name on error begin return 'lookup failed'; end error;
change $Order (Status = Shipped) on error begin log error 'could not ship'; return; end error;
log info node 'App' 'starting' on error begin return; end error;
show message 'saved' on error begin return; end error;

-- BLOCKING halts the client until dismissed; after `objects`, before `on error`.
show message 'Hello {1}' type Warning with ({1} = $Name) blocking;
validation feedback $Order/Total message 'must be positive' on error begin return; end error;
show page Module.Page on error begin return; end error;
close page on error begin return; end error;

Two limits, both reported rather than silently ignored:

  • on error continue is rejected by Mendix (CE6035) on create, change, commit, log, show page, close page, show message and validation feedback — MDL076. A custom { handler } is accepted on all of them; continue is fine on declare, set, retrieve, delete and call microflow. Measured on 11.14.0 — note that create-variable and change-variable accept continue while change-object does not.
  • List operations and aggregates ($x = head $l;, $n = count $l;) have no error handling in Mendix at all — MDL077.

In a nanoflow, almost none of them take a clause at all. change, log, show page, close page, show message and validation feedback are CE6035 there whichever form is written; only declare and set accept one. See write-nanoflows.

End the handler. A handler body that does not finish with return or throw merges back into the main flow, so a variable created after the merge point is out of scope on the error path — CE0108, which Studio Pro reports for the same model. Ending the handler (as Studio Pro does when you wire it to an end event) avoids this entirely.

© mendixlabs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 4 other files in .claude/skills/mendix/write-microflows of mendixlabs/mxcli.

  • SKILL.md
  • reference/control-flow.md
  • reference/data-operations.md
  • reference/integration.md
  • reference/pitfalls.md

Open the folder on GitHubat commit a924d11

Compare with similar skills

Write Microflows next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Write Microflows compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Write Microflows this skillmendixlabs/mxcli128—~7.1kAutomated safety check: PassApache-2.0
Finishing a Development Branchobra/superpowers296k5 repos~1.9kAutomated safety check: PassMIT
Typescript Advanced Typesrolling-scopes/rsschool-app10k24 repos~4.2kAutomated safety check: PassMPL-2.0
PR Babysitteropeninterpreter/openinterpreter69k3 repos~4.2kAutomated safety check: PassApache-2.0
Code Review ChecklistshareAI-lab/learn-claude-code78k5 repos~1.1kAutomated safety check: PassMIT
Greplooponyx-dot-app/onyx32k4 repos~3.3kAutomated safety check: PassMIT

Similar skills

  • Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.

    296k GitHub starsUsed in 5 repos~1.9k tokens
    DevelopmentAuto-check passed
  • Typescript Advanced Types

    rolling-scopes/rsschool-app

    Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications.

    10k GitHub starsUsed in 24 repos~4.2k tokens
    DevelopmentAuto-check passed
  • PR Babysitter

    openinterpreter/openinterpreter

    Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.

    69k GitHub starsUsed in 3 repos~4.2k tokens
    DevelopmentAuto-check passed
  • Code Review Checklist

    shareAI-lab/learn-claude-code

    Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.

    78k GitHub starsUsed in 5 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Greploop

    onyx-dot-app/onyx

    Iteratively improves a PR (GitHub), MR (GitLab), or shelved changelist (Perforce) until Greptile gives it a 5/5 confidence score with zero unresolved comments.

    32k GitHub starsUsed in 4 repos~3.3k tokens
    DevelopmentAuto-check passed
  • Guidelines

    akash-network/node

    Behavioral guidelines to reduce common LLM coding mistakes. An agent skill from akash-network/node.

    1.1k GitHub starsUsed in 22 repos~577 tokens
    DevelopmentAuto-check passed

More from mendixlabs/mxcli

All 75 skills in this repo
  • Mendix Odata Pushdown

    mendixlabs/mxcli

    Push OData query options into the SQL of a Mendix resource served by a read microflow, so $filter, $orderby, $top, $skip, $count and the key lookup reach the database instead of being silently…

    128 GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Mendix Vega Charts

    mendixlabs/mxcli

    Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload.

    128 GitHub stars~3k tokensUpdated today
    Auto-check passed
  • Agents

    mendixlabs/mxcli

    Author Mendix AI agent documents in MDL — Model, Knowledge Base, Consumed MCP Service and Agent, with variables, tools and multi-line prompts.

    128 GitHub starsUsed in 1 repo~2.2k tokens
    Auto-check passed
  • Mendix Bulk Oql Dml

    mendixlabs/mxcli

    Run set-based INSERT, UPDATE and DELETE against Mendix entities through OQL statements, which the runtime supports and Studio Pro cannot author.

    128 GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • Mock REST APIs

    mendixlabs/mxcli

    Stand up an HTTP endpoint you control instead of a live third-party API, and point the Mendix app at it — Prism from an OpenAPI contract, a constant swap, or a forward proxy.

    128 GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • REST Client

    mendixlabs/mxcli

    Call external REST APIs from Mendix — the three approaches (inline REST CALL, consumed REST client document, generated from OpenAPI) and how to choose.

    128 GitHub starsUsed in 1 repo~3.9k tokens
    Auto-check passed

Categories

Questions about Write Microflows

What does Write Microflows do?

Microflow syntax reference in MDL — every activity type, control flow, expressions, and the mistakes that fail mxcli check. Write Microflows is an agent skill from mendixlabs/mxcli. Microflow syntax reference in MDL — every activity type, control flow, expressions, and the mistakes that fail mxcli check.

When should I use Write Microflows?

Write Microflows fits situations like: development work in your project.

How do I install Write Microflows in Claude Code?

Run `npx skills add mendixlabs/mxcli --skill write-microflows -a claude-code`. Or copy the skill folder (.claude/skills/mendix/write-microflows in mendixlabs/mxcli) into .claude/skills/write-microflows in your project. Claude Code loads it when a task matches its description.

How do I install Write Microflows in Codex?

Run `npx skills add mendixlabs/mxcli --skill write-microflows -a codex`. Or copy the skill folder (.claude/skills/mendix/write-microflows in mendixlabs/mxcli) into .agents/skills/write-microflows in your project. Codex loads it when a task matches its description.

Can I use Write Microflows in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mendixlabs/mxcli --skill write-microflows -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/write-microflows, .gemini/skills/write-microflows, .github/skills/write-microflows and .opencode/skills/write-microflows in your project.

What does Write Microflows need to run?

SKILL.md names no scripts, command-line tools or credentials: Write Microflows is instructions for the agent only.

Does Write Microflows access the network?

SKILL.md names 1 domain. As links in the text: docs.mendix.com. This is read from the text; nothing was executed.

Is Write Microflows safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Write Microflows use?

Write Microflows is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Write Microflows use?

About 7.1k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Write Microflows?

Skills that share tags, products or a category with Write Microflows: Finishing a Development Branch (obra/superpowers, 296k stars), Typescript Advanced Types (rolling-scopes/rsschool-app, 10k stars), PR Babysitter (openinterpreter/openinterpreter, 69k stars) and Code Review Checklist (shareAI-lab/learn-claude-code, 78k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Write Microflows?

mendixlabs (a GitHub organization) maintains it in mendixlabs/mxcli, which has 128 GitHub stars. The repository holds 75 skills in this directory. The repository was last updated on October 7, 2026.

Source: mendixlabs/mxcli on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.