| name | mps-console |
| description | Use when running or generating MPS Console code, or when writing `jetbrains.mps.lang.smodel.query` queries anywhere in MPS (intentions, behavior, actions, generator queries, plain BaseLanguage). Covers the console command languages (`jetbrains.mps.console.base` / `ideCommands` / `internalCommands` / `scripts`): `BLCommand` / `BLExpression`, the `#print*` / `#show` result printers, IDE commands (`#make` / `#clean` / `#removeGenSources` / `#reloadClasses` / `#stat` / `#showGenPlan` / `#showBrokenRefs`), `#exec` / `refactor` scripts. Covers the smodel query language: `#nodes` / `#references` / `#models` / `#modules` / `#instances` / `#usages`, the `with`-statement scope wrapper, scopes (`project` / `editable` / `global` / `visible` / `modules` / `models` / `custom`) and query parameters (`scope` / `exact` / `r/o+`). Also how to insert, read, recall, and run console commands with `mps_mcp_insert_console_command_from_json`, `mps_mcp_get_current_editor_root_node(source="console")`, `mps_mcp_get_console_history`, `mps_mcp_recall_console_command`, and `mps_mcp_run_console_command`. |
| type | reference |
MPS Console and the smodel query language
The MPS Console runs DSL code against the live models of the open project: query and mutate nodes, run find-usages, gather statistics, make/clean models, reload classes. Code is typed line-by-line, generated by the MPS generator, and executed in the IDE context. Most console-specific constructs start with # and completion (Ctrl+Space) inserts them.
The smodel query language (jetbrains.mps.lang.smodel.query) exposes the same queries (#nodes, #instances, #usages, …) for use in ordinary model code — intentions, behavior methods, actions, migration/refactoring scripts — wrapped in a with (<scope>) { … } statement. Reach for it whenever code needs to enumerate nodes/models/modules or find instances/usages across a scope.
Ways this skill gets used
- Type code in the Console tool window (Tools ▸ Console, or the Console tool window). One command per input. See
references/console-languages.md.
- Write
smodel.query queries inside model code (an intention, behavior method, generator query, script). Import jetbrains.mps.lang.smodel.query and wrap queries in with (<scope>) { … }. See references/smodel-query.md.
- Insert code into the Console from an agent via
mps_mcp_insert_console_command_from_json — builds a command from a JSON blueprint and drops it into the console input without executing it (the user reviews and runs it with Ctrl+Enter). See references/mcp-insertion.md.
- Read the current Console command from an agent via
mps_mcp_get_current_editor_root_node with source = "console" — returns the node-info envelope of the command currently in the console input (one an agent inserted, or the user typed). Feed its reference to mps_mcp_print_node for the JSON blueprint (format = "JSON") or the notational printout (format = "PLAIN TEXT" / "HTML"), or to mps_mcp_check_root_node_problems to see the problems MPS's model checker reports for it (way #8). The reference is only valid until the next console interaction (execute / clear / history navigation), so print it promptly and do not cache it.
- Browse the Console history from an agent via
mps_mcp_get_console_history — lists previously executed commands in order, each with a one-line preview, a history-entry reference, and an effectiveCommandReference. Pass the entry reference to recall; pass effectiveCommandReference to mps_mcp_print_node. Use includeResponses = true to also see the printed output. Same reference-validity caveat as #4.
- Recall a history command into the input via
mps_mcp_recall_console_command(historyNodeReference) — deep-copies a history entry (from #5) back into the input slot without executing it. Pass the history entry's reference, not its effectiveCommandReference. There is no MPS "recall" API to call directly; this mirrors what the Console's own up/down history navigation does (copy + insert).
- Run the current Console command from an agent via
mps_mcp_run_console_command — executes whatever command is currently in the input (placed there by #3 or #6, or typed by the user), exactly as Ctrl+Enter, and only when a command is present. It executes code with side effects. The response is not returned by the tool; read it afterwards via #5 (mps_mcp_get_console_history with includeResponses = true) or from the Console tool window, and note that long-running commands (make/generate) complete asynchronously.
- Check a Console command for problems from an agent via
mps_mcp_check_root_node_problems — pass the reference from way #4 (or an effectiveCommandReference from way #5) and it runs MPS's full checker set (structure, constraints, reference scopes, typesystem, and checking rules), surfacing the same errors/warnings the Console editor underlines and the Model Checker reports. Two caveats: (a) root-scoped — the tool checks the command's containingRoot, which for console code is the single ConsoleRoot holding the current input and the entire history, so results can include problems from earlier commands; with the default onlyNodesWithProblems = true you get a flat list of problem nodes, so match each one's rootName/subtree to the command you mean. (b) Same reference-validity window as #4 — resolve and check before the next console interaction.
A command is one of three shapes
The console input holds exactly one command (jetbrains.mps.console.base.structure.Command):
| Shape | Concept | What it is |
|---|
| BaseLanguage statements | BLCommand (alias {) — body: StatementList | a { … } block of imperative statements; the value of a trailing expression statement is printed |
| BaseLanguage expression | BLExpression — expression: Expression | one expression; if non-void its value is printed (as text / AST / interactive response) |
| Interpreted command | InterpretedCommand subtypes | non-generated commands: #stat, #showGenPlan, #showBrokenRefs, #reloadClasses, ? (help) |
Key fact that trips up blueprints: the query commands (#nodes, #instances, …), the IDE commands #make / #clean / #removeGenSources / #show / #callAction, and the printers #print / #printNode / #printNodeRef / #printSequence / #printText are all baseLanguage Expressions, not Commands. To use one as a standalone command you put it inside a BLExpression (or inside { … } statements). Only InterpretedCommand subtypes and #reloadClasses are commands in their own right.
Critical Directives
- Pick the scope deliberately. Without a scope, console queries run over all editable models of the current project; a
with statement defaults to editable models too, so model-changing code is safe. Scopes: project, editable, global, visible, modules(...), models(...), custom(<SearchScope>). See references/smodel-query.md.
scope parameter ≠ with scope. When you pass scope explicitly as a query parameter it is used as-is and keeps read-only models, so #nodes inside with(project) and #nodes<scope project> can return different results.
- No nested
with. A with statement may not contain another with.
- Lazy vs eager:
#nodes / #references / #models / #modules are lazy sequences (full iteration). #instances / #usages use the find-usages index — far faster than iterate-then-filter. Prefer #instances(C) over #nodes.ofConcept<C>().
exact parameter on #instances excludes instances of sub-concepts (#instances<exact>(C)).
- Never hand-edit the console's
.mps model. Use the editor or the MCP tool. The console lives in a temporary ConsoleModel_* model.
- Insertion and recall do not execute.
mps_mcp_insert_console_command_from_json and mps_mcp_recall_console_command only place a command in the input; by default leave it for the user to run and tell them it is waiting. To execute it yourself, call mps_mcp_run_console_command (way #7) — it runs code with side effects, so do it deliberately and report what it did.
Examples (surface syntax)
#models // all editable models in the project
#modules<global> // every module in the repository
#instances(ClassConcept) // fast: all ClassConcept instances in scope
#instances<exact>(BaseConcept) // exclude sub-concepts
#usages(aNode) // direct references to a node
#print 2 + 2 // smart-print a value
#printNode someNode // print a node copy
#show #instances(Issue) // open the result in the usages view
#make #models<modules myModule> // make selected models
#reloadClasses // reload generated classes
// migrate every TryStatement with a catch + long body to TryCatchStatement (from the MPS docs)
#instances(TryStatement).where({~it => it.catchClause.isNotEmpty; }).refactor({~node => if (node.body.statement.size > 5) { node.replace with new(TryCatchStatement); } })
Related Skills
mps-model-manipulation — the smodel / collections / closures operations (.where, .select, .ofConcept<C>, replace with new(C), :eq:) used in the bodies of console commands, with blocks, and refactor closures. The smodel query language layers on top of these.
mps-node-editing — the JSON blueprint format that mps_mcp_insert_console_command_from_json consumes (shared with mps_mcp_insert_root_node_from_json).
mps-aspect-intentions — a common host for with (…) { #instances(…)… } queries.
mps-baselanguage — host BaseLanguage statements/expressions that fill BLCommand / BLExpression.
mps-run-configurations — for running a main/test root node instead of console code.
Reference Index
- Open
references/console-languages.md for the full console command-language reference — every # command grouped by language (base, ideCommands, internalCommands, scripts), aliases, what each prints, scopes, paste-as-nodeRef, and #exec scripts.
- Open
references/smodel-query.md for the jetbrains.mps.lang.smodel.query language used in model code — the with statement, the six query expressions, scope parameters, the scope / exact / r/o+ query parameters, default-scope rules, and intention/behavior usage examples.
- Open
references/mcp-insertion.md for mps_mcp_insert_console_command_from_json — the two accepted JSON shapes, validated working blueprints (BLExpression + query, statement arrays, interpreted commands), concept FQNs and language UUIDs, the "wrap expressions in BLExpression" gotcha, and dryRun validation.