Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MDL Quick Reference

Complete syntax reference for MDL (Mendix Definition Language). This is the authoritative reference for all MDL statement syntax.

Entity Generalization (EXTENDS)

CRITICAL: EXTENDS goes BEFORE the opening parenthesis, not after!

-- Correct: EXTENDS before (
CREATE PERSISTENT ENTITY Module.ProductPhoto EXTENDS System.Image (
  PhotoCaption: String(200)
);

-- Wrong: EXTENDS after ) = parse error!
CREATE PERSISTENT ENTITY Module.Photo (
  PhotoCaption: String(200)
) EXTENDS System.Image;

Domain Model

StatementSyntaxNotes
Create entityCREATE [OR MODIFY] PERSISTENT|NON-PERSISTENT ENTITY Module.Name (attrs);Persistent is default
Create with extendsCREATE PERSISTENT ENTITY Module.Name EXTENDS Parent.Entity (attrs);EXTENDS before (
Create view entityCREATE VIEW ENTITY Module.Name (attrs) AS SELECT ...;OQL-backed read-only
Create external entityCREATE EXTERNAL ENTITY Module.Name FROM ODATA CLIENT Module.Client (...) (attrs);From consumed OData
Drop entityDROP ENTITY Module.Name;
Describe entityDESCRIBE ENTITY Module.Name;Full MDL output
Show entitiesSHOW ENTITIES [IN Module];List all or filter by module
Create enumerationCREATE [OR MODIFY] ENUMERATION Module.Name (Value1 'Caption', ...);
Drop enumerationDROP ENUMERATION Module.Name;
Create associationCREATE ASSOCIATION Module.Name FROM Parent TO Child TYPE Reference|ReferenceSet [OWNER Default|Both] [DELETE_BEHAVIOR ...];
Drop associationDROP ASSOCIATION Module.Name;

ALTER ENTITY

Modifies an existing entity without full replacement.

OperationSyntaxNotes
Add attributesALTER ENTITY Module.Name ADD (Attr: Type [constraints]);One or more attributes
Drop attributesALTER ENTITY Module.Name DROP (AttrName, ...);
Modify attributesALTER ENTITY Module.Name MODIFY (Attr: NewType [constraints]);Change type/constraints
Rename attributeALTER ENTITY Module.Name RENAME OldName TO NewName;
Add indexALTER ENTITY Module.Name ADD INDEX (Col1 [ASC|DESC], ...);
Drop indexALTER ENTITY Module.Name DROP INDEX (Col1, ...);
Set documentationALTER ENTITY Module.Name SET DOCUMENTATION 'text';

Example:

ALTER ENTITY Sales.Customer
  ADD (Phone: String(50), Notes: String(unlimited));

ALTER ENTITY Sales.Customer
  RENAME Phone TO PhoneNumber;

ALTER ENTITY Sales.Customer
  ADD INDEX (Email);

Constants

StatementSyntaxNotes
Show constantsSHOW CONSTANTS [IN Module];List all or filter by module
Describe constantDESCRIBE CONSTANT Module.Name;Full MDL output
Create constantCREATE [OR MODIFY] CONSTANT Module.Name TYPE DataType DEFAULT 'value';String, Integer, Boolean, etc.
Drop constantDROP CONSTANT Module.Name;

Example:

CREATE CONSTANT MyModule.ApiBaseUrl TYPE String DEFAULT 'https://api.example.com';
CREATE CONSTANT MyModule.MaxRetries TYPE Integer DEFAULT 3;
CREATE CONSTANT MyModule.EnableLogging TYPE Boolean DEFAULT true;

OData Clients, Services & External Entities

StatementSyntaxNotes
Show OData clientsSHOW ODATA CLIENTS [IN Module];Consumed OData services
Describe OData clientDESCRIBE ODATA CLIENT Module.Name;Full MDL output
Create OData clientCREATE [OR MODIFY] ODATA CLIENT Module.Name (...);Version, MetadataUrl, Timeout, etc.
Alter OData clientALTER ODATA CLIENT Module.Name SET Key = Value;
Drop OData clientDROP ODATA CLIENT Module.Name;
Show OData servicesSHOW ODATA SERVICES [IN Module];Published OData services
Describe OData serviceDESCRIBE ODATA SERVICE Module.Name;Full MDL output
Create OData serviceCREATE [OR MODIFY] ODATA SERVICE Module.Name (...) AUTHENTICATION ... { PUBLISH ENTITY ... };
Alter OData serviceALTER ODATA SERVICE Module.Name SET Key = Value;
Drop OData serviceDROP ODATA SERVICE Module.Name;
Show external entitiesSHOW EXTERNAL ENTITIES [IN Module];OData-backed entities
Create external entityCREATE [OR MODIFY] EXTERNAL ENTITY Module.Name FROM ODATA CLIENT Module.Client (...) (attrs);
Grant OData accessGRANT ACCESS ON ODATA SERVICE Module.Name TO Module.Role, ...;
Revoke OData accessREVOKE ACCESS ON ODATA SERVICE Module.Name FROM Module.Role, ...;

OData Client Example:

CREATE ODATA CLIENT MyModule.ExternalAPI (
  Version: '1.0',
  ODataVersion: OData4,
  MetadataUrl: 'https://api.example.com/odata/v4/$metadata',
  Timeout: 300
);

OData Service Example:

CREATE ODATA SERVICE MyModule.CustomerAPI (
  Path: '/odata/customers',
  Version: '1.0.0',
  ODataVersion: OData4,
  Namespace: 'MyModule.Customers'
)
AUTHENTICATION Basic, Session
{
  PUBLISH ENTITY MyModule.Customer AS 'Customers' (
    ReadMode: SOURCE,
    InsertMode: SOURCE,
    UpdateMode: NOT_SUPPORTED,
    DeleteMode: NOT_SUPPORTED,
    UsePaging: Yes,
    PageSize: 100
  )
  EXPOSE (Name, Email, Phone);
};

Microflows - Supported Statements

StatementSyntaxNotes
Variable declarationDECLARE $Var Type = value;Primitives: String, Integer, Boolean, Decimal, DateTime
Entity declarationDECLARE $Entity Module.Entity;No AS keyword, no = empty
List declarationDECLARE $List List of Module.Entity = empty;
AssignmentSET $Var = expression;Variable must be declared first
Create object$Var = CREATE Module.Entity (Attr = value);
Change objectCHANGE $Entity (Attr = value);
CommitCOMMIT $Entity [WITH EVENTS] [REFRESH];
DeleteDELETE $Entity;
RollbackROLLBACK $Entity [REFRESH];Reverts uncommitted changes
Retrieve (DB)RETRIEVE $Var FROM Module.Entity [WHERE condition];Database XPath retrieve
Retrieve (Assoc)RETRIEVE $List FROM $Parent/Module.AssocName;Retrieve by association
Call microflow$Result = CALL MICROFLOW Module.Name (Param = $value);
Call nanoflow$Result = CALL NANOFLOW Module.Name (Param = $value);
Show pageSHOW PAGE Module.PageName ($Param = $value);Also accepts (Param: $value)
Close pageCLOSE PAGE;
ValidationVALIDATION FEEDBACK $Entity/Attribute MESSAGE 'message';Requires attribute path + MESSAGE
LogLOG INFO|WARNING|ERROR [NODE 'name'] 'message';
Position@position(x, y)Canvas position (before activity)
Caption@caption 'text'Custom caption (before activity)
Color@color GreenBackground color (before activity)
Annotation@annotation 'text'Visual note attached to next activity
IFIF condition THEN ... [ELSE ...] END IF;
LOOPLOOP $Item IN $List BEGIN ... END LOOP;FOR EACH over list
WHILEWHILE condition BEGIN ... END WHILE;Condition-based loop
ReturnRETURN $value;Required at end of every flow path
Execute DB query$Result = EXECUTE DATABASE QUERY Module.Conn.Query;3-part name; supports DYNAMIC, params, CONNECTION override
Error handling... ON ERROR CONTINUE|ROLLBACK|{ handler };Not supported on EXECUTE DATABASE QUERY

Microflows - NOT Supported (Will Cause Parse Errors)

UnsupportedUse InsteadNotes
CASE ... WHEN ... END CASENested IF ... ELSE ... END IFSwitch not implemented
TRY ... CATCH ... END TRYON ERROR { ... } blocksUse error handlers on specific activities

Notes:

  • RETRIEVE ... LIMIT n IS supported. LIMIT 1 returns a single entity, otherwise returns a list.
  • ROLLBACK $Entity [REFRESH]; IS supported. Rolls back uncommitted changes to an object.

Project Organization

StatementSyntaxNotes
Microflow folderFOLDER 'path' (before BEGIN)CREATE MICROFLOW ... FOLDER 'ACT' BEGIN ... END;
Page folderFolder: 'path' (in properties)CREATE PAGE ... (Folder: 'Pages/Detail') { ... }
Move to folderMOVE PAGE|MICROFLOW|SNIPPET|NANOFLOW|ENUMERATION Module.Name TO FOLDER 'path';Folders created automatically
Move to module rootMOVE PAGE Module.Name TO Module;Removes from folder
Move across modulesMOVE PAGE Old.Name TO NewModule;Breaks by-name references – use SHOW IMPACT OF first
Move to folder in other moduleMOVE PAGE Old.Name TO FOLDER 'path' IN NewModule;
Move entity to moduleMOVE ENTITY Old.Name TO NewModule;Entities don’t support folders

Nested folders use / separator: 'Parent/Child/Grandchild'. Missing folders are auto-created.

Security Management

StatementSyntaxNotes
Show project securitySHOW PROJECT SECURITY;Displays security level, admin, demo users
Show module rolesSHOW MODULE ROLES [IN Module];All roles or filtered by module
Show user rolesSHOW USER ROLES;Project-level user roles
Show demo usersSHOW DEMO USERS;Configured demo users
Show access on elementSHOW ACCESS ON MICROFLOW|PAGE|Entity Mod.Name;Which roles can access
Show security matrixSHOW SECURITY MATRIX [IN Module];Full access overview
Create module roleCREATE MODULE ROLE Mod.Role [DESCRIPTION 'text'];
Drop module roleDROP MODULE ROLE Mod.Role;
Create user roleCREATE USER ROLE Name (Mod.Role, ...) [MANAGE ALL ROLES];Aggregates module roles
Alter user roleALTER USER ROLE Name ADD|REMOVE MODULE ROLES (Mod.Role, ...);
Drop user roleDROP USER ROLE Name;
Grant microflow accessGRANT EXECUTE ON MICROFLOW Mod.MF TO Mod.Role, ...;
Revoke microflow accessREVOKE EXECUTE ON MICROFLOW Mod.MF FROM Mod.Role, ...;
Grant page accessGRANT VIEW ON PAGE Mod.Page TO Mod.Role, ...;
Revoke page accessREVOKE VIEW ON PAGE Mod.Page FROM Mod.Role, ...;
Grant entity accessGRANT Mod.Role ON Mod.Entity (CREATE, DELETE, READ *, WRITE *);Supports member lists and WHERE
Revoke entity accessREVOKE Mod.Role ON Mod.Entity;
Set security levelALTER PROJECT SECURITY LEVEL OFF|PROTOTYPE|PRODUCTION;
Toggle demo usersALTER PROJECT SECURITY DEMO USERS ON|OFF;
Create demo userCREATE DEMO USER 'name' PASSWORD 'pass' [ENTITY Module.Entity] (UserRole, ...);
Drop demo userDROP DEMO USER 'name';

Workflows

StatementSyntaxNotes
Show workflowsSHOW WORKFLOWS [IN Module];List all or filter by module
Describe workflowDESCRIBE WORKFLOW Module.Name;Full MDL output
Create workflowCREATE [OR MODIFY] WORKFLOW Module.Name PARAMETER $Ctx: Module.Entity BEGIN ... END WORKFLOW;See activity types below
Drop workflowDROP WORKFLOW Module.Name;
Grant workflow accessGRANT EXECUTE ON WORKFLOW Module.Name TO Mod.Role, ...;
Revoke workflow accessREVOKE EXECUTE ON WORKFLOW Module.Name FROM Mod.Role, ...;

Workflow Activity Types:

  • USER TASK <name> '<caption>' [PAGE Mod.Page] [TARGETING MICROFLOW Mod.MF] [OUTCOMES '<out>' { } ...];
  • CALL MICROFLOW Mod.MF [COMMENT '<text>'] [OUTCOMES '<out>' { } ...];
  • CALL WORKFLOW Mod.WF [COMMENT '<text>'];
  • DECISION ['<caption>'] OUTCOMES '<out>' { } ...;
  • PARALLEL SPLIT PATH 1 { } PATH 2 { };
  • JUMP TO <activity-name>;
  • WAIT FOR TIMER ['<expr>'];
  • WAIT FOR NOTIFICATION;
  • END;

Example:

CREATE WORKFLOW Module.ApprovalFlow
  PARAMETER $Context: Module.Request
  OVERVIEW PAGE Module.WorkflowOverview
BEGIN
  USER TASK ReviewTask 'Review the request'
    PAGE Module.ReviewPage
    OUTCOMES 'Approve' { } 'Reject' { };
END WORKFLOW;

Project Structure

StatementSyntaxNotes
Structure overviewSHOW STRUCTURE;Depth 2 (elements with signatures), user modules only
Module countsSHOW STRUCTURE DEPTH 1;One line per module with element counts
Full typesSHOW STRUCTURE DEPTH 3;Typed attributes, named parameters
Filter by moduleSHOW STRUCTURE IN ModuleName;Single module only
Include all modulesSHOW STRUCTURE DEPTH 1 ALL;Include system/marketplace modules
StatementSyntaxNotes
Show navigationSHOW NAVIGATION;Summary of all profiles
Show menu treeSHOW NAVIGATION MENU [Profile];Menu tree for profile or all
Show home pagesSHOW NAVIGATION HOMES;Home page assignments across profiles
Describe navigationDESCRIBE NAVIGATION [Profile];Full MDL output (round-trippable)
Create/replace navigationCREATE OR REPLACE NAVIGATION Profile ...;Full replacement of profile

Navigation Example:

CREATE OR REPLACE NAVIGATION Responsive
  HOME PAGE MyModule.Home_Web
  HOME PAGE MyModule.AdminHome FOR MyModule.Administrator
  LOGIN PAGE Administration.Login
  NOT FOUND PAGE MyModule.Custom404
  MENU (
    MENU ITEM 'Home' PAGE MyModule.Home_Web;
    MENU 'Admin' (
      MENU ITEM 'Users' PAGE Administration.Account_Overview;
    );
  );

Project Settings

StatementSyntaxNotes
Show settingsSHOW SETTINGS;Overview of all settings parts
Describe settingsDESCRIBE SETTINGS;Full MDL output (round-trippable)
Alter model settingsALTER SETTINGS MODEL Key = Value;AfterStartupMicroflow, HashAlgorithm, JavaVersion, etc.
Alter configurationALTER SETTINGS CONFIGURATION 'Name' Key = Value;DatabaseType, DatabaseUrl, HttpPortNumber, etc.
Alter constantALTER SETTINGS CONSTANT 'Name' VALUE 'val' IN CONFIGURATION 'cfg';Override constant per configuration
Alter languageALTER SETTINGS LANGUAGE Key = Value;DefaultLanguageCode
Alter workflowsALTER SETTINGS WORKFLOWS Key = Value;UserEntity, DefaultTaskParallelism

Business Events

StatementSyntaxNotes
Show servicesSHOW BUSINESS EVENTS;List all business event services
Show in moduleSHOW BUSINESS EVENTS IN Module;Filter by module
Describe serviceDESCRIBE BUSINESS EVENT SERVICE Module.Name;Full MDL output
Create serviceCREATE BUSINESS EVENT SERVICE Module.Name (...) { MESSAGE ... };See help topic for full syntax
Drop serviceDROP BUSINESS EVENT SERVICE Module.Name;Delete a service

Java Actions

StatementSyntaxNotes
Show Java actionsSHOW JAVA ACTIONS [IN Module];List all or filtered by module
Describe Java actionDESCRIBE JAVA ACTION Module.Name;Full MDL output with signature
Create Java actionCREATE JAVA ACTION Module.Name(params) RETURNS type AS $$ ... $$;Inline Java code
Create with type paramsCREATE JAVA ACTION Module.Name(EntityType: ENTITY <pEntity>, Obj: pEntity) ...;Generic type parameters
Create exposed action... EXPOSED AS 'Caption' IN 'Category' AS $$ ... $$;Toolbox-visible in Studio Pro
Drop Java actionDROP JAVA ACTION Module.Name;Delete a Java action
Call from microflow$Result = CALL JAVA ACTION Module.Name(Param = value);Inside BEGIN…END

Parameter Types: String, Integer, Long, Decimal, Boolean, DateTime, Module.Entity, List of Module.Entity, ENUM Module.EnumName, Enumeration(Module.EnumName), StringTemplate(Sql), StringTemplate(Oql), ENTITY <pEntity> (type parameter declaration), bare pEntity (type parameter reference).

Type Parameters allow generic entity handling. ENTITY <pEntity> declares the type parameter inline and becomes the entity type selector; bare pEntity parameters receive entity instances:

CREATE JAVA ACTION Module.Validate(
  EntityType: ENTITY <pEntity> NOT NULL,
  InputObject: pEntity NOT NULL
) RETURNS Boolean
EXPOSED AS 'Validate Entity' IN 'Validation'
AS $$
return InputObject != null;
$$;

Pages

MDL uses explicit property declarations for pages:

ElementSyntaxExample
Page properties(Key: value, ...)(Title: 'Edit', Layout: Atlas_Core.Atlas_Default)
Page variablesVariables: { $name: Type = 'expr' }Variables: { $show: Boolean = 'true' }
Widget nameRequired after typeTEXTBOX txtName (...)
Attribute bindingAttribute: AttrNameTEXTBOX txt (Label: 'Name', Attribute: Name)
Variable bindingDataSource: $VarDATAVIEW dv (DataSource: $Product) { ... }
Action bindingAction: TYPEACTIONBUTTON btn (Caption: 'Save', Action: SAVE_CHANGES)
Microflow actionAction: MICROFLOW Name(Param: val)Action: MICROFLOW Mod.ACT_Process(Order: $Order)
Database sourceDataSource: DATABASE EntityDATAGRID dg (DataSource: DATABASE Module.Entity)
Selection bindingDataSource: SELECTION widgetDATAVIEW dv (DataSource: SELECTION galleryList)
CSS classClass: 'classes'CONTAINER c (Class: 'card mx-spacing-top-large')
Inline styleStyle: 'css'CONTAINER c (Style: 'padding: 16px;')
Design propertiesDesignProperties: [...]CONTAINER c (DesignProperties: ['Spacing top': 'Large', 'Full width': ON])
Width (pixels)Width: integerIMAGE img (Width: 200)
Height (pixels)Height: integerIMAGE img (Height: 150)
Page sizePageSize: integerDATAGRID dg (PageSize: 25)
Pagination modePagination: modeDATAGRID dg (Pagination: virtualScrolling)
Paging positionPagingPosition: posDATAGRID dg (PagingPosition: both)
Paging buttonsShowPagingButtons: modeDATAGRID dg (ShowPagingButtons: auto)

DataGrid Column Properties:

PropertyValuesDefaultExample
Attributeattribute name(required)Attribute: Price
Captionstringattribute nameCaption: 'Unit Price'
Alignmentleft, center, rightleftAlignment: right
WrapTexttrue, falsefalseWrapText: true
Sortabletrue, falsetrue/falseSortable: false
Resizabletrue, falsetrueResizable: false
Draggabletrue, falsetrueDraggable: false
Hidableyes, hidden, noyesHidable: no
ColumnWidthautoFill, autoFit, manualautoFillColumnWidth: manual
Sizeinteger (px)1Size: 200
Visibleexpression stringtrueVisible: '$showColumn' (page variable, not $currentObject)
DynamicCellClassexpression string(empty)DynamicCellClass: 'if(...) then ... else ...'
Tooltiptext string(empty)Tooltip: 'Price in USD'

Page Example:

CREATE PAGE MyModule.Customer_Edit
(
  Params: { $Customer: MyModule.Customer },
  Title: 'Edit Customer',
  Layout: Atlas_Core.PopupLayout
)
{
  DATAVIEW dvCustomer (DataSource: $Customer) {
    TEXTBOX txtName (Label: 'Name', Attribute: Name)
    TEXTBOX txtEmail (Label: 'Email', Attribute: Email)
    COMBOBOX cbStatus (Label: 'Status', Attribute: Status)

    FOOTER footer1 {
      ACTIONBUTTON btnSave (Caption: 'Save', Action: SAVE_CHANGES, ButtonStyle: Primary)
      ACTIONBUTTON btnCancel (Caption: 'Cancel', Action: CANCEL_CHANGES)
    }
  }
}

Supported Widgets:

  • Layout: LAYOUTGRID, ROW, COLUMN, CONTAINER, CUSTOMCONTAINER
  • Input: TEXTBOX, TEXTAREA, CHECKBOX, RADIOBUTTONS, DATEPICKER, COMBOBOX
  • Display: DYNAMICTEXT, DATAGRID, GALLERY, LISTVIEW, IMAGE, STATICIMAGE, DYNAMICIMAGE
  • Actions: ACTIONBUTTON, LINKBUTTON, NAVIGATIONLIST
  • Structure: DATAVIEW, HEADER, FOOTER, CONTROLBAR, SNIPPETCALL

ALTER PAGE / ALTER SNIPPET

Modify an existing page or snippet’s widget tree in-place without full CREATE OR REPLACE. Works directly on the raw BSON tree, preserving unsupported widget types.

OperationSyntaxNotes
Set propertySET Caption = 'New' ON widgetNameSingle property on a widget
Set multipleSET (Caption = 'Save', ButtonStyle = Success) ON btnMultiple properties at once
Page-level setSET Title = 'New Title'No ON clause for page properties
Insert afterINSERT AFTER widgetName { widgets }Add widgets after target
Insert beforeINSERT BEFORE widgetName { widgets }Add widgets before target
Drop widgetsDROP WIDGET name1, name2Remove widgets by name
Replace widgetREPLACE widgetName WITH { widgets }Replace widget subtree
Pluggable propSET 'showLabel' = false ON cbStatusQuoted name for pluggable widgets
Add variableADD Variables $name: Type = 'expr'Add a page variable
Drop variableDROP Variables $nameRemove a page variable

Supported SET properties: Caption, Label, ButtonStyle, Class, Style, Editable, Visible, Name, Title (page-level), and quoted pluggable widget properties.

Example:

ALTER PAGE Module.EditPage {
  SET (Caption = 'Save & Close', ButtonStyle = Success) ON btnSave;
  DROP WIDGET txtUnused;
  INSERT AFTER txtEmail {
    TEXTBOX txtPhone (Label: 'Phone', Attribute: Phone)
  }
};

ALTER SNIPPET Module.NavMenu {
  SET Caption = 'Dashboard' ON btnHome
};

Tip: Run DESCRIBE PAGE Module.PageName first to see widget names.

External SQL Statements

Direct SQL query execution against external databases (PostgreSQL, Oracle, SQL Server). Credentials are isolated – DSN never appears in session output or logs.

StatementSyntaxNotes
ConnectSQL CONNECT <driver> '<dsn>' AS <alias>;Drivers: postgres, oracle, sqlserver
DisconnectSQL DISCONNECT <alias>;Closes connection
List connectionsSQL CONNECTIONS;Shows alias + driver only (no DSN)
Show tablesSQL <alias> SHOW TABLES;Lists user tables
Show viewsSQL <alias> SHOW VIEWS;Lists user views
Show functionsSQL <alias> SHOW FUNCTIONS;Lists functions and procedures
Describe tableSQL <alias> DESCRIBE <table>;Shows columns, types, nullability
QuerySQL <alias> <any-sql>;Raw SQL passthrough
ImportIMPORT FROM <alias> QUERY '<sql>' INTO Module.Entity MAP (...) [LINK (...)] [BATCH n] [LIMIT n];Insert external data into Mendix app DB
Generate connectorSQL <alias> GENERATE CONNECTOR INTO <module> [TABLES (...)] [VIEWS (...)] [EXEC];Generate Database Connector MDL from schema
-- Connect to PostgreSQL
SQL CONNECT postgres 'postgres://user:pass@localhost:5432/mydb' AS source;

-- Explore schema
SQL source SHOW TABLES;
SQL source DESCRIBE users;

-- Query data
SQL source SELECT * FROM users WHERE active = true LIMIT 10;

-- Import external data into Mendix app database
IMPORT FROM source QUERY 'SELECT name, email FROM employees'
  INTO HRModule.Employee
  MAP (name AS Name, email AS Email);

-- Import with association linking
IMPORT FROM source QUERY 'SELECT name, dept_name FROM employees'
  INTO HR.Employee
  MAP (name AS Name)
  LINK (dept_name TO Employee_Department ON Name);

-- Generate Database Connector from schema
SQL source GENERATE CONNECTOR INTO HRModule;
SQL source GENERATE CONNECTOR INTO HRModule TABLES (employees, departments) EXEC;

-- Manage connections
SQL CONNECTIONS;
SQL DISCONNECT source;

CLI subcommand: mxcli sql --driver postgres --dsn '...' "SELECT 1" (see mxcli syntax sql). Supported drivers: postgres (pg, postgresql), oracle (ora), sqlserver (mssql).

StatementSyntaxNotes
Refresh catalogREFRESH CATALOG;Rebuild basic metadata tables
Refresh with refsREFRESH CATALOG FULL;Include cross-references and source
Show catalog tablesSHOW CATALOG TABLES;List available queryable tables
Query catalogSELECT ... FROM CATALOG.<table> [WHERE ...];SQL against project metadata
Show callersSHOW CALLERS OF Module.Name;What calls this element
Show calleesSHOW CALLEES OF Module.Name;What this element calls
Show referencesSHOW REFERENCES OF Module.Name;All references to/from
Show impactSHOW IMPACT OF Module.Name;Impact analysis
Show contextSHOW CONTEXT OF Module.Name;Surrounding context
Full-text searchSEARCH '<keyword>';Search across all strings and source

Cross-reference commands require REFRESH CATALOG FULL to populate reference data.

Connection & Session

StatementSyntaxNotes
ConnectCONNECT LOCAL '/path/to/app.mpr';Open a Mendix project
DisconnectDISCONNECT;Close current project
StatusSTATUS;Show connection info
RefreshREFRESH;Reload project from disk
CommitCOMMIT [MESSAGE 'text'];Save changes to MPR
Set variableSET key = value;Session variable (e.g., output_format = 'json')
ExitEXIT;Close REPL session

CLI Commands

CommandSyntaxNotes
Interactive REPLmxcliInteractive MDL shell
Execute commandmxcli -p app.mpr -c "SHOW ENTITIES"Single command
Execute scriptmxcli exec script.mdl -p app.mprScript file
Check syntaxmxcli check script.mdlParse-only validation
Check referencesmxcli check script.mdl -p app.mpr --referencesWith reference validation
Lint projectmxcli lint -p app.mpr [--format json|sarif]14 built-in + 27 Starlark rules
Reportmxcli report -p app.mpr [--format markdown|json|html]Best practices report
Testmxcli test tests/ -p app.mpr.test.mdl / .test.md files
Diff scriptmxcli diff -p app.mpr changes.mdlCompare script vs project
Diff localmxcli diff-local -p app.mpr --ref HEADGit diff for MPR v2
OQLmxcli oql -p app.mpr "SELECT ..."Query running Mendix runtime
External SQLmxcli sql --driver postgres --dsn '...' "SELECT 1"Direct database query
Docker buildmxcli docker build -p app.mprBuild with PAD patching
Docker checkmxcli docker check -p app.mprValidate with mx check
Diagnosticsmxcli diag [--bundle]Session logs, version info
Init projectmxcli init -p app.mprCreate .claude/ folder with skills
LSP servermxcli lsp --stdioLanguage server for VS Code