WARNING: Alpha-quality software. This project is in early stages and has been largely vibe-engineered with AI coding assistants. Expect bugs, missing features, and rough edges. mxcli can corrupt your Mendix project files — always work on a copy or use version control. Use at your own risk.
A command-line tool that enables AI coding assistants (Claude Code, Cursor, Continue.dev, Windsurf, Aider, and others) to read, understand, and modify Mendix application projects.
Mendix projects are stored in binary .mpr files that AI agents can't read directly. mxcli bridges this gap by providing:
- MDL (Mendix Definition Language) - A SQL-like syntax for querying and modifying Mendix models
- Multi-tool support - Works with Claude Code, Cursor, Continue.dev, Windsurf, Aider, and more
- Full-text search - Search across all strings, messages, and source definitions
- Code navigation - Find callers, callees, references, and impact analysis
- Catalog queries - SQL-based querying of project metadata
- Linting - Check projects for common issues
- Unix pipe support - Output formats designed for scripting and chaining
The recommended way to use mxcli is inside a Dev Container. This sandboxes the AI agent so it can only access your project files, preventing unintended changes to your system. mxcli init sets up a .devcontainer/ configuration automatically.
# Initialize a Mendix project for your AI assistant
mxcli init /path/to/my-mendix-project
# Or specify your tool(s)
mxcli init --tool cursor /path/to/my-mendix-project
mxcli init --tool claude --tool cursor /path/to/my-mendix-project
# This creates:
# AGENTS.md and .ai-context/ with universal skills
# .devcontainer/ for sandboxed development
# Tool-specific config files (.cursorrules, .continue/config.json, etc.)
# Open the project in VS Code / Cursor and reopen in Dev Container,
# then start your AI assistant:
claude # or use Cursor, Continue.dev, etc.| Tool | Config File | Description |
|---|---|---|
| Claude Code | .claude/, CLAUDE.md |
Full integration with skills and commands |
| Cursor | .cursorrules |
Compact MDL reference and command guide |
| Continue.dev | .continue/config.json |
Custom commands and slash commands |
| Windsurf | .windsurfrules |
Codeium's AI with MDL rules |
| Aider | .aider.conf.yml |
Terminal-based AI pair programming |
| Universal | AGENTS.md |
Works with all tools |
# List supported tools
mxcli init --list-tools
# Add tool to existing project
mxcli add-tool cursorDownload the latest release for your platform from the releases page, or build from source:
git clone https://github.com/mendixlabs/mxcli.git
cd mxcli
make build
# Binary is at ./bin/mxcli# List all modules
mxcli -p app.mpr -c "SHOW MODULES"
# List entities in a module
mxcli -p app.mpr -c "SHOW ENTITIES IN MyModule"
# Describe an entity, microflow, page, or workflow
mxcli describe -p app.mpr entity MyModule.Customer
mxcli describe -p app.mpr microflow MyModule.ProcessOrder
mxcli describe -p app.mpr page MyModule.CustomerOverview
mxcli describe -p app.mpr workflow MyModule.MyWorkflowSearch across validation messages, log messages, captions, labels, and MDL source:
# Search for validation-related content
mxcli search -p app.mpr "validation"
# Pipe-friendly output (type<TAB>name per line)
mxcli search -p app.mpr "error" -q --format names
# JSON output for processing with jq
mxcli search -p app.mpr "Customer" -q --format jsonPipe to describe:
# Describe the first matching microflow
mxcli search -p app.mpr "validation" -q --format names | head -1 | awk '{print $2}' | \
xargs mxcli describe -p app.mpr microflow
# Process all matches
mxcli search -p app.mpr "error" -q --format names > results.txt
while IFS=$'\t' read -r type name; do
mxcli describe -p app.mpr "$type" "$name"
done < results.txt# Find what calls a microflow
mxcli callers -p app.mpr MyModule.ProcessOrder
mxcli callers -p app.mpr MyModule.ProcessOrder --transitive
# Find what a microflow calls
mxcli callees -p app.mpr MyModule.ProcessOrder
# Find all references to an element
mxcli refs -p app.mpr MyModule.Customer
# Analyze impact of changing an element
mxcli impact -p app.mpr MyModule.Customer
# Assemble context for understanding code
mxcli context -p app.mpr MyModule.ProcessOrder --depth 3EXPERIMENTAL: These commands are an untested proof-of-concept. Always use
DRY RUNfirst and backup your project before applying changes.
Find and update widget properties across pages and snippets:
# Discover widgets by type
mxcli -p app.mpr -c "SHOW WIDGETS WHERE WidgetType LIKE '%combobox%'"
# Filter by module
mxcli -p app.mpr -c "SHOW WIDGETS IN MyModule"
# Preview changes (dry run)
mxcli -p app.mpr -c "UPDATE WIDGETS SET 'showLabel' = false WHERE WidgetType LIKE '%DataGrid%' DRY RUN"
# Apply changes
mxcli -p app.mpr -c "UPDATE WIDGETS SET 'showLabel' = false, 'labelWidth' = 4 WHERE WidgetType LIKE '%combobox%' IN MyModule"Requires REFRESH CATALOG FULL to populate the widgets table.
SQL-based querying of project metadata:
# Find microflows with many activities
mxcli -p app.mpr -c "SELECT Name, ActivityCount FROM CATALOG.MICROFLOWS WHERE ActivityCount > 10 ORDER BY ActivityCount DESC"
# Find all entity usages
mxcli -p app.mpr -c "REFRESH CATALOG FULL; SELECT SourceName, RefKind, TargetName FROM CATALOG.REFS WHERE TargetName = 'MyModule.Customer'"
# Search strings table directly
mxcli -p app.mpr -c "SELECT * FROM CATALOG.STRINGS WHERE strings MATCH 'error' LIMIT 10"Available tables: MODULES, ENTITIES, MICROFLOWS, NANOFLOWS, PAGES, SNIPPETS, ENUMERATIONS, WORKFLOWS, ACTIVITIES, WIDGETS, REFS, PERMISSIONS, STRINGS, SOURCE
# Lint a project
mxcli lint -p app.mpr
# SARIF output for CI/GitHub integration
mxcli lint -p app.mpr --format sarif > results.sarif
# List available rules
mxcli lint -p app.mpr --list-rules
# Exclude modules
mxcli lint -p app.mpr --exclude System --exclude Administration14 built-in Go rules (MDL001-MDL007, SEC001-SEC003, CONV011-CONV014) plus 27 bundled Starlark rules covering security (SEC004-SEC009), architecture (ARCH001-003), quality (QUAL001-004), design (DESIGN001), and Mendix best practice conventions (CONV001-CONV010, CONV015-CONV017). Custom .star rules in .claude/lint-rules/ are loaded automatically.
# Generate a scored report (Markdown)
mxcli report -p app.mpr
# HTML report
mxcli report -p app.mpr --format html --output report.html
# JSON report for CI
mxcli report -p app.mpr --format jsonThe report evaluates the project across 6 categories (Security, Quality, Architecture, Performance, Naming, Design) with a 0-100 score per category and overall.
Test microflows using MDL syntax with javadoc-style annotations:
# Run tests
mxcli test tests/microflows.test.mdl -p app.mpr
# List tests without executing
mxcli test tests/ --list
# JUnit XML output for CI
mxcli test tests/ -p app.mpr --junit results.xmlTests use @test and @expect annotations in .test.mdl or .test.md files. See mxcli help test for full syntax.
# Execute MDL commands
mxcli -p app.mpr -c "CREATE ENTITY MyModule.Product (Name: String(200) NOT NULL, Price: Decimal)"
# Execute an MDL script file
mxcli -p app.mpr -c "EXECUTE SCRIPT 'setup.mdl'"
# Check MDL syntax before executing
mxcli check script.mdl
# Check syntax and validate references
mxcli check script.mdl -p app.mpr --references
# Preview changes (diff against current state)
mxcli diff -p app.mpr changes.mdlMDL (Mendix Definition Language) is a SQL-like syntax for working with Mendix models:
-- Show project structure
SHOW MODULES;
SHOW ENTITIES IN MyModule;
DESCRIBE ENTITY MyModule.Customer;
DESCRIBE MICROFLOW MyModule.ProcessOrder;
DESCRIBE PAGE MyModule.CustomerOverview;
-- Create entities
CREATE ENTITY MyModule.Product (
Name: String(200) NOT NULL,
Price: Decimal(10,2),
IsActive: Boolean DEFAULT true
);
-- Create associations
CREATE ASSOCIATION MyModule.Order_Product
FROM MyModule.Order TO MyModule.Product
TYPE ReferenceSet;
-- Create pages
CREATE PAGE MyModule.Product_Edit
(
Params: { $Product: MyModule.Product },
Title: 'Edit Product',
Layout: Atlas_Core.PopupLayout
)
{
DATAVIEW dvProduct (DataSource: $Product) {
TEXTBOX txtName (Label: 'Name', Attribute: Name)
TEXTBOX txtPrice (Label: 'Price', Attribute: Price)
CHECKBOX cbActive (Label: 'Active', Attribute: IsActive)
FOOTER footer1 {
ACTIONBUTTON btnSave (Caption: 'Save', Action: SAVE_CHANGES, ButtonStyle: Primary)
ACTIONBUTTON btnCancel (Caption: 'Cancel', Action: CANCEL_CHANGES)
}
}
}
-- Security management
CREATE MODULE ROLE MyModule.Admin DESCRIPTION 'Full access';
CREATE MODULE ROLE MyModule.Viewer DESCRIPTION 'Read-only';
GRANT EXECUTE ON MICROFLOW MyModule.ProcessOrder TO MyModule.Admin;
GRANT VIEW ON PAGE MyModule.Product_Edit TO MyModule.Admin, MyModule.Viewer;
GRANT MyModule.Admin ON MyModule.Product (CREATE, DELETE, READ *, WRITE *);
GRANT MyModule.Viewer ON MyModule.Product (READ *);
CREATE USER ROLE AppAdmin (MyModule.Admin) MANAGE ALL ROLES;
ALTER PROJECT SECURITY LEVEL PRODUCTION;
SHOW SECURITY MATRIX IN MyModule;
-- Search
SEARCH 'validation';
-- Code navigation
SHOW CALLERS OF MyModule.ProcessOrder TRANSITIVE;
SHOW REFERENCES TO MyModule.Customer;
SHOW IMPACT OF MyModule.Customer;
SHOW CONTEXT OF MyModule.ProcessOrder DEPTH 3;
-- Widget discovery and bulk updates
SHOW WIDGETS WHERE WidgetType LIKE '%combobox%';
UPDATE WIDGETS SET 'showLabel' = false WHERE WidgetType LIKE '%DataGrid%' DRY RUN;Run mxcli syntax for MDL syntax reference, or mxcli syntax <topic> for specific topics:
mxcli syntax keywords- Reserved keywordsmxcli syntax entity- Entity creation syntaxmxcli syntax microflow- Microflow creation syntaxmxcli syntax page- Page creation syntaxmxcli syntax search- Full-text search syntax
The mxcli init command sets up a Mendix project for AI-assisted development:
# Default: Claude Code + universal docs
mxcli init /path/to/my-mendix-project
# Specify tool(s)
mxcli init --tool cursor /path/to/my-mendix-project
mxcli init --tool claude --tool cursor /path/to/my-mendix-project
# All tools
mxcli init --all-tools /path/to/my-mendix-project
# Add tool to existing project
mxcli add-tool cursorUniversal (all tools):
AGENTS.md- Comprehensive guide for AI assistants.ai-context/skills/- MDL pattern guides (write-microflows.md, create-page.md, etc.).ai-context/examples/- Example MDL scripts
Tool-Specific:
- Claude Code:
.claude/settings.json,CLAUDE.md, commands, lint-rules, skills - Cursor:
.cursorrules- Compact MDL reference - Continue.dev:
.continue/config.json- Custom commands and slash commands - Windsurf:
.windsurfrules- MDL rules for Codeium - Aider:
.aider.conf.yml- YAML config for Aider
VS Code Extension (auto-installed with Claude):
- Syntax highlighting and diagnostics
- Hover and go-to-definition
- Code completion
- Context menu commands
mxcli init generates a .devcontainer/ configuration that provides a sandboxed development environment. This is the recommended way to run AI coding agents — it limits their access to just the project files.
What's installed in the dev container:
| Component | Purpose |
|---|---|
| mxcli | Mendix CLI for AI-assisted development (copied into project) |
| MxBuild / mx | Mendix project validation and building (~/.mxcli/mxbuild/) |
| JDK 21 (Adoptium) | Required by MxBuild |
| Docker-in-Docker | Running Mendix apps locally with mxcli docker |
| Node.js | Playwright testing support |
| PostgreSQL client | Database connectivity |
| Claude Code | AI coding assistant (auto-installed on container creation) |
Key paths inside the dev container:
~/.mxcli/mxbuild/{version}/modeler/mx # mx check / mx build
~/.mxcli/runtime/{version}/ # Mendix runtime (auto-downloaded)
./mxcli # Project-local mxcli binary
MxBuild is auto-downloaded on first use (via mxcli setup mxbuild -p app.mpr or mxcli docker build). To validate a project:
# Auto-download mxbuild and check project
mxcli setup mxbuild -p app.mpr
~/.mxcli/mxbuild/*/modeler/mx check app.mpr
# Or use the integrated command
mxcli docker check -p app.mprAfter initialization, open the project in VS Code or Cursor and reopen in Dev Container, then start your AI assistant:
claude # Claude Code
# or use Cursor, Continue.dev, Windsurf, etc.The AI assistant will have access to:
- MDL command reference in
AGENTS.md - Pattern guides in
.ai-context/skills/ - Tool-specific configuration
- Full project context via
mxclicommands
The MDL extension for VS Code provides a rich editing experience for .mdl files:
- Syntax highlighting and parse diagnostics as you type
- Semantic diagnostics on save (validates references against the project)
- Code completion with context-aware keyword and snippet suggestions
- Hover over
Module.Namereferences to see their MDL definition - Go-to-definition (Ctrl+click) to open element source as a virtual document
- Document outline and folding for MDL statements and blocks
- Context menu commands: Run File, Run Selection, Check File
The extension is automatically installed by mxcli init. To install manually:
make vscode-install
# or: code --install-extension vscode-mdl/vscode-mdl-*.vsixSettings:
mdl.mxcliPath- Path to the mxcli executable (default:mxcli)mdl.mprPath- Path to.mprfile (auto-discovered if empty)
The source_tree tool provides a visual overview of the codebase, showing file sizes, dependency tiers, and optional quality metrics:
# Basic source tree (file sizes + dependency depth)
go run ./cmd/source_tree
# With function metrics (count, longest function per file)
go run ./cmd/source_tree --fn
# With intra-file duplication detection
go run ./cmd/source_tree --dup
# With churn (commit frequency per file)
go run ./cmd/source_tree --churn
# All metrics at once
go run ./cmd/source_tree --all
# With test coverage (runs tests first if no coverage.out exists)
go run ./cmd/source_tree --coverOutput is color-coded by severity (green/yellow/orange/red) for each metric, making it easy to spot files that need attention.
# Prerequisites: Go 1.24+, Make
# Build
make build
# Run tests
make test
# Build release binaries for all platforms
make release
# Regenerate parser (requires ANTLR4)
make grammar- Mendix versions: Studio Pro 8.x, 9.x, 10.x, 11.x
- MPR formats: Both v1 and v2 (with mprcontents folder)
- Platforms: Linux, macOS, Windows (amd64 and arm64)
mxcli is built on a Go library for reading and modifying Mendix projects. If you want to use the library directly:
import "github.com/mendixlabs/mxcli"
// Read a project
reader, _ := modelsdk.Open("/path/to/app.mpr")
modules, _ := reader.ListModules()
dm, _ := reader.GetDomainModel(modules[0].ID)
// Write to a project
writer, _ := modelsdk.OpenForWriting("/path/to/app.mpr")
entity := modelsdk.NewEntity("Customer")
writer.CreateEntity(dm.ID, entity)See docs/GO_LIBRARY.md for full API documentation.
Apache License 2.0 - See LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.