JetBrains logo

Skill

mps-console

run MPS console queries

Covers Code Analysis

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` / `forEach` / `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`.

SKILL.md

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

  1. Type code in the Console tool window (Tools ▸ Console, or the Console tool window). One command per input. See references/console-languages.md.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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).
  7. 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.
  8. 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):

ShapeConceptWhat it is
BaseLanguage statementsBLCommand (alias {) — body: StatementLista { … } block of imperative statements; the value of a trailing expression statement is printed
BaseLanguage expressionBLExpressionexpression: Expressionone expression; if non-void its value is printed (as text / AST / interactive response)
Interpreted commandInterpretedCommand subtypesnon-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

  • This skill is the controlling workflow for Console tasks. Start from surface syntax first — choose the query (#instances, #usages, #nodes, …), filter and transform with smodel / collections / closures, then insert or run via the console MCP tools. Only fall back to low-level Java/MPS-OpenAPI approaches if the surface syntax route has genuinely failed.
  • 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)).
  • MetaAdapterFactory is a rabbit-hole warning for Console tasks. If you feel tempted to use MetaAdapterFactory, hex feature IDs, generated StructureAspectDescriptor code, or hand-built SConcept / SContainmentLink objects while solving a Console command, stop and reframe the solution in surface syntax instead: #instances(Concept), node.property, node.childRole, replace with new(Concept), .forEach, or .refactor. MetaAdapterFactory belongs to low-level/generated implementation details, not the first-line solution for MPS Console work.
  • 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.
  • Bulk node mutation: pick refactor vs forEach by whether you will run it. .refactor({~it => … }) (RefactorOperation) pops a modal confirmation dialog and applies nothing until a human approves it; .forEach({~it => … }) (collections VisitAllOperation) applies its closure immediately, in the console's own write command, with no dialog. So: when the user asks only to create / insert a command for them to run themselves (mps_mcp_insert_console_command_from_json and stop), prefer refactor — the dialog gives them a review-and-confirm step at the keyboard. When the user asks you to create and run it yourself (you will call mps_mcp_run_console_command), prefer forEachrefactor would return executed:true but stall on the dialog with no human present, leaving the model unchanged and the run a silent no-op.

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)
// `.forEach` applies immediately and headlessly; `.refactor` instead pops a confirmation dialog
#instances(TryStatement).where({~it => it.catchClause.isNotEmpty; }).forEach({~node => if (node.body.statement.size > 5) { node.replace with new(TryCatchStatement); } })
  • 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.

© 2026 YourAI.tools. Every skill from an identity-verified publisher.

Independent catalog. Not affiliated with, endorsed by, or sponsored by Anthropic or any listed publisher. All trademarks belong to their respective owners.