Skip to main content
Glama

simulate_input

Destructive

Simulate sequential key, mouse, click, action, text, and wait inputs in a running Godot project, then report per-action outcomes, UI changes, signal fires, and input-handler errors.

Instructions

Simulate sequential input in a running project and report what each action did. Action type: key, mouse_button, mouse_motion, click_element, action, text, wait. For key/mouse_button/action, omit pressed to tap (press+release); set it to hold or release. click_element resolves by node path/name (see get_ui_elements), not visible text. Returns: results[] per action with ok, timing, signals fired, the Control hit, UI changes (appeared/disappeared/changed), watch samples, and errors from input handlers (spawned sessions only). Invalid batches inject nothing; a runtime failure stops the batch and skips the rest.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
watchNoGodot NodePath:property strings sampled after every action and reported per result, e.g. "/root/Main/Player:position". Property subnames are allowed ("/root/Main/Player:position:x"). Read-only; an unresolvable path samples as null instead of failing the batch.
actionsYesArray of input actions to execute sequentially. Each object must have a "type" field.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultsNoOne entry per requested action, in order.
successNoFalse when an action failed and the remaining actions were skipped.
still_heldNoInputs this batch pressed and did not release, e.g. "key:W", "action:jump".

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed14 schema fields changedv3.8.0
    • addedInput schema / properties / actions / items / properties / frames
      Added value: +{
      +  "description": "[wait] Deterministic pause of N engine process frames, for stepping game logic rather than waiting on the clock. Exactly one of ms or frames is required. Max 600, budgeted at a 10fps floor, so a wait of several hundred frames may be cut off by your client before the server answers.",
      +  "type": "number"
      +}
    • addedInput schema / properties / actions / items / properties / hold_ms
      Added value: +{
      +  "description": "[key, mouse_button, action] Tap hold duration in milliseconds, overriding the default (one process frame plus one physics frame for key/action, zero gap for mouse_button). Use it for code polling is_action_pressed over real time. Rejected when pressed is also set. Max 10000.",
      +  "type": "number"
      +}
    • changedInput schema / properties / actions / items / properties / ms / description
      Previous value: -"[wait] Duration in milliseconds to pause before the next action (~16ms = one frame at 60fps)."New value: +"[wait] Real-time pause in milliseconds, for time-driven things such as cooldowns and animations (~16ms = one frame at 60fps). Exactly one of ms or frames is required. Uncapped, but a batch whose total wait approaches 60s may be cut off by your client before the server answers: split it across calls."
    • changedInput schema / properties / actions / items / properties / pressed / description
      Previous value: -"[key, mouse_button, action] Whether the input is pressed (true) or released (false). For mouse_button: omit to auto-click (press+release in one action); set explicitly only for hold/release. For key: defaults to true and does NOT auto-release - emit a second action with pressed:false to release."New value: +"[key, mouse_button, action] Omit to tap: the action presses, holds briefly, and releases by itself. Set true to press and hold across later actions (reported in still_held), false to release an earlier hold. Cannot be combined with hold_ms."
    • changedInput schema / properties / actions / items / properties / strength / description
      Previous value: -"[action] Action strength (0–1, default 1.0)"New value: +"[action] Action strength (0 to 1, default 1.0)"
    • addedInput schema / properties / actions / items / properties / text
      Added value: +{
      +  "description": "[text] String to type into whatever Control currently holds focus, expanded to one key press+release per character. Fails when nothing holds focus - click or focus the LineEdit first. Max 1000 characters.",
      +  "type": "string"
      +}
    • changedInput schema / properties / actions / items / properties / type / enum
      Previous value: -[
      -  "key",
      -  "mouse_button",
      -  "mouse_motion",
      -  "click_element",
      -  "action",
      -  "wait"
      -]New value: +[
      +  "key",
      +  "mouse_button",
      +  "mouse_motion",
      +  "click_element",
      +  "action",
      +  "text",
      +  "wait"
      +]
    • addedInput schema / properties / watch
      Added value: +{
      +  "description": "Godot NodePath:property strings sampled after every action and reported per result, e.g. \"/root/Main/Player:position\". Property subnames are allowed (\"/root/Main/Player:position:x\"). Read-only; an unresolvable path samples as null instead of failing the batch.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 16,
      +  "type": "array"
      +}
    • removedOutput schema / properties / actions_processed
      Removed value: -{
      -  "type": "number"
      -}
    • addedOutput schema / properties / results
      Added value: +{
      +  "description": "One entry per requested action, in order.",
      +  "items": {
      +    "properties": {
      +      "changes": {
      +        "properties": {
      +          "appeared": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "changed": {
      +            "items": {
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "disappeared": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "focus": {
      +            "type": "string"
      +          },
      +          "scene": {
      +            "type": "string"
      +          },
      +          "truncated": {
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "elapsed_ms": {
      +        "description": "Milliseconds since batch start.",
      +        "type": "number"
      +      },
      +      "error": {
      +        "type": "string"
      +      },
      +      "errors": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "focus": {
      +        "description": "Path of the focus owner after the action.",
      +        "type": "string"
      +      },
      +      "frame": {
      +        "description": "Process frames elapsed since batch start.",
      +        "type": "number"
      +      },
      +      "hit": {
      +        "description": "Path of the Control under the pointer after the action settled.",
      +        "type": "string"
      +      },
      +      "index": {
      +        "type": "number"
      +      },
      +      "ok": {
      +        "type": "boolean"
      +      },
      +      "position": {
      +        "properties": {
      +          "x": {
      +            "type": "number"
      +          },
      +          "y": {
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "pressed": {
      +        "description": "Whether the input action is still held after this entry.",
      +        "type": "boolean"
      +      },
      +      "signals": {
      +        "description": "Which of pressed, toggled, item_selected, text_submitted the target emitted within the settle frame. A signal emitted later (call_deferred, a tween, a timer) is not observed, so an absent entry means \"not within one frame\", not \"never\".",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "skipped": {
      +        "description": "Present when an earlier failure ended the batch before this action.",
      +        "type": "boolean"
      +      },
      +      "type": {
      +        "type": "string"
      +      },
      +      "value": {
      +        "description": "Resulting text of the focused text Control.",
      +        "type": "string"
      +      },
      +      "watch": {
      +        "additionalProperties": true,
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "index",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / still_held
      Added value: +{
      +  "description": "Inputs this batch pressed and did not release, e.g. \"key:W\", \"action:jump\".",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / success / description
      Added value: +"False when an action failed and the remaining actions were skipped."
    • removedOutput schema / properties / tip
      Removed value: -{
      -  "type": "string"
      -}
    • removedOutput schema / properties / warnings
      Removed value: -{
      -  "items": {
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
  2. Changed1 schema field changedv3.6.0
    • changedInput schema / properties / actions / items / properties / pressed / description
      Previous value: -"[key, mouse_button, action] Whether the input is pressed (true) or released (false). For mouse_button: omit to auto-click (press+release in one action); set explicitly only for hold/release. For key: defaults to true and does NOT auto-release — emit a second action with pressed:false to release."New value: +"[key, mouse_button, action] Whether the input is pressed (true) or released (false). For mouse_button: omit to auto-click (press+release in one action); set explicitly only for hold/release. For key: defaults to true and does NOT auto-release - emit a second action with pressed:false to release."
  3. Addedv3.1.1
  4. Removedv3.0.0
  5. Addedv1.0.0

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare destructiveHint=true. The description adds significant behavior beyond that: it explains that invalid batches inject nothing, that a runtime failure stops the batch and skips the rest, and it details the result structure (ok, timing, signals, Control hit, changes, watch samples, errors). This goes well beyond the annotation's simple hint and gives the agent a realistic picture of side effects and failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but organized: it leads with purpose, then lists action types, gives key behavioral notes, and closes with return and failure handling. It is long but every clause earns its place. Minor structural improvement would be bullet lists for the action specifics, but it's already front-loaded and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (two parameters, nested action objects, many conditional fields), the description covers the essential operational aspects: sequential execution, action types, return contents, failure behavior, and the get_ui_elements cross-reference for node resolution. It also mentions the watch sampling mechanism. It does not explicitly state that the project must already be running, but that is implied by 'running project' in the first sentence and by the tool's purpose. An output schema exists, so the return summary is a bonus rather than a necessity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description does not add much parameter-level meaning beyond what the schema already provides; it summarizes action types and repeats the 'omit pressed to tap' rule, but the schema itself already explains each parameter in detail. It adds no new semantic insight beyond the overview, so it stays at baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Simulate sequential input in a running project and report what each action did,' which states a specific verb (simulate), resource (running project), and outcome (report). It enumerates the supported action types, making it immediately distinct from sibling tools like run_script or run_project, and clarifies that it interacts with a running project rather than editing it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong guidance on parameter usage (e.g., 'omit `pressed` to tap', 'click_element resolves by node path/name (see get_ui_elements)'), and warns about long waits being cut off. However, it does not explicitly contrast itself with alternatives or state when it should be preferred over similar tools, leaving the when-to-use-vs-others partly implicit. It provides no exclusions or 'do not use when' guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.