> ## Documentation Index
> Fetch the complete documentation index at: https://docs.summerengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Operations: engine

> The open project in Summer Engine and the running game: scenes, nodes, scripts, play, input and screenshots. For each operation: what it does, whether it asks you first, its inputs and an example call.

The open project in Summer Engine and the running game: scenes, nodes, scripts, play, input and screenshots. 85 operations. How to call them, and what the answers mean: [Operations reference](/mcp/operations).

<Note>
  Generated from the `summer-engine` npm package `4.2.0`: its public operation catalog (`registry/operations/public-catalog.json`) and its engine and local operations. If something here is wrong, the operation's definition is wrong.
</Note>

| Operation | What it does | Asks you first |
| - | - | - |
| [`engine.add_node`](#add_node) | Add one node of any type to the scene at scenePath (it need not be the open tab) and save it. | Not by default |
| [`engine.align_distribute_3d`](#align_distribute_3d) | Align 2 to 16 3D nodes on one world axis (min, center, max) or space them equally (centers or gaps) from their visible bounds, then save the scene. | Not by default |
| [`engine.attach_to_surface`](#attach_to_surface) | Turn a piece so its measured back faces a wall, ceiling or floor found by a ray, keep it upright and seat it at a standoff: pipes, lamps, signs. | Not by default |
| [`engine.batch`](#batch) | Send a list of raw engine ops (AddNode, SetProp, RunVerification...) in one call: one undo step unless an op must travel alone, and one save at the end. | Not by default |
| [`engine.capture_gameplay`](#capture_gameplay) | Capture real gameplay frames (HUD included) from a hidden game window, no editor needed; game flags and player steps get past the title screen. | Never |
| [`engine.clear_console`](#clear_console) | Clear the editor's Output panel, for a clean slate before the game runs. | Not by default |
| [`engine.connect_ports`](#connect_ports) | Move and turn one piece so its port (a Marker3D, or an open pipe end such as +Y) meets another piece's port: pipe to pipe, duct to duct. | Not by default |
| [`engine.connect_signal`](#connect_signal) | Connect a signal of one node to a method of another so the saved scene keeps it, verified from the saved .tscn. | Not by default |
| [`engine.create_debug_report`](#create_debug_report) | Write a support-ready Markdown report: doctor checks, engine health, diagnostics, console and debugger output, and a hand-off prompt. | Not by default |
| [`engine.create_scene`](#create_scene) | Create a new, minimal .tscn file with the root type you name. | Not by default |
| [`engine.debug_views`](#debug_views) | Render one pose as a grid of debug views next to the beauty pass: lighting only, albedo, world normals, overdraw and wireframe. | Never |
| [`engine.delete_camera_bookmark`](#delete_camera_bookmark) | Delete one saved camera viewpoint by name. | Not by default |
| [`engine.enable_plugin`](#enable_plugin) | Enable an editor plugin in res\://addons/\<name>/ and return the real result: enabled with its autoloads, or why it failed. | Not by default |
| [`engine.export_game`](#export_game) | Export the game headless as the file the Summer Games store takes: a bundle for iPhone, Android, macOS and Windows, a web build or a desktop download. | Not by default |
| [`engine.export_templates`](#export_templates) | List or install Summer Engine export templates (web, macOS, Windows) from Summer's CDN, each sha256-checked. | Not by default |
| [`engine.fabricate_3d`](#fabricate_3d) | Make a mesh with a bpy script in the person's own Blender (4.2 or newer, headless), import the .glb into the project and optionally place it. | Not by default |
| [`engine.frame_nodes`](#frame_nodes) | Fit a camera to the world bounds of some nodes and render them with the scene's real environment and lights; bookmark\_name also saves the pose. | Not by default |
| [`engine.frame_shot`](#frame_shot) | Find, score and save camera poses for a shot type (establishing, eye level, low angle, detail, corridor), tested against the real geometry. | Not by default |
| [`engine.game_control`](#game_control) | Pause or resume the RUNNING game, step exactly N frames, set the time scale, or list the live game instances. | Not by default |
| [`engine.game_input`](#game_input) | Drive the RUNNING game's input: a script of timed actions, keys and clicks, or record real input and replay it on a seeded instance. | Not by default |
| [`engine.game_probe`](#game_probe) | Read state and pixels of one frame of the RUNNING game together: the live tree, property values and a screenshot stamped with the same frame numbers. | Never |
| [`engine.get_console`](#get_console) | Read recent editor Output messages, collapsed and filtered (errors and warnings by default; errors\_only false for print output). | Never |
| [`engine.get_debugger_errors`](#get_debugger_errors) | Read the played game's runtime errors from the debugger (null references, missing nodes, physics errors), collapsed, with call stacks on request. | Never |
| [`engine.get_debugger_warnings`](#get_debugger_warnings) | Read the played game's runtime warnings from the debugger, with file, line and call stack. | Never |
| [`engine.get_diagnostics`](#get_diagnostics) | Read the editor console, the runtime debugger and script errors together, with complete counts and errors first. | Never |
| [`engine.get_project_context`](#get_project_context) | Bind this session to the project open in Summer Engine and read it: project, current and main scene, engine health, project memory and warnings. | Never |
| [`engine.get_runtime_tree`](#get_runtime_tree) | Read the node tree of the RUNNING game: spawned enemies, autoloads and pooled nodes that editor reads never show. | Never |
| [`engine.get_scene_tree`](#get_scene_tree) | Read the node tree of a scene: names, types and paths. | Never |
| [`engine.get_script_errors`](#get_script_errors) | Check one GDScript file for parse and compile errors without running the game: line, message and severity of each. | Never |
| [`engine.grep`](#grep) | Search project files with a regular expression: file, line and text of each match, with optional context lines and a result cap. | Never |
| [`engine.import_asset`](#import_asset) | Search the Summer asset library, import the best match into the project and, for a 3D model, add it to a scene. | Not by default |
| [`engine.import_asset_by_id`](#import_asset_by_id) | Import one Summer asset by its id (from a search, the person's assets or a generation) into the project; a 3D model can go straight into the scene at scenePath. | Not by default |
| [`engine.import_from_url`](#import_from_url) | Download one file (model, texture, audio) from a URL into the project and run the import, so it is ready to use. | Not by default |
| [`engine.import_from_url_batch`](#import_from_url_batch) | Download several files from URLs into the project in one call, with one import scan at the end. | Not by default |
| [`engine.import_hdri`](#import_hdri) | Find a CC0 HDRI sky on Poly Haven (or take an exact id) and import it into res\://sky/ for environment light. | Not by default |
| [`engine.input_map_bind`](#input_map_bind) | Create an input action when it is missing and bind keys or mouse buttons to it, for example jump to Space. | Not by default |
| [`engine.inspect_asset`](#inspect_asset) | Measure a 3D asset file without placing it: bounds, origin, meshes, largest flat faces, open pipe ends, Marker3D anchors and collision shapes. | Never |
| [`engine.inspect_node`](#inspect_node) | Read one node of the open scene: every editable property with its value and type, or only the fields you name (transform, global\_transform, scene\_file\_path, aabb). | Never |
| [`engine.inspect_resource`](#inspect_resource) | Read a resource file (a mesh's bounds and surfaces, a scene's nodes, any resource's non-default properties) or a resource a node holds (nodePath and property). | Never |
| [`engine.inspect_runtime_node`](#inspect_runtime_node) | Read the live properties of one node in the RUNNING game (transform, visibility, physics state...) without stopping it. | Never |
| [`engine.instantiate_scene`](#instantiate_scene) | Add an existing .tscn, .glb or .gltf as a child node in the scene at scenePath, placed in the same call (position, rotation\_degrees, scale or transform). | Not by default |
| [`engine.invoke_ui_action`](#invoke_ui_action) | Run one named editor action exactly as its menu item or shortcut would: open Project Settings, switch the main screen, toggle a panel. | Not by default |
| [`engine.is_running`](#is_running) | Check whether the game is running, and which scene it runs. | Never |
| [`engine.list_camera_bookmarks`](#list_camera_bookmarks) | List the camera viewpoints saved in this project: names, poses and dates. | Never |
| [`engine.list_ui_actions`](#list_ui_actions) | List the editor's named actions (menu items and shortcuts) with labels and shortcuts, filtered by text. | Never |
| [`engine.measure`](#measure) | Measure the gap or overlap on each axis between two placed nodes, or check that one face of many nodes lies on one plane. | Never |
| [`engine.navigation_probe`](#navigation_probe) | Check whether two world points are connected on the scene's navigation map: readiness, snapped end points, route length and route points. | Never |
| [`engine.open_main_scene`](#open_main_scene) | Open the project's main scene (from project settings) in the editor, instead of guessing a scene file name. | Not by default |
| [`engine.open_scene`](#open_scene) | Open a scene file in the editor and show its tab. | Not by default |
| [`engine.place_adjacent`](#place_adjacent) | Move one node so its bounds face sits against another node's, lining up the other axes: modules edge to edge, storeys stacked. | Not by default |
| [`engine.play`](#play) | Start the game quietly (the editor keeps its tab and focus): the main scene or a given one, embedded or as a hidden offscreen instance, with an optional seed and fixed frame rate, or a local multiplayer session… | Not by default |
| [`engine.project_setting`](#project_setting) | Set one project.godot setting, such as application/run/main\_scene, the window size, the renderer or the default gravity. | Not by default |
| [`engine.raycast`](#raycast) | Cast one ray from any point in a scene: the node it hits, the point and the normal. | Never |
| [`engine.read_file`](#read_file) | Read a text file of the project (res\://), a line or byte window of it, or parts of a .json, with the whole file's sha256. | Never |
| [`engine.recent_events`](#recent_events) | Read the newest engine events (saves, plays, op results, script errors, imports) at once, and next\_seq, the cursor to pass to engine.wait\_for\_event. | Never |
| [`engine.remove_node`](#remove_node) | Remove a node and all its children from the scene at scenePath and save it. | Not by default |
| [`engine.repeat_along`](#repeat_along) | Place copies of one scene along a line in one call: fence posts, clamps, a row of windows (at most 64). | Not by default |
| [`engine.replace_node`](#replace_node) | Replace a node with another scene or node type, keeping its parent, index, name, transform and children; the saved file is read back to prove it. | Not by default |
| [`engine.replace_text`](#replace_text) | Replace text in an existing project file. | Not by default |
| [`engine.run_editor_script`](#run_editor_script) | Run an EditorScript func \_run() in a fresh headless editor against the project on disk: batch and project-wide jobs such as re-saving many scenes. | Not by default |
| [`engine.run_script`](#run_script) | Run one GDScript func run(ctx) in the live editor on the scene at scenePath: the way to make 3 or more scene edits, loops, grids and procedural meshes. | Not by default |
| [`engine.runtime_animate`](#runtime_animate) | Read and drive animation in the RUNNING game: AnimationPlayer clips, AnimationTree states and Skeleton3D bone poses. | Not by default |
| [`engine.runtime_call`](#runtime_call) | Call one method on a node in the RUNNING game and return its result, to trigger gameplay code directly. | Not by default |
| [`engine.runtime_set`](#runtime_set) | Set one property on a node in the RUNNING game (the live object, never the scene file) and read back whether it applied: move the player, set health, flip a flag. | Not by default |
| [`engine.runtime_spawn`](#runtime_spawn) | Spawn a scene into the RUNNING game (action spawn) or free a live node (action free) to set up a test. | Not by default |
| [`engine.save_camera_bookmark`](#save_camera_bookmark) | Save a named camera viewpoint in the project (res\://.summer/camera\_bookmarks.json): position and look\_at as Vector3 literals, or neither to take the editor's 3D camera. | Not by default |
| [`engine.save_scene`](#save_scene) | Save the scene at scenePath, or save it under a new path. | Not by default |
| [`engine.scene_audit`](#scene_audit) | Check a saved 3D scene for visual and placement problems: holes, exposed edges, floor gaps, floating or sunken props, overlaps, z-fighting, light limits. | Never |
| [`engine.screenshot`](#screenshot) | Return a frame as an image you see: the editor viewport, an offscreen render of a scene (preset, camera, bookmark or free pose, numbered marks) or the running game. | Never |
| [`engine.select_node`](#select_node) | Select a node in the editor's scene tree and show it in the inspector, so the person sees it. | Not by default |
| [`engine.set_prop`](#set_prop) | Set one property of a node in the scene at scenePath and save it. | Not by default |
| [`engine.set_resource_property`](#set_resource_property) | Set a property inside a resource a node holds, such as a collision shape's size or a material's albedo\_color, and save the scene. | Not by default |
| [`engine.shot_sheet`](#shot_sheet) | Render several bookmarks or poses into one labelled grid with real lighting, and compare each bookmark with its last render (difference map). | Never |
| [`engine.snap_to_surface`](#snap_to_surface) | Move one 3D node along a ray until it sits at the given gap on the first surface (floor, ramp, shelf, table), then save the scene. | Not by default |
| [`engine.snapshot_diff`](#snapshot_diff) | Compare two scene snapshots: added, removed and changed nodes and count changes. | Never |
| [`engine.starcast`](#starcast) | Read the clearance around one 3D node in 26 directions: what blocks each side and how far, contact, grounding and nearby objects. | Never |
| [`engine.stop`](#stop) | Stop the running game, or one offscreen instance by name. | Not by default |
| [`engine.test_placement`](#test_placement) | Test one 3D node at a candidate world position and rotation without moving it: overlaps, grounded state and the gap to the floor. | Never |
| [`engine.ui_activate`](#ui_activate) | Use one editor control by its tree path (press, toggle, focus, select a tab, type text, set a value) or dismiss a dialog; the control's state is read back. | Not by default |
| [`engine.ui_screenshot`](#ui_screenshot) | Return an image of the editor window, or of one dock, dialog or control: the last resort to look at the UI, never to pick click points. | Never |
| [`engine.ui_tree`](#ui_tree) | Read the live editor UI as a tree (controls, paths, text, state), or every visible dialog and whether one blocks input. | Never |
| [`engine.wait_for_event`](#wait_for_event) | Wait for an engine event (game started, op applied or failed, script error, scene saved) instead of sleeping; it says so honestly at the timeout. | Never |
| [`engine.world_snapshot`](#world_snapshot) | Take a structured snapshot of the edited scene: node paths, transforms, world bounds, fingerprints and counts, filtered by subtree, class or field. | Never |
| [`engine.write_file`](#write_file) | Create a text file (create\_only true) or overwrite one (expected\_sha256 from engine.read\_file); exactly one guard is required, so a stale write fails. | Not by default |
| [`engine.zoom`](#zoom) | Render a close-up of part of a frame (a region, or mark N of a marks render) at full resolution: real detail, seams and gaps, not enlarged pixels. | Never |

## Value formats

Engine properties such as `position`, `rotation_degrees` and `mesh` take engine string syntax, not JSON objects.

| Type | Format | Example |
| - | - | - |
| Vector3 | `"Vector3(x, y, z)"` | `"Vector3(0, 10, 0)"` |
| Vector2 | `"Vector2(x, y)"` | `"Vector2(100, 200)"` |
| Color | `"Color(r, g, b, a)"`, 0 to 1 | `"Color(1, 0.5, 0, 1)"` |
| Transform3D | basis and origin | `"Transform3D(1,0,0, 0,1,0, 0,0,1, 0,5,0)"` |
| Resource | class name, created for you | `"BoxMesh"`, `"StandardMaterial3D"` |
| Number, boolean, string | plain JSON | `1.5`, `true`, `"hello"` |

Node paths start with `./` from the scene root: `./World/Player` is the `Player` child of `World`. Every scene change names its scene with `scenePath`, such as `res://main.tscn`; the scene does not need to be the open editor tab. Three or more scene edits: one `summer_run_script` with `scenePath`.

***

### add\_node

`engine.add_node`: **Add a node**

Add one node of any type to the scene at scenePath (it need not be the open tab) and save it. For 3 or more edits, write one engine.run\_script instead. Next: engine.set\_prop.

| | |
| - | - |
| **MCP** | `summer_add_node` in the npm MCP |
| **CLI** | `summer engine add-node` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_add_node` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene path, e.g. 'res\://main.tscn' |
| `parent` | string | Yes | Parent node path, e.g. `./World` or `./World/Enemies` |
| `type` | string | Yes | Summer Engine node type, e.g. 'MeshInstance3D', 'CharacterBody3D' |
| `name` | string | Yes | Name for the new node, e.g. 'Player', 'MainCamera' |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene path, e.g. 'res://main.tscn'"
      },
      "parent": {
        "type": "string",
        "description": "Parent node path, e.g. './World' or './World/Enemies'"
      },
      "type": {
        "type": "string",
        "description": "Summer Engine node type, e.g. 'MeshInstance3D', 'CharacterBody3D'"
      },
      "name": {
        "type": "string",
        "description": "Name for the new node, e.g. 'Player', 'MainCamera'"
      }
    },
    "required": [
      "scenePath",
      "parent",
      "type",
      "name"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Add a node

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_add_node",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine add-node
  ```
</CodeGroup>

***

### align\_distribute\_3d

`engine.align_distribute_3d`: **Align or space 3D nodes**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Align 2 to 16 3D nodes on one world axis (min, center, max) or space them equally (centers or gaps) from their visible bounds, then save the scene. One undo step.

| | |
| - | - |
| **MCP** | `summer_align_distribute_3d` in the npm MCP |
| **CLI** | `summer engine align-distribute-3d` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_align_distribute_3d` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact target scene, e.g. 'res\://levels/market.tscn'. Length 1 to 512. |
| `subjectPaths` | string\[] | Yes | Two to sixteen exact Node3D paths in the order to align or distribute. Items 2 to 16. |
| `axis` | number\[] | Yes | Finite, non-zero world axis \[x,y,z]; normalization is automatic. Items 3 to 3. |
| `mode` | "align\_min" \| "align\_center" \| "align\_max" \| "distribute\_centers" \| "distribute\_gaps" | Yes | Alignment anchor or equal-spacing policy. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact target scene, e.g. 'res://levels/market.tscn'."
      },
      "subjectPaths": {
        "type": "array",
        "items": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256
        },
        "minItems": 2,
        "maxItems": 16,
        "description": "Two to sixteen exact Node3D paths in the order to align or distribute."
      },
      "axis": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 3,
        "maxItems": 3,
        "description": "Finite, non-zero world axis [x,y,z]; normalization is automatic."
      },
      "mode": {
        "type": "string",
        "enum": [
          "align_min",
          "align_center",
          "align_max",
          "distribute_centers",
          "distribute_gaps"
        ],
        "description": "Alignment anchor or equal-spacing policy."
      }
    },
    "required": [
      "scenePath",
      "subjectPaths",
      "axis",
      "mode"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Align or space 3D nodes

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_align_distribute_3d",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine align-distribute-3d
  ```
</CodeGroup>

***

### attach\_to\_surface

`engine.attach_to_surface`: **Mount a piece on a surface**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Turn a piece so its measured back faces a wall, ceiling or floor found by a ray, keep it upright and seat it at a standoff: pipes, lamps, signs. Saves the scene; a refused seat puts the piece back.

| | |
| - | - |
| **MCP** | `summer_attach_to_surface` in the npm MCP |
| **CLI** | `summer engine attach-to-surface` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_attach_to_surface` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene, e.g. 'res\://levels/street.tscn'. It must be open; physics rays need it to be the active tab. Length 1 to 512. |
| `subject` | string | Yes | Piece to mount (exact path from the scene root). Length 1 to 256. |
| `surface` | string | No | Surface node. Without ray, the ray runs from the subject's origin to the nearest point of this node's bounds; with ray, hits on other nodes are skipped. The seat must land on this node (or inside it); a seat on any other node is refused and the piece is put back. Length 1 to 256. |
| `ray` | object | No | Explicit ray that finds the surface plane and its normal. Pass this or surface (or both). With a ray only, a seat on another node is refused unless that node lies on the hit plane (a coplanar neighbour module, warned). |
| `ray.origin` | number\[] | Yes | Ray start \[x, y, z] in scene space. Items 3 to 3. |
| `ray.direction` | number\[] | Yes | Ray direction \[x, y, z]. Items 3 to 3. |
| `backAxis` | "+x" \| "-x" \| "+y" \| "-y" \| "+z" \| "-z" | No | The subject's LOCAL axis that faces into the surface. Measure it with summer\_inspect\_asset. Default `"-z"`. |
| `upAxis` | "+x" \| "-x" \| "+y" \| "-y" \| "+z" \| "-z" | No | The subject's LOCAL axis kept toward worldUp; not on the same line as backAxis. Default `"+y"`. |
| `worldUp` | number\[] | No | World direction the upAxis follows (projected onto the surface). Default `[0,1,0]`. Items 3 to 3. |
| `standoff` | number | No | Gap between the subject's measured back face (the extreme of its visible bounds along backAxis) and the surface. Default `0`. Range 0 to 10. |
| `placeAt` | "current" \| "hit" | No | current: the piece keeps its height and its place along the surface and only moves along the surface normal. hit: it also slides so the centre of its back face lands on the ray hit point (its height then follows the ray). Default `"current"`. |
| `maxMove` | number | No | Refuse, changing nothing, when the piece would end farther than this from where it starts. Place the piece near its mount first; raise this only for a deliberate long move. Default `2`. Range … to 100. |
| `maxDistance` | number | No | Maximum ray length when looking for the surface. Default `20`. Range … to 1000. |
| `collisionMask` | integer | No | Godot 3D physics layer mask for the ray. Default `4294967295`. Range 0 to 4294967295. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene, e.g. 'res://levels/street.tscn'. It must be open; physics rays need it to be the active tab."
      },
      "subject": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Piece to mount (exact path from the scene root)."
      },
      "surface": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Surface node. Without ray, the ray runs from the subject's origin to the nearest point of this node's bounds; with ray, hits on other nodes are skipped. The seat must land on this node (or inside it); a seat on any other node is refused and the piece is put back."
      },
      "ray": {
        "type": "object",
        "properties": {
          "origin": {
            "type": "array",
            "minItems": 3,
            "maxItems": 3,
            "items": {
              "type": "number"
            },
            "description": "Ray start [x, y, z] in scene space."
          },
          "direction": {
            "type": "array",
            "minItems": 3,
            "maxItems": 3,
            "items": {
              "type": "number"
            },
            "description": "Ray direction [x, y, z]."
          }
        },
        "required": [
          "origin",
          "direction"
        ],
        "additionalProperties": false,
        "description": "Explicit ray that finds the surface plane and its normal. Pass this or surface (or both). With a ray only, a seat on another node is refused unless that node lies on the hit plane (a coplanar neighbour module, warned)."
      },
      "backAxis": {
        "type": "string",
        "enum": [
          "+x",
          "-x",
          "+y",
          "-y",
          "+z",
          "-z"
        ],
        "default": "-z",
        "description": "The subject's LOCAL axis that faces into the surface. Measure it with summer_inspect_asset."
      },
      "upAxis": {
        "type": "string",
        "enum": [
          "+x",
          "-x",
          "+y",
          "-y",
          "+z",
          "-z"
        ],
        "default": "+y",
        "description": "The subject's LOCAL axis kept toward worldUp; not on the same line as backAxis."
      },
      "worldUp": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "default": [
          0,
          1,
          0
        ],
        "description": "World direction the upAxis follows (projected onto the surface)."
      },
      "standoff": {
        "type": "number",
        "minimum": 0,
        "maximum": 10,
        "default": 0,
        "description": "Gap between the subject's measured back face (the extreme of its visible bounds along backAxis) and the surface."
      },
      "placeAt": {
        "type": "string",
        "enum": [
          "current",
          "hit"
        ],
        "default": "current",
        "description": "current: the piece keeps its height and its place along the surface and only moves along the surface normal. hit: it also slides so the centre of its back face lands on the ray hit point (its height then follows the ray)."
      },
      "maxMove": {
        "type": "number",
        "exclusiveMinimum": 0,
        "maximum": 100,
        "default": 2,
        "description": "Refuse, changing nothing, when the piece would end farther than this from where it starts. Place the piece near its mount first; raise this only for a deliberate long move."
      },
      "maxDistance": {
        "type": "number",
        "exclusiveMinimum": 0,
        "maximum": 1000,
        "default": 20,
        "description": "Maximum ray length when looking for the surface."
      },
      "collisionMask": {
        "type": "integer",
        "minimum": 0,
        "maximum": 4294967295,
        "default": 4294967295,
        "description": "Godot 3D physics layer mask for the ray."
      }
    },
    "required": [
      "scenePath",
      "subject"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Mount a piece on a surface

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_attach_to_surface",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine attach-to-surface
  ```
</CodeGroup>

***

### batch

`engine.batch`: **Run engine ops in one call**

Send a list of raw engine ops (AddNode, SetProp, RunVerification...) in one call: one undo step unless an op must travel alone, and one save at the end. Ask for receipt summary on long lists. For computed edits, engine.run\_script is simpler.

| | |
| - | - |
| **MCP** | `summer_batch` in the npm MCP |
| **CLI** | `summer engine batch` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_batch` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Required when ops contains scene mutations; exact res\:// target scene path |
| `ops` | object\[] | Yes | Array of operation objects, each with 'op' plus its parameters. InstantiateScene ops may also carry position, rotation\_degrees, scale or transform; the tool sets them on the created node. Each InstantiateScene is its own engine request; the transforms of a run of them travel together before the next other op, so N placed pieces plus the save cost about N + 2 requests. |
| `receipt` | "full" \| "summary" | No | full (default): every engine receipt. summary: counts, failures with their op index, created node paths only (under 5 KB). |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Required when ops contains scene mutations; exact res:// target scene path"
      },
      "ops": {
        "type": "array",
        "items": {
          "type": "object",
          "additionalProperties": {}
        },
        "description": "Array of operation objects, each with 'op' plus its parameters. InstantiateScene ops may also carry position, rotation_degrees, scale or transform; the tool sets them on the created node. Each InstantiateScene is its own engine request; the transforms of a run of them travel together before the next other op, so N placed pieces plus the save cost about N + 2 requests."
      },
      "receipt": {
        "type": "string",
        "enum": [
          "full",
          "summary"
        ],
        "description": "full (default): every engine receipt. summary: counts, failures with their op index, created node paths only (under 5 KB)."
      }
    },
    "required": [
      "ops"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Run engine ops in one call

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_batch",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine batch
  ```
</CodeGroup>

***

### capture\_gameplay

`engine.capture_gameplay`: **Capture gameplay screenshots**

Capture real gameplay frames (HUD included) from a hidden game window, no editor needed; game flags and player steps get past the title screen. Returns each frame's path and size: look at them before use.

| | |
| - | - |
| **MCP** | `summer_capture_gameplay` in the npm MCP |
| **CLI** | `summer engine capture-gameplay` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_capture_gameplay` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `project` | string | No | Project folder with project.godot. Defaults to the MCP's bound project, then the working directory. |
| `scene` | string | No | Scene to start (res\://... or uid://...). Default is the project's main scene, often a title menu; pass the gameplay scene for gameplay frames. |
| `resolution` | string | No | Window size WIDTHxHEIGHT (default 1920x1080; 1080x1920 for portrait). |
| `frames` | integer | No | Frames to save (default 1). Range 1 to 10. |
| `waitSeconds` | number | No | Seconds the game runs before the first frame (default 3). Range 0 to 120. |
| `intervalSeconds` | number | No | Seconds between frames (default 1). Range 0.1 to 60. |
| `out` | string | No | Output folder. Defaults to \<project>/.summer/captures/\<time>/ (ignored by git). |
| `args` | string\[] | No | The game's own command-line flags, passed after "--" (OS.get\_cmdline\_user\_args()), e.g. \["--autostart", "--solo"] to skip the title screen. Items 0 to 32. |
| `steps` | object\[] | No | What to do after waitSeconds, in order; exactly one of press, key, action, click, drag, wait, shot per step. Example: \[\{"press":"Play"},\{"wait":3000},\{"key":"Space"},\{"shot":true},\{"action":"jump"},\{"wait":500},\{"shot":true}]. With a shot step only shot steps save frames. A step that cannot run becomes a warning. Items 0 to 50. |
| `steps[].press` | string | No | Press the visible button with this text (or node name); waits up to timeoutSeconds (default 10) for it. |
| `steps[].timeoutSeconds` | number | No | Range 0 to 60. |
| `steps[].key` | string | No | Press a key by Godot name (Space, Enter, Escape, A, Up). |
| `steps[].action` | string | No | Press an input action from the project's InputMap, e.g. jump. |
| `steps[].holdMs` | number | No | How long key or action is held (default 100). Range 0 to 10000. |
| `steps[].click` | number\[] | No | Left-click at \[x, y] in frame pixels. |
| `steps[].drag` | object | No | Drag with the left button from \[x, y] to \[x, y] over ms (default 300). |
| `steps[].drag.from` | number\[] | Yes | |
| `steps[].drag.to` | number\[] | Yes | |
| `steps[].drag.ms` | number | No | Range 0 to 10000. |
| `steps[].wait` | number | No | Wait this many milliseconds. Range 0 to 60000. |
| `steps[].shot` | boolean | No | true saves a frame now. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "project": {
        "type": "string",
        "description": "Project folder with project.godot. Defaults to the MCP's bound project, then the working directory."
      },
      "scene": {
        "type": "string",
        "description": "Scene to start (res://... or uid://...). Default is the project's main scene, often a title menu; pass the gameplay scene for gameplay frames."
      },
      "resolution": {
        "type": "string",
        "description": "Window size WIDTHxHEIGHT (default 1920x1080; 1080x1920 for portrait)."
      },
      "frames": {
        "type": "integer",
        "minimum": 1,
        "maximum": 10,
        "description": "Frames to save (default 1)."
      },
      "waitSeconds": {
        "type": "number",
        "minimum": 0,
        "maximum": 120,
        "description": "Seconds the game runs before the first frame (default 3)."
      },
      "intervalSeconds": {
        "type": "number",
        "minimum": 0.1,
        "maximum": 60,
        "description": "Seconds between frames (default 1)."
      },
      "out": {
        "type": "string",
        "description": "Output folder. Defaults to <project>/.summer/captures/<time>/ (ignored by git)."
      },
      "args": {
        "type": "array",
        "maxItems": 32,
        "items": {
          "type": "string"
        },
        "description": "The game's own command-line flags, passed after \"--\" (OS.get_cmdline_user_args()), e.g. [\"--autostart\", \"--solo\"] to skip the title screen."
      },
      "steps": {
        "type": "array",
        "maxItems": 50,
        "description": "What to do after waitSeconds, in order; exactly one of press, key, action, click, drag, wait, shot per step. Example: [{\"press\":\"Play\"},{\"wait\":3000},{\"key\":\"Space\"},{\"shot\":true},{\"action\":\"jump\"},{\"wait\":500},{\"shot\":true}]. With a shot step only shot steps save frames. A step that cannot run becomes a warning.",
        "items": {
          "type": "object",
          "properties": {
            "press": {
              "type": "string",
              "description": "Press the visible button with this text (or node name); waits up to timeoutSeconds (default 10) for it."
            },
            "timeoutSeconds": {
              "type": "number",
              "minimum": 0,
              "maximum": 60
            },
            "key": {
              "type": "string",
              "description": "Press a key by Godot name (Space, Enter, Escape, A, Up)."
            },
            "action": {
              "type": "string",
              "description": "Press an input action from the project's InputMap, e.g. jump."
            },
            "holdMs": {
              "type": "number",
              "minimum": 0,
              "maximum": 10000,
              "description": "How long key or action is held (default 100)."
            },
            "click": {
              "type": "array",
              "items": {
                "type": "number"
              },
              "description": "Left-click at [x, y] in frame pixels."
            },
            "drag": {
              "type": "object",
              "properties": {
                "from": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                },
                "to": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                },
                "ms": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 10000
                }
              },
              "required": [
                "from",
                "to"
              ],
              "description": "Drag with the left button from [x, y] to [x, y] over ms (default 300)."
            },
            "wait": {
              "type": "number",
              "minimum": 0,
              "maximum": 60000,
              "description": "Wait this many milliseconds."
            },
            "shot": {
              "type": "boolean",
              "description": "true saves a frame now."
            }
          },
          "additionalProperties": false
        }
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Capture gameplay screenshots

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_capture_gameplay",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine capture-gameplay
  ```
</CodeGroup>

***

### clear\_console

`engine.clear_console`: **Clear the editor console**

Clear the editor's Output panel, for a clean slate before the game runs.

| | |
| - | - |
| **MCP** | `summer_clear_console` in the npm MCP |
| **CLI** | `summer engine clear-console` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_clear_console` |

**Inputs:**

No inputs.

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Clear the editor console

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_clear_console",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine clear-console
  ```
</CodeGroup>

***

### connect\_ports

`engine.connect_ports`: **Join two pieces at their ports**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Move and turn one piece so its port (a Marker3D, or an open pipe end such as +Y) meets another piece's port: pipe to pipe, duct to duct. Refuses joins that tilt the piece. Saves the scene.

| | |
| - | - |
| **MCP** | `summer_connect_ports` in the npm MCP |
| **CLI** | `summer engine connect-ports` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_connect_ports` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene, e.g. 'res\://levels/street.tscn'. It must be open in the editor (any tab). Length 1 to 512. |
| `subject` | string | Yes | Piece to move. Length 1 to 256. |
| `subjectPort` | string \| integer | Yes | An open-loop id from summer\_inspect\_asset, e.g. '+Y' (the outermost open loop facing +Y in the piece's own axes) or '+Y#2' (the next one facing +Y); or a Marker3D (or Node3D) name under the subject, whose -Z axis points out of the port; or an open-loop index. Ids and indices follow the stable order (facing, then position), never the radius. |
| `target` | string | Yes | Piece that stays put. Length 1 to 256. |
| `targetPort` | string \| integer | Yes | Port on the target (open-loop id such as '-Y', marker name, or open-loop index). |
| `gap` | number | No | Distance between the ports along the target port's direction. Default `0`. Range -1 to 10. |
| `rollDegrees` | number | No | Extra turn of the subject, in degrees, about the joined port axis, applied after the ports are lined up. Axis: the target port's direction reversed, pointing from the joint into the target (receipt roll\_axis). Sign: right-hand rule about that axis; positive turns counter-clockwise when you look back along the axis from inside the target toward the subject. Zero: the shortest turn that makes the subject's port face the target's from the subject's CURRENT orientation, so the same value gives different results from different start poses. Read other\_ports in the receipt; once the ports are joined, a second call turns by exactly rollDegrees about the joint (180 flips a bend's free end to the other side). Default `0`. Range -360 to 360. |
| `maxTiltDegrees` | number | No | Refuse the join, changing nothing, when it would tilt the subject's up axis (its local +Y) more than this many degrees from where it points now. Turning about the up axis is never tilt. The refusal names the predicted tilt and the subject ports that would join within the limit. Default `5`. Range 0 to 180. |
| `allowTilt` | boolean | No | true joins even when the subject tilts more than maxTiltDegrees (a bend laid on its side, a sloped run). The receipt still reports tilt\_degrees. Default `false`. |
| `maxTriangles` | integer | No | Triangle budget (100-300000) per node when ports are open-loop ids or indices. Default `60000`. Range 100 to 300000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene, e.g. 'res://levels/street.tscn'. It must be open in the editor (any tab)."
      },
      "subject": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Piece to move."
      },
      "subjectPort": {
        "oneOf": [
          {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          {
            "type": "integer",
            "minimum": 0,
            "maximum": 255
          }
        ],
        "description": "An open-loop id from summer_inspect_asset, e.g. '+Y' (the outermost open loop facing +Y in the piece's own axes) or '+Y#2' (the next one facing +Y); or a Marker3D (or Node3D) name under the subject, whose -Z axis points out of the port; or an open-loop index. Ids and indices follow the stable order (facing, then position), never the radius."
      },
      "target": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Piece that stays put."
      },
      "targetPort": {
        "oneOf": [
          {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          {
            "type": "integer",
            "minimum": 0,
            "maximum": 255
          }
        ],
        "description": "Port on the target (open-loop id such as '-Y', marker name, or open-loop index)."
      },
      "gap": {
        "type": "number",
        "minimum": -1,
        "maximum": 10,
        "default": 0,
        "description": "Distance between the ports along the target port's direction."
      },
      "rollDegrees": {
        "type": "number",
        "minimum": -360,
        "maximum": 360,
        "default": 0,
        "description": "Extra turn of the subject, in degrees, about the joined port axis, applied after the ports are lined up. Axis: the target port's direction reversed, pointing from the joint into the target (receipt roll_axis). Sign: right-hand rule about that axis; positive turns counter-clockwise when you look back along the axis from inside the target toward the subject. Zero: the shortest turn that makes the subject's port face the target's from the subject's CURRENT orientation, so the same value gives different results from different start poses. Read other_ports in the receipt; once the ports are joined, a second call turns by exactly rollDegrees about the joint (180 flips a bend's free end to the other side)."
      },
      "maxTiltDegrees": {
        "type": "number",
        "minimum": 0,
        "maximum": 180,
        "default": 5,
        "description": "Refuse the join, changing nothing, when it would tilt the subject's up axis (its local +Y) more than this many degrees from where it points now. Turning about the up axis is never tilt. The refusal names the predicted tilt and the subject ports that would join within the limit."
      },
      "allowTilt": {
        "type": "boolean",
        "default": false,
        "description": "true joins even when the subject tilts more than maxTiltDegrees (a bend laid on its side, a sloped run). The receipt still reports tilt_degrees."
      },
      "maxTriangles": {
        "type": "integer",
        "minimum": 100,
        "maximum": 300000,
        "default": 60000,
        "description": "Triangle budget (100-300000) per node when ports are open-loop ids or indices."
      }
    },
    "required": [
      "scenePath",
      "subject",
      "subjectPort",
      "target",
      "targetPort"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Join two pieces at their ports

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_connect_ports",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine connect-ports
  ```
</CodeGroup>

***

### connect\_signal

`engine.connect_signal`: **Connect a signal**

Connect a signal of one node to a method of another so the saved scene keeps it, verified from the saved .tscn. The receiver should define the method. Then test it with engine.play.

| | |
| - | - |
| **MCP** | `summer_connect_signal` in the npm MCP |
| **CLI** | `summer engine connect-signal` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_connect_signal` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene path, e.g. 'res\://main.tscn' |
| `emitter` | string | Yes | Node that fires the signal, e.g. `./Player/HitArea` |
| `signal` | string | Yes | Signal name, e.g. 'body\_entered' |
| `receiver` | string | Yes | Node with the handler script, e.g. `./Player` |
| `method` | string | Yes | Method name in the receiver's script, e.g. '\_on\_hit\_area\_body\_entered' |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene path, e.g. 'res://main.tscn'"
      },
      "emitter": {
        "type": "string",
        "description": "Node that fires the signal, e.g. './Player/HitArea'"
      },
      "signal": {
        "type": "string",
        "description": "Signal name, e.g. 'body_entered'"
      },
      "receiver": {
        "type": "string",
        "description": "Node with the handler script, e.g. './Player'"
      },
      "method": {
        "type": "string",
        "description": "Method name in the receiver's script, e.g. '_on_hit_area_body_entered'"
      }
    },
    "required": [
      "scenePath",
      "emitter",
      "signal",
      "receiver",
      "method"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Connect a signal

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_connect_signal",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine connect-signal
  ```
</CodeGroup>

***

### create\_debug\_report

`engine.create_debug_report`: **Write a debug report**

Write a support-ready Markdown report: doctor checks, engine health, diagnostics, console and debugger output, and a hand-off prompt. No tokens or file contents; the person should still read it before sending it.

| | |
| - | - |
| **MCP** | `summer_create_debug_report` in the npm MCP |
| **CLI** | `summer engine create-debug-report` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_create_debug_report` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `issue` | string | No | User-visible issue or repro summary. |
| `output_path` | string | No | Where to write the Markdown report. Defaults to the open project root, or the current working directory if no project is open. |
| `include_play_session` | boolean | No | Launch the game briefly and collect post-play diagnostics. Default `false`. |
| `play_wait_ms` | number | No | Milliseconds to wait after launching the game when include\_play\_session is true. Default `2500`. |
| `max_console_lines` | number | No | Console lines to include after filtering/deduping. Default `200`. |
| `max_debugger_entries` | number | No | Debugger error/warning entries to include after filtering/deduping. Default `100`. |
| `include_doctor` | boolean | No | Include summer doctor checks in the report. Default `true`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "issue": {
        "type": "string",
        "description": "User-visible issue or repro summary."
      },
      "output_path": {
        "type": "string",
        "description": "Where to write the Markdown report. Defaults to the open project root, or the current working directory if no project is open."
      },
      "include_play_session": {
        "type": "boolean",
        "default": false,
        "description": "Launch the game briefly and collect post-play diagnostics."
      },
      "play_wait_ms": {
        "type": "number",
        "default": 2500,
        "description": "Milliseconds to wait after launching the game when include_play_session is true."
      },
      "max_console_lines": {
        "type": "number",
        "default": 200,
        "description": "Console lines to include after filtering/deduping."
      },
      "max_debugger_entries": {
        "type": "number",
        "default": 100,
        "description": "Debugger error/warning entries to include after filtering/deduping."
      },
      "include_doctor": {
        "type": "boolean",
        "default": true,
        "description": "Include summer doctor checks in the report."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Write a debug report

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_create_debug_report",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine create-debug-report
  ```
</CodeGroup>

***

### create\_scene

`engine.create_scene`: **Create a scene file**

Create a new, minimal .tscn file with the root type you name. It fails when the file exists and never touches the open scene. Build it out with engine.run\_script and that scenePath.

| | |
| - | - |
| **MCP** | `summer_create_scene` in the npm MCP |
| **CLI** | `summer engine create-scene` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_create_scene` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | New scene path, e.g. 'res\://scenes/empty\_level.tscn' |
| `rootName` | string | No | Root node name for the new scene Default `"Main"`. |
| `rootType` | string | No | Root node type. Default 'Node3D' (3D scenes); common alternatives: 'Node2D' (2D scenes), 'Control' (UI scenes), 'Node' (logic-only). Default `"Node3D"`. |
| `allow_temporary_scene_mutation` | boolean | No | DEPRECATED, ignored. Scene creation no longer mutates any open scene; kept only so older callers don't break. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "New scene path, e.g. 'res://scenes/empty_level.tscn'"
      },
      "rootName": {
        "type": "string",
        "default": "Main",
        "description": "Root node name for the new scene"
      },
      "rootType": {
        "type": "string",
        "default": "Node3D",
        "description": "Root node type. Default 'Node3D' (3D scenes); common alternatives: 'Node2D' (2D scenes), 'Control' (UI scenes), 'Node' (logic-only)."
      },
      "allow_temporary_scene_mutation": {
        "type": "boolean",
        "description": "DEPRECATED, ignored. Scene creation no longer mutates any open scene; kept only so older callers don't break."
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Create a scene file

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_create_scene",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine create-scene
  ```
</CodeGroup>

***

### debug\_views

`engine.debug_views`: **Render debug views of a pose**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Render one pose as a grid of debug views next to the beauty pass: lighting only, albedo, world normals, overdraw and wireframe. Shows why a shot looks wrong.

| | |
| - | - |
| **MCP** | `summer_debug_views` in the npm MCP |
| **CLI** | `summer engine debug-views` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_debug_views` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Scene to look at, e.g. "res\://levels/town.tscn" (the SAVED file). Omit for the scene open in the editor. |
| `bookmark_name` | string | No | Pose from a camera bookmark (summer\_camera\_bookmark). Use INSTEAD of camera\_position/camera\_look\_at. |
| `camera_position` | string | No | Explicit pose: camera position, "Vector3(x, y, z)". Goes with camera\_look\_at. |
| `camera_look_at` | string | No | Explicit pose: point the camera looks at, "Vector3(x, y, z)". |
| `fov` | number | No | Vertical field of view in degrees (1..179). Default: the bookmark's own, or 60. |
| `views` | "beauty" \| "lighting" \| "unshaded" \| "normals" \| "overdraw" \| "wireframe"\[] | No | Which views, in grid order (default all six: beauty, lighting, unshaded, normals, overdraw, wireframe). Items 0 to 8. |
| `update_previous` | boolean | No | bookmark\_name only: replace the bookmark's previous image (compare baseline) with this beauty tile. Default false: only a missing slot is created. |
| `max_size` | integer | No | Longest edge of the returned JPEG in pixels (default 1536). Bigger costs more context; up to 4096 for detail work on a PC. Range 64 to 4096. |
| `aspect` | number | No | Frame width/height (default 1.7778 = 16:9). Every tile uses it. |
| `save_to` | string | No | Also write the returned image to res\://.summer/shots/saved/\<name>.jpg (1-64 of A-Z a-z 0-9 \\\_ -; needs max\_size \<= 1024). Nothing is written without it, except one previous-image slot per rendered bookmark. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to look at, e.g. \"res://levels/town.tscn\" (the SAVED file). Omit for the scene open in the editor."
      },
      "bookmark_name": {
        "type": "string",
        "description": "Pose from a camera bookmark (summer_camera_bookmark). Use INSTEAD of camera_position/camera_look_at."
      },
      "camera_position": {
        "type": "string",
        "description": "Explicit pose: camera position, \"Vector3(x, y, z)\". Goes with camera_look_at."
      },
      "camera_look_at": {
        "type": "string",
        "description": "Explicit pose: point the camera looks at, \"Vector3(x, y, z)\"."
      },
      "fov": {
        "type": "number",
        "description": "Vertical field of view in degrees (1..179). Default: the bookmark's own, or 60."
      },
      "views": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "beauty",
            "lighting",
            "unshaded",
            "normals",
            "overdraw",
            "wireframe"
          ]
        },
        "maxItems": 8,
        "description": "Which views, in grid order (default all six: beauty, lighting, unshaded, normals, overdraw, wireframe)."
      },
      "update_previous": {
        "type": "boolean",
        "description": "bookmark_name only: replace the bookmark's previous image (compare baseline) with this beauty tile. Default false: only a missing slot is created."
      },
      "max_size": {
        "type": "integer",
        "minimum": 64,
        "maximum": 4096,
        "description": "Longest edge of the returned JPEG in pixels (default 1536). Bigger costs more context; up to 4096 for detail work on a PC."
      },
      "aspect": {
        "type": "number",
        "description": "Frame width/height (default 1.7778 = 16:9). Every tile uses it."
      },
      "save_to": {
        "type": "string",
        "description": "Also write the returned image to res://.summer/shots/saved/<name>.jpg (1-64 of A-Z a-z 0-9 _ -; needs max_size <= 1024). Nothing is written without it, except one previous-image slot per rendered bookmark."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Render debug views of a pose

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_debug_views",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine debug-views
  ```
</CodeGroup>

***

### delete\_camera\_bookmark

`engine.delete_camera_bookmark`: **Delete a camera bookmark**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Delete one saved camera viewpoint by name. Returns the names that remain.

| | |
| - | - |
| **MCP** | `summer_engine_delete_camera_bookmark` in the npm MCP |
| **CLI** | `summer engine delete-camera-bookmark` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_camera_bookmark#delete` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `name` | string | Yes | Bookmark name for save/delete: 1-64 characters from A-Z a-z 0-9 \\\_ - (e.g. "hero\_closeup"). |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Bookmark name for save/delete: 1-64 characters from A-Z a-z 0-9 _ - (e.g. \"hero_closeup\")."
      }
    },
    "required": [
      "name"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Delete a camera bookmark

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_engine_delete_camera_bookmark",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine delete-camera-bookmark
  ```
</CodeGroup>

***

### enable\_plugin

`engine.enable_plugin`: **Enable an editor plugin**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Enable an editor plugin in res\://addons/\<name>/ and return the real result: enabled with its autoloads, or why it failed. Older engines only queue it (queued true); then check engine.get\_debugger\_errors.

| | |
| - | - |
| **MCP** | `summer_enable_plugin` in the npm MCP |
| **CLI** | `summer engine enable-plugin` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_enable_plugin` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `plugin` | string | Yes | The plugin folder under res\://addons/ (e.g. 'quest\_tools') or its 'res\://addons/\<name>/plugin.cfg' Length 1 to 200. |
| `timeoutMs` | integer | No | How long the engine waits for the plugin to load (default 30000) Range 1000 to 120000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "plugin": {
        "type": "string",
        "minLength": 1,
        "maxLength": 200,
        "description": "The plugin folder under res://addons/ (e.g. 'quest_tools') or its 'res://addons/<name>/plugin.cfg'"
      },
      "timeoutMs": {
        "type": "integer",
        "minimum": 1000,
        "maximum": 120000,
        "description": "How long the engine waits for the plugin to load (default 30000)"
      }
    },
    "required": [
      "plugin"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Enable an editor plugin

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_enable_plugin",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine enable-plugin
  ```
</CodeGroup>

***

### export\_game

`engine.export_game`: **Export the game**

Export the game headless as the file the Summer Games store takes: a bundle for iPhone, Android, macOS and Windows, a web build or a desktop download. Returns path, sha256 and size. Upload it with store.upload\_file.

| | |
| - | - |
| **MCP** | `summer_export_game` in the npm MCP |
| **CLI** | `summer engine export-game` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_export_game` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `project` | string | No | Project folder with project.godot. Defaults to the MCP's bound project, then the working directory. |
| `out` | string | No | Output .zip path. Defaults to \<project>/.summer/exports/. |
| `targets` | "macos" \| "windows" \| "ios" \| "android" \| "web"\[] | No | Store platforms. Bundle: any of macos, windows, ios, android (omit to use every platform the project declares). Download: exactly one of web, macos, windows. |
| `format` | "bundle" \| "download" | No | bundle (default): the summer.games store build. download: a web build or native download; the default when targets is \["web"]. |
| `debug` | boolean | No | Export a debug build (--export-debug). Default `false`. |
| `timeoutSeconds` | integer | No | Stop the engine after this many seconds (default 900; a first export imports every asset). Range 10 to 7200. |
| `alignDeclaration` | boolean | No | A game with a server, set summer.build.json targetPlatforms to targets before exporting. The store refuses an upload whose declaration differs from the exported platforms (declaration\_mismatch) and that spends the version. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "project": {
        "type": "string",
        "description": "Project folder with project.godot. Defaults to the MCP's bound project, then the working directory."
      },
      "out": {
        "type": "string",
        "description": "Output .zip path. Defaults to <project>/.summer/exports/."
      },
      "targets": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "macos",
            "windows",
            "ios",
            "android",
            "web"
          ]
        },
        "description": "Store platforms. Bundle: any of macos, windows, ios, android (omit to use every platform the project declares). Download: exactly one of web, macos, windows."
      },
      "format": {
        "type": "string",
        "enum": [
          "bundle",
          "download"
        ],
        "description": "bundle (default): the summer.games store build. download: a web build or native download; the default when targets is [\"web\"]."
      },
      "debug": {
        "type": "boolean",
        "default": false,
        "description": "Export a debug build (--export-debug)."
      },
      "timeoutSeconds": {
        "type": "integer",
        "minimum": 10,
        "maximum": 7200,
        "description": "Stop the engine after this many seconds (default 900; a first export imports every asset)."
      },
      "alignDeclaration": {
        "type": "boolean",
        "description": "A game with a server, set summer.build.json targetPlatforms to targets before exporting. The store refuses an upload whose declaration differs from the exported platforms (declaration_mismatch) and that spends the version."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Export the game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_export_game",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine export-game
  ```
</CodeGroup>

***

### export\_templates

`engine.export_templates`: **List or install export templates**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

List or install Summer Engine export templates (web, macOS, Windows) from Summer's CDN, each sha256-checked. Needed only for engine.export\_game with format download.

| | |
| - | - |
| **MCP** | `summer_export_templates` in the npm MCP |
| **CLI** | `summer engine export-templates` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_export_templates` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `action` | "list" \| "install" | Yes | list: installed and published templates. install: download and install. |
| `platforms` | "web" \| "macos" \| "windows" \| "linux" \| "ios" \| "android"\[] | No | Template platforms to install (default \["web"]). |
| `includeDebug` | boolean | No | Also install the debug templates (for exports with debug true). Default `false`. |
| `summerVersion` | string | No | The installed Summer Engine version (Help > About, e.g. 0.7.1). Read automatically on macOS; needed on Windows and Linux. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": [
          "list",
          "install"
        ],
        "description": "list: installed and published templates. install: download and install."
      },
      "platforms": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "web",
            "macos",
            "windows",
            "linux",
            "ios",
            "android"
          ]
        },
        "description": "Template platforms to install (default [\"web\"])."
      },
      "includeDebug": {
        "type": "boolean",
        "default": false,
        "description": "Also install the debug templates (for exports with debug true)."
      },
      "summerVersion": {
        "type": "string",
        "description": "The installed Summer Engine version (Help > About, e.g. 0.7.1). Read automatically on macOS; needed on Windows and Linux."
      }
    },
    "required": [
      "action"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** List or install export templates

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_export_templates",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine export-templates
  ```
</CodeGroup>

***

### fabricate\_3d

`engine.fabricate_3d`: **Make a mesh with Blender**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Make a mesh with a bpy script in the person's own Blender (4.2 or newer, headless), import the .glb into the project and optionally place it. For exact modular kits and effect meshes, not characters or props.

| | |
| - | - |
| **MCP** | `summer_fabricate_3d` in the npm MCP |
| **CLI** | `summer engine fabricate-3d` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_fabricate_3d` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `source` | string | Yes | Blender Python (bpy) code that creates mesh objects and leaves them linked in the scene. No export call — the engine exports the .glb. Pre-bound names bpy, bmesh, mathutils, math, Vector, Matrix, Euler. |
| `name` | string | Yes | Asset name — used for the default out\_path (res\://assets/fabricated/\<name>.glb) and the instantiated node. Sanitized by the engine to \[A-Za-z0-9\_-]. |
| `out_path` | string | No | Destination res\:// path ending in .glb (default res\://assets/fabricated/\<name>.glb). An existing file is overwritten; '..' and hidden directories are refused. |
| `target_size` | number | No | Largest world-AABB dimension after instantiation — uniform scale, same rule as summer\_instantiate\_scene target\_size. Only used together with import\_to\_scene. |
| `import_to_scene` | object | No | Instantiate the imported .glb into the currently open scene after import. Omit to only write and import the file. |
| `import_to_scene.parent` | string | Yes | Parent node path in the open scene, e.g. '/' (scene root) or `./World`. |
| `import_to_scene.position` | string | No | Optional local position as the engine variant string 'Vector3(x, y, z)'. |
| `max_seconds` | number | No | Child budget in seconds (default 120, clamped 15-600) — Blender boot + script + procedural-colour bakes + export. The client waits max\_seconds + 60 s. |
| `checkpoint` | boolean | No | Take a SummerGit checkpoint before the child runs (default false). The result confesses (no\_rewind\_point) when none could be taken. |
| `blender_path` | string | No | Explicit Blender executable. Only when the user named one; otherwise the engine resolves SUMMER\_BLENDER\_BIN, the editor setting filesystem/import/blender/blender\_path, then PATH and well-known install locations. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "source": {
        "type": "string",
        "description": "Blender Python (bpy) code that creates mesh objects and leaves them linked in the scene. No export call — the engine exports the .glb. Pre-bound names bpy, bmesh, mathutils, math, Vector, Matrix, Euler."
      },
      "name": {
        "type": "string",
        "description": "Asset name — used for the default out_path (res://assets/fabricated/<name>.glb) and the instantiated node. Sanitized by the engine to [A-Za-z0-9_-]."
      },
      "out_path": {
        "type": "string",
        "description": "Destination res:// path ending in .glb (default res://assets/fabricated/<name>.glb). An existing file is overwritten; '..' and hidden directories are refused."
      },
      "target_size": {
        "type": "number",
        "exclusiveMinimum": 0,
        "description": "Largest world-AABB dimension after instantiation — uniform scale, same rule as summer_instantiate_scene target_size. Only used together with import_to_scene."
      },
      "import_to_scene": {
        "type": "object",
        "description": "Instantiate the imported .glb into the currently open scene after import. Omit to only write and import the file.",
        "properties": {
          "parent": {
            "type": "string",
            "description": "Parent node path in the open scene, e.g. '/' (scene root) or './World'."
          },
          "position": {
            "type": "string",
            "description": "Optional local position as the engine variant string 'Vector3(x, y, z)'."
          }
        },
        "required": [
          "parent"
        ],
        "additionalProperties": false
      },
      "max_seconds": {
        "type": "number",
        "description": "Child budget in seconds (default 120, clamped 15-600) — Blender boot + script + procedural-colour bakes + export. The client waits max_seconds + 60 s."
      },
      "checkpoint": {
        "type": "boolean",
        "description": "Take a SummerGit checkpoint before the child runs (default false). The result confesses (no_rewind_point) when none could be taken."
      },
      "blender_path": {
        "type": "string",
        "description": "Explicit Blender executable. Only when the user named one; otherwise the engine resolves SUMMER_BLENDER_BIN, the editor setting filesystem/import/blender/blender_path, then PATH and well-known install locations."
      }
    },
    "required": [
      "source",
      "name"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Make a mesh with Blender

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_fabricate_3d",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine fabricate-3d
  ```
</CodeGroup>

***

### frame\_nodes

`engine.frame_nodes`: **Frame nodes and render them**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Fit a camera to the world bounds of some nodes and render them with the scene's real environment and lights; bookmark\_name also saves the pose. Returns the image and a caption with the pose and bounds.

| | |
| - | - |
| **MCP** | `summer_frame_nodes` in the npm MCP |
| **CLI** | `summer engine frame-nodes` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_frame_nodes` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Scene to look at, e.g. "res\://levels/town.tscn" (the SAVED file). Omit for the scene open in the editor. |
| `nodes` | string\[] | Yes | Node paths relative to the scene root ("House1", "Props/Crate\_02"). The camera fits their combined WORLD bounds (visible meshes, children included). Items 1 to 16. |
| `direction` | "front" \| "back" \| "left" \| "right" \| "top" \| "iso" | No | Side the camera sits on: "front" (+Z), "back" (-Z), "left" (-X), "right" (+X), "top", "iso" (default, 3/4 from -X,+Y,-Z like summer\_screenshot). Use from for anything else. |
| `from` | string | No | Explicit direction FROM the nodes TOWARD the camera, "Vector3(1, 0.4, 2)". Replaces direction. The fitted pose is checked in-engine: when walls block it, or it puts the camera behind or inside a one-sided surface (whose back is not drawn, so the image would look THROUGH it), the caption opens with a WARNING and offers the nearest valid from (+ fov); the requested view is still rendered. |
| `fill` | number | No | Share of the frame the nodes span along their limiting dimension (0.1..1.5, default 0.8). |
| `fov` | number | No | Vertical field of view in degrees (default 50). |
| `max_size` | integer | No | Longest edge of the returned JPEG in pixels (default 1024). Bigger costs more context; up to 4096 for detail work on a PC. Range 64 to 4096. |
| `aspect` | number | No | Frame width/height (default 1.7778 = 16:9). Every tile uses it. |
| `marks` | boolean | No | Numbered Set-of-Mark labels over the largest visible nodes; the caption maps label -> node path (feed a label to summer\_zoom mark). Each labelled node gets an occlusion test (centre + 4 bounds points); a node hidden behind other geometry is noted "(hidden behind \<path>)" — ignore its label. |
| `max_marks` | integer | No | marks only: cap on labels (engine default 32). Range 1 to 128. |
| `bookmark_name` | string | No | Also save the fitted pose as this camera bookmark (1-64 of A-Z a-z 0-9 \\\_ -), so later renders line up with it. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to look at, e.g. \"res://levels/town.tscn\" (the SAVED file). Omit for the scene open in the editor."
      },
      "nodes": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "minItems": 1,
        "maxItems": 16,
        "description": "Node paths relative to the scene root (\"House1\", \"Props/Crate_02\"). The camera fits their combined WORLD bounds (visible meshes, children included)."
      },
      "direction": {
        "type": "string",
        "enum": [
          "front",
          "back",
          "left",
          "right",
          "top",
          "iso"
        ],
        "description": "Side the camera sits on: \"front\" (+Z), \"back\" (-Z), \"left\" (-X), \"right\" (+X), \"top\", \"iso\" (default, 3/4 from -X,+Y,-Z like summer_screenshot). Use from for anything else."
      },
      "from": {
        "type": "string",
        "description": "Explicit direction FROM the nodes TOWARD the camera, \"Vector3(1, 0.4, 2)\". Replaces direction. The fitted pose is checked in-engine: when walls block it, or it puts the camera behind or inside a one-sided surface (whose back is not drawn, so the image would look THROUGH it), the caption opens with a WARNING and offers the nearest valid from (+ fov); the requested view is still rendered."
      },
      "fill": {
        "type": "number",
        "description": "Share of the frame the nodes span along their limiting dimension (0.1..1.5, default 0.8)."
      },
      "fov": {
        "type": "number",
        "description": "Vertical field of view in degrees (default 50)."
      },
      "max_size": {
        "type": "integer",
        "minimum": 64,
        "maximum": 4096,
        "description": "Longest edge of the returned JPEG in pixels (default 1024). Bigger costs more context; up to 4096 for detail work on a PC."
      },
      "aspect": {
        "type": "number",
        "description": "Frame width/height (default 1.7778 = 16:9). Every tile uses it."
      },
      "marks": {
        "type": "boolean",
        "description": "Numbered Set-of-Mark labels over the largest visible nodes; the caption maps label -> node path (feed a label to summer_zoom mark). Each labelled node gets an occlusion test (centre + 4 bounds points); a node hidden behind other geometry is noted \"(hidden behind <path>)\" — ignore its label."
      },
      "max_marks": {
        "type": "integer",
        "minimum": 1,
        "maximum": 128,
        "description": "marks only: cap on labels (engine default 32)."
      },
      "bookmark_name": {
        "type": "string",
        "description": "Also save the fitted pose as this camera bookmark (1-64 of A-Z a-z 0-9 _ -), so later renders line up with it."
      }
    },
    "required": [
      "nodes"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Frame nodes and render them

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_frame_nodes",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine frame-nodes
  ```
</CodeGroup>

***

### frame\_shot

`engine.frame_shot`: **Find camera poses for a shot**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Find, score and save camera poses for a shot type (establishing, eye level, low angle, detail, corridor), tested against the real geometry. Returns the best 3 poses and a sheet, and saves the best as a bookmark.

| | |
| - | - |
| **MCP** | `summer_frame_shot` in the npm MCP |
| **CLI** | `summer engine frame-shot` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_frame_shot` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Scene to look at, e.g. "res\://levels/town.tscn" (the SAVED file). Omit for the scene open in the editor. |
| `shot` | "establishing" \| "eye\_level" \| "low\_angle" \| "detail" \| "corridor" | Yes | "establishing" (wide, whole subject, 12-40 deg up; a pose showing more than 15% empty ground or world edge ranks below every pose showing less), "eye\_level" (player eye at spawn: its Camera3D kept inside 1.5-1.8 m, or eye\_height, above the walkable surface under the camera), "low\_angle" (hero, camera near the ground looking up), "detail" (close-up), "corridor" (down a lane/corridor inside the subject, found by a free-space scan, at eye height; prefers looking in from its open end). Eye-level and corridor cameras are never raised: a pose that cannot stand at eye height moves horizontally or is rejected. Every top pose states its camera height above the surface below it and its absolute y. |
| `subject` | string\[] | No | Node paths to frame (required except for eye\_level, where it is what the player looks at). Items 0 to 8. |
| `spawn` | string | No | eye\_level only: node the player stands at, e.g. the player or a spawn marker. Its own geometry never counts as an occluder. |
| `eye_height` | number | No | eye\_level/corridor: exact camera height in metres above the walkable surface under the camera (default: 1.6; an eye\_level spawn's own Camera3D keeps its height clamped into 1.5-1.8). |
| `fov` | number | No | Override the shot type's field of view (establishing 55, eye\_level 60/75, low\_angle 60 then widened, detail 40, corridor 60/75). |
| `aspect` | number | No | Frame width/height (default 1.7778 = 16:9). Every tile uses it. |
| `occluders` | object | No | Override the occluder classification. Default: path names (wall/house/terrain... = hard; tree/fence/lamp/prop/pipe... = soft), MultiMesh = soft, else size (\<= 2.5 m = soft). The caption reports the counts by rule. |
| `occluders.hard` | string\[] | No | Path prefixes that must never block the view (walls, terrain): a pose they block is rejected. |
| `occluders.soft` | string\[] | No | Path prefixes that may sit in front as framing (foliage, fences, props). |
| `occluders.ignore` | string\[] | No | Path prefixes left out of the visibility pass entirely. |
| `occluders.hard_layers` | integer | No | Physics layer mask: geometry whose nearest CollisionObject3D is on these layers is hard. |
| `occluders.soft_layers` | integer | No | Physics layer mask for soft geometry. |
| `max_soft_fraction` | number | No | Most of the subject that soft geometry may cover before a pose is rejected (0..1, default 0.67). |
| `bookmark_name` | string | No | Name for the saved best pose (default \<shot>\_\<subject leaf>). |
| `save_bookmark` | boolean | No | Save the best pose as a camera bookmark (default true). |
| `render` | "sheet" \| "best" \| "none" | No | "sheet" (default): the top 3 in one labelled grid with real lighting; "best": the winner only; "none": scores only. |
| `max_size` | integer | No | Longest edge of the returned JPEG in pixels (default 1536). Bigger costs more context; up to 4096 for detail work on a PC. Range 64 to 4096. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to look at, e.g. \"res://levels/town.tscn\" (the SAVED file). Omit for the scene open in the editor."
      },
      "shot": {
        "type": "string",
        "enum": [
          "establishing",
          "eye_level",
          "low_angle",
          "detail",
          "corridor"
        ],
        "description": "\"establishing\" (wide, whole subject, 12-40 deg up; a pose showing more than 15% empty ground or world edge ranks below every pose showing less), \"eye_level\" (player eye at spawn: its Camera3D kept inside 1.5-1.8 m, or eye_height, above the walkable surface under the camera), \"low_angle\" (hero, camera near the ground looking up), \"detail\" (close-up), \"corridor\" (down a lane/corridor inside the subject, found by a free-space scan, at eye height; prefers looking in from its open end). Eye-level and corridor cameras are never raised: a pose that cannot stand at eye height moves horizontally or is rejected. Every top pose states its camera height above the surface below it and its absolute y."
      },
      "subject": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "maxItems": 8,
        "description": "Node paths to frame (required except for eye_level, where it is what the player looks at)."
      },
      "spawn": {
        "type": "string",
        "description": "eye_level only: node the player stands at, e.g. the player or a spawn marker. Its own geometry never counts as an occluder."
      },
      "eye_height": {
        "type": "number",
        "description": "eye_level/corridor: exact camera height in metres above the walkable surface under the camera (default: 1.6; an eye_level spawn's own Camera3D keeps its height clamped into 1.5-1.8)."
      },
      "fov": {
        "type": "number",
        "description": "Override the shot type's field of view (establishing 55, eye_level 60/75, low_angle 60 then widened, detail 40, corridor 60/75)."
      },
      "aspect": {
        "type": "number",
        "description": "Frame width/height (default 1.7778 = 16:9). Every tile uses it."
      },
      "occluders": {
        "type": "object",
        "properties": {
          "hard": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Path prefixes that must never block the view (walls, terrain): a pose they block is rejected."
          },
          "soft": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Path prefixes that may sit in front as framing (foliage, fences, props)."
          },
          "ignore": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Path prefixes left out of the visibility pass entirely."
          },
          "hard_layers": {
            "type": "integer",
            "description": "Physics layer mask: geometry whose nearest CollisionObject3D is on these layers is hard."
          },
          "soft_layers": {
            "type": "integer",
            "description": "Physics layer mask for soft geometry."
          }
        },
        "additionalProperties": false,
        "description": "Override the occluder classification. Default: path names (wall/house/terrain... = hard; tree/fence/lamp/prop/pipe... = soft), MultiMesh = soft, else size (<= 2.5 m = soft). The caption reports the counts by rule."
      },
      "max_soft_fraction": {
        "type": "number",
        "description": "Most of the subject that soft geometry may cover before a pose is rejected (0..1, default 0.67)."
      },
      "bookmark_name": {
        "type": "string",
        "description": "Name for the saved best pose (default <shot>_<subject leaf>)."
      },
      "save_bookmark": {
        "type": "boolean",
        "description": "Save the best pose as a camera bookmark (default true)."
      },
      "render": {
        "type": "string",
        "enum": [
          "sheet",
          "best",
          "none"
        ],
        "description": "\"sheet\" (default): the top 3 in one labelled grid with real lighting; \"best\": the winner only; \"none\": scores only."
      },
      "max_size": {
        "type": "integer",
        "minimum": 64,
        "maximum": 4096,
        "description": "Longest edge of the returned JPEG in pixels (default 1536). Bigger costs more context; up to 4096 for detail work on a PC."
      }
    },
    "required": [
      "shot"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Find camera poses for a shot

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_frame_shot",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine frame-shot
  ```
</CodeGroup>

***

### game\_control

`engine.game_control`: **Control the game clock**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Pause or resume the RUNNING game, step exactly N frames, set the time scale, or list the live game instances. Step between two engine.game\_probe reads for exact checks.

| | |
| - | - |
| **MCP** | `summer_game_control` in the npm MCP |
| **CLI** | `summer engine game-control` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_game_control` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `action` | "pause" \| "resume" \| "step" \| "speed" \| "instances" | Yes | 'pause' suspends the game (Engine time frozen, physics inactive); 'resume' lifts the suspension; 'step' advances exactly N frames and leaves the game suspended; 'speed' sets the user time scale; 'instances' lists the live game instances (main + offscreen). |
| `frames` | integer | No | action step — frames to advance, 1..600 (default 1). |
| `kind` | "physics" \| "process" | No | action step — 'physics' (default, exact physics ticks) or 'process' (rendered frames). |
| `speed` | number | No | action speed — user time scale in (0, 100]. 0.25 = quarter speed, 2 = double. |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; ignored by action instances. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": [
          "pause",
          "resume",
          "step",
          "speed",
          "instances"
        ],
        "description": "'pause' suspends the game (Engine time frozen, physics inactive); 'resume' lifts the suspension; 'step' advances exactly N frames and leaves the game suspended; 'speed' sets the user time scale; 'instances' lists the live game instances (main + offscreen)."
      },
      "frames": {
        "type": "integer",
        "description": "action step — frames to advance, 1..600 (default 1)."
      },
      "kind": {
        "type": "string",
        "enum": [
          "physics",
          "process"
        ],
        "description": "action step — 'physics' (default, exact physics ticks) or 'process' (rendered frames)."
      },
      "speed": {
        "type": "number",
        "description": "action speed — user time scale in (0, 100]. 0.25 = quarter speed, 2 = double."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; ignored by action instances."
      }
    },
    "required": [
      "action"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Control the game clock

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_game_control",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine game-control
  ```
</CodeGroup>

***

### game\_input

`engine.game_input`: **Send input to the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Drive the RUNNING game's input: a script of timed actions, keys and clicks, or record real input and replay it on a seeded instance. Input is an action: prove its effect with engine.game\_probe.

| | |
| - | - |
| **MCP** | `summer_game_input` in the npm MCP |
| **CLI** | `summer engine game-input` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_game_input` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `action` | "script" \| "record\_start" \| "record\_stop" \| "replay" | Yes | 'script' schedules a timed sequence of synthetic inputs (SimulateInputScript); 'record\_start'/'record\_stop' capture the game's real input into res\://.summer/replays/\<id>.json; 'replay' plays a recording (or inline events) back. |
| `events` | object\[] | No | action script (required) or replay (instead of recording) — up to 1000 timed events; last event within 36000 frames / 600 s. |
| `events[].at_frame` | integer | No | When to fire, in frames after scheduling (clock frame). Default 0 = the next frame. |
| `events[].at_ms` | integer | No | When to fire, in milliseconds after scheduling (clock ms); exact only on an instance with fixed\_fps. |
| `events[].type` | "action" \| "key" \| "mouse\_click" \| "axis" \| "raw" | Yes | 'action' = InputMap action press/release; 'key' = keycode; 'mouse\_click' = click at a position; 'axis' = analog strength between two actions; 'raw' = a recorded InputEvent replayed as \{class, props}. |
| `events[].action` | string | No | type action — InputMap action name (unknown\_action if not bound). |
| `events[].pressed` | boolean | No | type action\|key — press (default true) or release. |
| `events[].strength` | number | No | type action — press strength 0..1 (default 1). type axis — signed strength; negative selects action\_negative. |
| `events[].hold_ms` | integer | No | type action\|key — auto-release after this many ms (0 = stays pressed until a release event). |
| `events[].keycode` | integer | No | type key — Godot Key enum value (e.g. 32 = Space). |
| `events[].physical_keycode` | integer | No | type key — physical Key enum value (alternative to keycode). |
| `events[].position` | number\[] | No | type mouse\_click — \[x, y] in window pixels. Items 2 to 2. |
| `events[].button` | integer | No | type mouse\_click — MouseButton (1 = left, 2 = right, 3 = middle). |
| `events[].action_negative` | string | No | type axis — action for negative strength (e.g. 'move\_left'). |
| `events[].action_positive` | string | No | type axis — action for positive strength (e.g. 'move\_right'). |
| `events[].duration_ms` | integer | No | type axis — auto-release after this many ms. |
| `events[].class` | string | No | type raw — InputEvent class to instantiate (e.g. 'InputEventKey'). |
| `events[].props` | object | No | type raw — properties set on the instantiated event. |
| `clock` | "frame" \| "ms" | No | action script — whether at\_frame ('frame', default, exact) or at\_ms ('ms') schedules the events. |
| `wait` | boolean | No | action script\|replay — wait for the last event to fire (default true; the engine caps a waited script at 20 s). Longer scripts use wait false and observe with summer\_game\_probe. |
| `include_motion` | boolean | No | action record\_start — also record mouse/joypad motion events (default false; large). |
| `save_as` | string | No | action record\_stop — res\://.summer/replays/\<name>.json to write instead of a generated id. |
| `recording` | string | No | action replay — the res\://.summer/replays/\<id>.json path returned by record\_stop. |
| `seed` | integer | No | action replay — assert the replay is reproducible; only accepted on an instance started with summer\_play mode offscreen + deterministic true (else nondeterministic\_instance). |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; summer\_game\_control action 'instances' lists them. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": [
          "script",
          "record_start",
          "record_stop",
          "replay"
        ],
        "description": "'script' schedules a timed sequence of synthetic inputs (SimulateInputScript); 'record_start'/'record_stop' capture the game's real input into res://.summer/replays/<id>.json; 'replay' plays a recording (or inline events) back."
      },
      "events": {
        "type": "array",
        "description": "action script (required) or replay (instead of recording) — up to 1000 timed events; last event within 36000 frames / 600 s.",
        "items": {
          "type": "object",
          "properties": {
            "at_frame": {
              "type": "integer",
              "description": "When to fire, in frames after scheduling (clock frame). Default 0 = the next frame."
            },
            "at_ms": {
              "type": "integer",
              "description": "When to fire, in milliseconds after scheduling (clock ms); exact only on an instance with fixed_fps."
            },
            "type": {
              "type": "string",
              "enum": [
                "action",
                "key",
                "mouse_click",
                "axis",
                "raw"
              ],
              "description": "'action' = InputMap action press/release; 'key' = keycode; 'mouse_click' = click at a position; 'axis' = analog strength between two actions; 'raw' = a recorded InputEvent replayed as {class, props}."
            },
            "action": {
              "type": "string",
              "description": "type action — InputMap action name (unknown_action if not bound)."
            },
            "pressed": {
              "type": "boolean",
              "description": "type action|key — press (default true) or release."
            },
            "strength": {
              "type": "number",
              "description": "type action — press strength 0..1 (default 1). type axis — signed strength; negative selects action_negative."
            },
            "hold_ms": {
              "type": "integer",
              "description": "type action|key — auto-release after this many ms (0 = stays pressed until a release event)."
            },
            "keycode": {
              "type": "integer",
              "description": "type key — Godot Key enum value (e.g. 32 = Space)."
            },
            "physical_keycode": {
              "type": "integer",
              "description": "type key — physical Key enum value (alternative to keycode)."
            },
            "position": {
              "type": "array",
              "items": {
                "type": "number"
              },
              "minItems": 2,
              "maxItems": 2,
              "description": "type mouse_click — [x, y] in window pixels."
            },
            "button": {
              "type": "integer",
              "description": "type mouse_click — MouseButton (1 = left, 2 = right, 3 = middle)."
            },
            "action_negative": {
              "type": "string",
              "description": "type axis — action for negative strength (e.g. 'move_left')."
            },
            "action_positive": {
              "type": "string",
              "description": "type axis — action for positive strength (e.g. 'move_right')."
            },
            "duration_ms": {
              "type": "integer",
              "description": "type axis — auto-release after this many ms."
            },
            "class": {
              "type": "string",
              "description": "type raw — InputEvent class to instantiate (e.g. 'InputEventKey')."
            },
            "props": {
              "type": "object",
              "description": "type raw — properties set on the instantiated event."
            }
          },
          "required": [
            "type"
          ],
          "additionalProperties": false
        }
      },
      "clock": {
        "type": "string",
        "enum": [
          "frame",
          "ms"
        ],
        "description": "action script — whether at_frame ('frame', default, exact) or at_ms ('ms') schedules the events."
      },
      "wait": {
        "type": "boolean",
        "description": "action script|replay — wait for the last event to fire (default true; the engine caps a waited script at 20 s). Longer scripts use wait false and observe with summer_game_probe."
      },
      "include_motion": {
        "type": "boolean",
        "description": "action record_start — also record mouse/joypad motion events (default false; large)."
      },
      "save_as": {
        "type": "string",
        "description": "action record_stop — res://.summer/replays/<name>.json to write instead of a generated id."
      },
      "recording": {
        "type": "string",
        "description": "action replay — the res://.summer/replays/<id>.json path returned by record_stop."
      },
      "seed": {
        "type": "integer",
        "description": "action replay — assert the replay is reproducible; only accepted on an instance started with summer_play mode offscreen + deterministic true (else nondeterministic_instance)."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; summer_game_control action 'instances' lists them."
      }
    },
    "required": [
      "action"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Send input to the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_game_input",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine game-input
  ```
</CodeGroup>

***

### game\_probe

`engine.game_probe`: **Probe the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read state and pixels of one frame of the RUNNING game together: the live tree, property values and a screenshot stamped with the same frame numbers. The evidence read of a playtest.

| | |
| - | - |
| **MCP** | `summer_game_probe` in the npm MCP |
| **CLI** | `summer engine game-probe` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_game_probe` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `tree` | object | No | Include the live scene tree (\{name, class, path, children}) built game-side on the SAME frame as the pixels. Omit for no tree. |
| `tree.path` | string | No | Subtree root, ABSOLUTE runtime path (default the scene tree root). |
| `tree.depth` | integer | No | Depth to walk, 1..8 (default 2). |
| `tree.limit` | integer | No | Node cap, 1..4000 (default 200); truncated is reported. |
| `props` | string\[] | No | Up to 64 '\<absolute path>:\<property>' keys read on the same frame, e.g. '/root/Main/Player:position'. Values come back as Godot literal strings; misses land in missing. |
| `screenshot` | boolean | No | Capture the game viewport (default true). false = state only, cheaper and works when the window draws nothing. |
| `max_dim` | integer | No | Longest image side in pixels, 16..4096 (default 1280); the frame is downscaled to fit. |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; summer\_game\_control action 'instances' lists them. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "tree": {
        "type": "object",
        "description": "Include the live scene tree ({name, class, path, children}) built game-side on the SAME frame as the pixels. Omit for no tree.",
        "properties": {
          "path": {
            "type": "string",
            "description": "Subtree root, ABSOLUTE runtime path (default the scene tree root)."
          },
          "depth": {
            "type": "integer",
            "description": "Depth to walk, 1..8 (default 2)."
          },
          "limit": {
            "type": "integer",
            "description": "Node cap, 1..4000 (default 200); truncated is reported."
          }
        },
        "additionalProperties": false
      },
      "props": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "Up to 64 '<absolute path>:<property>' keys read on the same frame, e.g. '/root/Main/Player:position'. Values come back as Godot literal strings; misses land in missing."
      },
      "screenshot": {
        "type": "boolean",
        "description": "Capture the game viewport (default true). false = state only, cheaper and works when the window draws nothing."
      },
      "max_dim": {
        "type": "integer",
        "description": "Longest image side in pixels, 16..4096 (default 1280); the frame is downscaled to fit."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; summer_game_control action 'instances' lists them."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Probe the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_game_probe",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine game-probe
  ```
</CodeGroup>

***

### get\_console

`engine.get_console`: **Read the editor console**

Read recent editor Output messages, collapsed and filtered (errors and warnings by default; errors\_only false for print output). A played game's runtime errors are not here: read engine.get\_diagnostics first.

| | |
| - | - |
| **MCP** | `summer_get_console` in the npm MCP |
| **CLI** | `summer engine get-console` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_console` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `max_lines` | number | No | Max lines to return after dedupe (default 100) Default `100`. |
| `filter` | string | No | Only return lines containing this string |
| `type` | "error" \| "warning" \| "std" \| "editor" | No | Filter by message type at the engine level |
| `errors_only` | boolean | No | Drop info/std noise, keep errors and warnings (default true) Default `true`. |
| `strict_errors` | boolean | No | Drop warnings too — return errors only Default `false`. |
| `raw` | boolean | No | Bypass dedupe and level filtering — return engine output verbatim Default `false`. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "max_lines": {
        "type": "number",
        "default": 100,
        "description": "Max lines to return after dedupe (default 100)"
      },
      "filter": {
        "type": "string",
        "description": "Only return lines containing this string"
      },
      "type": {
        "type": "string",
        "enum": [
          "error",
          "warning",
          "std",
          "editor"
        ],
        "description": "Filter by message type at the engine level"
      },
      "errors_only": {
        "type": "boolean",
        "default": true,
        "description": "Drop info/std noise, keep errors and warnings (default true)"
      },
      "strict_errors": {
        "type": "boolean",
        "default": false,
        "description": "Drop warnings too — return errors only"
      },
      "raw": {
        "type": "boolean",
        "default": false,
        "description": "Bypass dedupe and level filtering — return engine output verbatim"
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read the editor console

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_console",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-console
  ```
</CodeGroup>

***

### get\_debugger\_errors

`engine.get_debugger_errors`: **Read runtime errors**

Read the played game's runtime errors from the debugger (null references, missing nodes, physics errors), collapsed, with call stacks on request. After a fix, read engine.get\_diagnostics again.

| | |
| - | - |
| **MCP** | `summer_get_debugger_errors` in the npm MCP |
| **CLI** | `summer engine get-debugger-errors` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_debugger_errors` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `max_errors` | number | No | Max errors to return after dedupe Default `50`. |
| `include_stack` | boolean | No | Include stack traces for each error |
| `include_warnings` | boolean | No | Forward-compat flag — when engine supports it, returns warning bodies in the same call. Today the engine ignores it; use summer\_get\_debugger\_warnings instead. Default `false`. |
| `raw` | boolean | No | Bypass dedupe — return engine output verbatim Default `false`. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "max_errors": {
        "type": "number",
        "default": 50,
        "description": "Max errors to return after dedupe"
      },
      "include_stack": {
        "type": "boolean",
        "description": "Include stack traces for each error"
      },
      "include_warnings": {
        "type": "boolean",
        "default": false,
        "description": "Forward-compat flag — when engine supports it, returns warning bodies in the same call. Today the engine ignores it; use summer_get_debugger_warnings instead."
      },
      "raw": {
        "type": "boolean",
        "default": false,
        "description": "Bypass dedupe — return engine output verbatim"
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read runtime errors

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_debugger_errors",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-debugger-errors
  ```
</CodeGroup>

***

### get\_debugger\_warnings

`engine.get_debugger_warnings`: **Read runtime warnings**

Read the played game's runtime warnings from the debugger, with file, line and call stack.

| | |
| - | - |
| **MCP** | `summer_get_debugger_warnings` in the npm MCP |
| **CLI** | `summer engine get-debugger-warnings` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_debugger_warnings` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `max_warnings` | number | No | Max warnings to return after dedupe Default `50`. |
| `include_stack` | boolean | No | Include stack traces Default `true`. |
| `raw` | boolean | No | Bypass dedupe Default `false`. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "max_warnings": {
        "type": "number",
        "default": 50,
        "description": "Max warnings to return after dedupe"
      },
      "include_stack": {
        "type": "boolean",
        "default": true,
        "description": "Include stack traces"
      },
      "raw": {
        "type": "boolean",
        "default": false,
        "description": "Bypass dedupe"
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read runtime warnings

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_debugger_warnings",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-debugger-warnings
  ```
</CodeGroup>

***

### get\_diagnostics

`engine.get_diagnostics`: **Read errors and warnings**

Read the editor console, the runtime debugger and script errors together, with complete counts and errors first. The first read after a change and after play. Next: engine.get\_debugger\_errors or engine.get\_console for the details.

| | |
| - | - |
| **MCP** | `summer_get_diagnostics` in the npm MCP |
| **CLI** | `summer engine get-diagnostics` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_diagnostics` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `includeAll` | boolean | No | Return the full engine diagnostics payload untrimmed (no severity reordering, no info-noise cap). Default `false`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "includeAll": {
        "type": "boolean",
        "default": false,
        "description": "Return the full engine diagnostics payload untrimmed (no severity reordering, no info-noise cap)."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read errors and warnings

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_diagnostics",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-diagnostics
  ```
</CodeGroup>

***

### get\_project\_context

`engine.get_project_context`: **Read the project context**

Bind this session to the project open in Summer Engine and read it: project, current and main scene, engine health, project memory and warnings. Call it first in every chat; the scene tree and settings come on request (include). Next: engine.get\_scene\_tree.

| | |
| - | - |
| **MCP** | `summer_get_project_context` in the npm MCP |
| **CLI** | `summer engine get-project-context` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_project_context` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `include` | "scene\_tree" \| "capabilities" \| "settings"\[] | No | Heavy blocks to add to the compact default: 'scene\_tree' (the open scene's node tree, up to 200 nodes), 'capabilities' (the engine's full op/capability lists), 'settings' (project settings, curated groups). settingsPrefix/settingsPrefixes imply 'settings'. Items 0 to 3. |
| `settingsPrefix` | string | No | Only return project settings whose key starts with this prefix, e.g. 'audio/' or 'application/config/'. Omit for the curated default set. |
| `settingsPrefixes` | string\[] | No | Several settings groups at once, e.g. \['audio/', 'layer\_names/2d\_physics/', 'input/ui\_']. Merged with settingsPrefix. Omit for the curated default set. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "include": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "scene_tree",
            "capabilities",
            "settings"
          ]
        },
        "maxItems": 3,
        "description": "Heavy blocks to add to the compact default: 'scene_tree' (the open scene's node tree, up to 200 nodes), 'capabilities' (the engine's full op/capability lists), 'settings' (project settings, curated groups). settingsPrefix/settingsPrefixes imply 'settings'."
      },
      "settingsPrefix": {
        "type": "string",
        "description": "Only return project settings whose key starts with this prefix, e.g. 'audio/' or 'application/config/'. Omit for the curated default set."
      },
      "settingsPrefixes": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "Several settings groups at once, e.g. ['audio/', 'layer_names/2d_physics/', 'input/ui_']. Merged with settingsPrefix. Omit for the curated default set."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read the project context

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_project_context",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-project-context
  ```
</CodeGroup>

***

### get\_runtime\_tree

`engine.get_runtime_tree`: **Read the running game's tree**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read the node tree of the RUNNING game: spawned enemies, autoloads and pooled nodes that editor reads never show. Needs a running game. Next: engine.inspect\_runtime\_node.

| | |
| - | - |
| **MCP** | `summer_get_runtime_tree` in the npm MCP |
| **CLI** | `summer engine get-runtime-tree` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_runtime_tree` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | No | Subtree root to read, e.g. '/root/Main/Enemies'. Omit for the scene tree root. |
| `depth` | integer | No | Maximum depth to walk (engine default 3). |
| `limit` | integer | No | Maximum nodes to return (engine default 500). |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Subtree root to read, e.g. '/root/Main/Enemies'. Omit for the scene tree root."
      },
      "depth": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Maximum depth to walk (engine default 3)."
      },
      "limit": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Maximum nodes to return (engine default 500)."
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read the running game's tree

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_runtime_tree",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-runtime-tree
  ```
</CodeGroup>

***

### get\_scene\_tree

`engine.get_scene_tree`: **Read a scene's node tree**

Read the node tree of a scene: names, types and paths. Pass scenePath for an exact scene and depth for deep trees; the engine stops at depth 2 and 200 nodes by default and says truncated. Next: engine.inspect\_node.

| | |
| - | - |
| **MCP** | `summer_get_scene_tree` in the npm MCP |
| **CLI** | `summer engine get-scene-tree` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_scene_tree` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Exact res\:// scene path to inspect |
| `depth` | integer | No | Maximum tree depth to walk. Engine default is 2 — pass a larger value for deep hierarchies. |
| `limit` | integer | No | Maximum number of nodes to return. Engine default is 200. |
| `maxCharacters` | integer | No | Most characters of text to return (default 8000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Exact res:// scene path to inspect"
      },
      "depth": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Maximum tree depth to walk. Engine default is 2 — pass a larger value for deep hierarchies."
      },
      "limit": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Maximum number of nodes to return. Engine default is 200."
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 8000). A longer result is cut and says so."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read a scene's node tree

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_scene_tree",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-scene-tree
  ```
</CodeGroup>

***

### get\_script\_errors

`engine.get_script_errors`: **Check a script for errors**

Check one GDScript file for parse and compile errors without running the game: line, message and severity of each. The first check after writing a script.

| | |
| - | - |
| **MCP** | `summer_get_script_errors` in the npm MCP |
| **CLI** | `summer engine get-script-errors` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_get_script_errors` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Script path, e.g. 'res\://scripts/player.gd' or 'res\://player\_controller.gd' |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Script path, e.g. 'res://scripts/player.gd' or 'res://player_controller.gd'"
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Check a script for errors

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_get_script_errors",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine get-script-errors
  ```
</CodeGroup>

***

### grep

`engine.grep`: **Search project files**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Search project files with a regular expression: file, line and text of each match, with optional context lines and a result cap. Then read the part you need with engine.read\_file.

| | |
| - | - |
| **MCP** | `summer_grep` in the npm MCP |
| **CLI** | `summer engine grep` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_grep` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `pattern` | string | Yes | Ripgrep regular expression, e.g. '"fits\_into"' or 'func \_on\_.\*\_pressed' Length 1 to …. |
| `path` | string | No | Search scope: a res\:// directory or file, e.g. 'res\://kit/' or 'res\://kit/kit\_manifest.json'. Default: the whole project. |
| `glob` | string | No | File filter passed to ripgrep --glob, e.g. '\*.gd', '\*\*/\*.json', '!addons/\*\*'. A glob also reaches files .gitignore would skip. |
| `case_sensitive` | boolean | No | Match case exactly (default false: case-insensitive). |
| `context_lines` | integer | No | Lines of context before and after each match (0-10, default 0). Range 0 to 10. |
| `max_results` | integer | No | Most matches to return (default 50, max 500). truncated:true means there were more. Range … to 500. |
| `max_line_chars` | integer | No | Clip every returned line to this many characters (default 240). Range 40 to 2000. |
| `multiline` | boolean | No | Let the pattern span lines (ripgrep -U --multiline-dotall). |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "pattern": {
        "type": "string",
        "minLength": 1,
        "description": "Ripgrep regular expression, e.g. '\"fits_into\"' or 'func _on_.*_pressed'"
      },
      "path": {
        "type": "string",
        "description": "Search scope: a res:// directory or file, e.g. 'res://kit/' or 'res://kit/kit_manifest.json'. Default: the whole project."
      },
      "glob": {
        "type": "string",
        "description": "File filter passed to ripgrep --glob, e.g. '*.gd', '**/*.json', '!addons/**'. A glob also reaches files .gitignore would skip."
      },
      "case_sensitive": {
        "type": "boolean",
        "description": "Match case exactly (default false: case-insensitive)."
      },
      "context_lines": {
        "type": "integer",
        "minimum": 0,
        "maximum": 10,
        "description": "Lines of context before and after each match (0-10, default 0)."
      },
      "max_results": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "maximum": 500,
        "description": "Most matches to return (default 50, max 500). truncated:true means there were more."
      },
      "max_line_chars": {
        "type": "integer",
        "minimum": 40,
        "maximum": 2000,
        "description": "Clip every returned line to this many characters (default 240)."
      },
      "multiline": {
        "type": "boolean",
        "description": "Let the pattern span lines (ripgrep -U --multiline-dotall)."
      }
    },
    "required": [
      "pattern"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Search project files

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_grep",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine grep
  ```
</CodeGroup>

***

### import\_asset

`engine.import_asset`: **Find and import a Summer asset**

Search the Summer asset library, import the best match into the project and, for a 3D model, add it to a scene. Needs the Summer sign-in. For an exact asset use engine.import\_asset\_by\_id.

| | |
| - | - |
| **MCP** | `summer_import_asset` in the npm MCP |
| **CLI** | `summer engine import-asset` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_import_asset` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `query` | string | Yes | What to find, e.g. 'low-poly tree', 'wooden crate' |
| `parent` | string | No | Parent node path to add the asset under, e.g. `./World`. If omitted, only imports (no scene placement) |
| `scenePath` | string | No | Required with parent. Exact res\:// target scene path. |
| `assetType` | "2d\_image" \| "animation" \| "3d\_model" \| "audio" \| "music" \| "all" | No | Preferred asset type Default `"3d_model"`. |
| `source` | "library" \| "my\_assets" \| "all" | No | Where to search before importing Default `"all"`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "What to find, e.g. 'low-poly tree', 'wooden crate'"
      },
      "parent": {
        "type": "string",
        "description": "Parent node path to add the asset under, e.g. './World'. If omitted, only imports (no scene placement)"
      },
      "scenePath": {
        "type": "string",
        "description": "Required with parent. Exact res:// target scene path."
      },
      "assetType": {
        "type": "string",
        "enum": [
          "2d_image",
          "animation",
          "3d_model",
          "audio",
          "music",
          "all"
        ],
        "default": "3d_model",
        "description": "Preferred asset type"
      },
      "source": {
        "type": "string",
        "enum": [
          "library",
          "my_assets",
          "all"
        ],
        "default": "all",
        "description": "Where to search before importing"
      }
    },
    "required": [
      "query"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Find and import a Summer asset

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_import_asset",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine import-asset
  ```
</CodeGroup>

***

### import\_asset\_by\_id

`engine.import_asset_by_id`: **Import a Summer asset by id**

Import one Summer asset by its id (from a search, the person's assets or a generation) into the project; a 3D model can go straight into the scene at scenePath. Needs the Summer sign-in.

| | |
| - | - |
| **MCP** | `summer_import_asset_by_id` in the npm MCP |
| **CLI** | `summer engine import-asset-by-id` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_import_asset_by_id` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `assetId` | string | Yes | Summer ArtAssets id |
| `path` | string | No | Optional target res\:// path. If omitted, a path is inferred from asset type and filename. |
| `parent` | string | No | Optional parent node path. For 3D models only; imports and instantiates under this node. |
| `scenePath` | string | No | Required with parent. Exact res\:// scene that receives the 3D model. |
| `name` | string | No | Optional scene node name when parent is provided. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "assetId": {
        "type": "string",
        "description": "Summer ArtAssets id"
      },
      "path": {
        "type": "string",
        "description": "Optional target res:// path. If omitted, a path is inferred from asset type and filename."
      },
      "parent": {
        "type": "string",
        "description": "Optional parent node path. For 3D models only; imports and instantiates under this node."
      },
      "scenePath": {
        "type": "string",
        "description": "Required with parent. Exact res:// scene that receives the 3D model."
      },
      "name": {
        "type": "string",
        "description": "Optional scene node name when parent is provided."
      }
    },
    "required": [
      "assetId"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Import a Summer asset by id

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_import_asset_by_id",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine import-asset-by-id
  ```
</CodeGroup>

***

### import\_from\_url

`engine.import_from_url`: **Import a file from a URL**

Download one file (model, texture, audio) from a URL into the project and run the import, so it is ready to use. For a model, next: engine.instantiate\_scene.

| | |
| - | - |
| **MCP** | `summer_import_from_url` in the npm MCP |
| **CLI** | `summer engine import-from-url` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_import_from_url` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `url` | string | Yes | HTTP(S) URL to download from |
| `path` | string | No | Target path in project, e.g. 'res\://assets/player.glb'. Auto-inferred from URL if omitted. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "url": {
        "type": "string",
        "description": "HTTP(S) URL to download from"
      },
      "path": {
        "type": "string",
        "description": "Target path in project, e.g. 'res://assets/player.glb'. Auto-inferred from URL if omitted."
      }
    },
    "required": [
      "url"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Import a file from a URL

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_import_from_url",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine import-from-url
  ```
</CodeGroup>

***

### import\_from\_url\_batch

`engine.import_from_url_batch`: **Import files from URLs**

Download several files from URLs into the project in one call, with one import scan at the end.

| | |
| - | - |
| **MCP** | `summer_import_from_url_batch` in the npm MCP |
| **CLI** | `summer engine import-from-url-batch` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_import_from_url_batch` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `imports` | object\[] | Yes | Array of \{url, path} objects |
| `imports[].url` | string | Yes | URL to download |
| `imports[].path` | string | Yes | Target path in project |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "imports": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "url": {
              "type": "string",
              "description": "URL to download"
            },
            "path": {
              "type": "string",
              "description": "Target path in project"
            }
          },
          "required": [
            "url",
            "path"
          ],
          "additionalProperties": false
        },
        "description": "Array of {url, path} objects"
      }
    },
    "required": [
      "imports"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Import files from URLs

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_import_from_url_batch",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine import-from-url-batch
  ```
</CodeGroup>

***

### import\_hdri

`engine.import_hdri`: **Import an HDRI sky**

Find a CC0 HDRI sky on Poly Haven (or take an exact id) and import it into res\://sky/ for environment light. Returns a ready engine.run\_script snippet that wires it into the WorldEnvironment.

| | |
| - | - |
| **MCP** | `summer_import_hdri` in the npm MCP |
| **CLI** | `summer engine import-hdri` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_import_hdri` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `query` | string | No | What kind of sky/environment, e.g. 'sunset beach', 'overcast field', 'studio'. Omit when assetId is given. |
| `assetId` | string | No | Exact Poly Haven asset id (lowercase slug, e.g. 'kloppenheim\_02'). Skips the search. |
| `resolution` | "1k" \| "2k" \| "4k" | No | HDRI resolution. 2k (default) is right for most games; 4k for hero skies; 1k for quick blockouts. Default `"2k"`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "What kind of sky/environment, e.g. 'sunset beach', 'overcast field', 'studio'. Omit when assetId is given."
      },
      "assetId": {
        "type": "string",
        "description": "Exact Poly Haven asset id (lowercase slug, e.g. 'kloppenheim_02'). Skips the search."
      },
      "resolution": {
        "type": "string",
        "enum": [
          "1k",
          "2k",
          "4k"
        ],
        "default": "2k",
        "description": "HDRI resolution. 2k (default) is right for most games; 4k for hero skies; 1k for quick blockouts."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Import an HDRI sky

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_import_hdri",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine import-hdri
  ```
</CodeGroup>

***

### input\_map\_bind

`engine.input_map_bind`: **Bind input to an action**

Create an input action when it is missing and bind keys or mouse buttons to it, for example jump to Space. Then try it with engine.play.

| | |
| - | - |
| **MCP** | `summer_input_map_bind` in the npm MCP |
| **CLI** | `summer engine input-map-bind` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_input_map_bind` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `name` | string | Yes | Action name, e.g. 'jump', 'move\_forward', 'interact' |
| `events` | object\[] | Yes | Array of input event objects |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Action name, e.g. 'jump', 'move_forward', 'interact'"
      },
      "events": {
        "type": "array",
        "items": {
          "type": "object",
          "additionalProperties": {}
        },
        "description": "Array of input event objects"
      }
    },
    "required": [
      "name",
      "events"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Bind input to an action

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_input_map_bind",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine input-map-bind
  ```
</CodeGroup>

***

### inspect\_asset

`engine.inspect_asset`: **Measure a 3D asset file**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Measure a 3D asset file without placing it: bounds, origin, meshes, largest flat faces, open pipe ends, Marker3D anchors and collision shapes. Measure each kit piece once before placing it. Next: engine.instantiate\_scene.

| | |
| - | - |
| **MCP** | `summer_inspect_asset` in the npm MCP |
| **CLI** | `summer engine inspect-asset` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_inspect_asset` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Asset to measure, e.g. 'res\://kit/facade/wall\_single\_01.tscn' (.tscn, .scn, .glb, .gltf, .res, .tres, .mesh or .obj). Loaded and instanced off-scene, never added to an open scene. Length 1 to 512. |
| `maxTriangles` | integer | No | Triangle budget (100-300000) for the face and open-loop analysis (AABBs and counts are always complete). summary.warnings says when the budget cut the analysis and which budget covers the whole mesh. Default `60000`. Range 100 to 300000. |
| `detail` | "summary" \| "full" | No | summary: open\_loops lists only port-like loops (radius over 2 cm with a partner loop facing another way, or the one opening of an end piece on its bounding-box face), or none. full: every open loop, including the outline of flat sheets. Every loop has a stable id ('+Y', '+Y#2') that summer\_connect\_ports accepts. Both start with the summary block (AABB, origin, the two largest opposite plane pairs with one\_sided flags, port-like loop ids). Default `"summary"`. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Asset to measure, e.g. 'res://kit/facade/wall_single_01.tscn' (.tscn, .scn, .glb, .gltf, .res, .tres, .mesh or .obj). Loaded and instanced off-scene, never added to an open scene."
      },
      "maxTriangles": {
        "type": "integer",
        "minimum": 100,
        "maximum": 300000,
        "default": 60000,
        "description": "Triangle budget (100-300000) for the face and open-loop analysis (AABBs and counts are always complete). summary.warnings says when the budget cut the analysis and which budget covers the whole mesh."
      },
      "detail": {
        "type": "string",
        "enum": [
          "summary",
          "full"
        ],
        "default": "summary",
        "description": "summary: open_loops lists only port-like loops (radius over 2 cm with a partner loop facing another way, or the one opening of an end piece on its bounding-box face), or none. full: every open loop, including the outline of flat sheets. Every loop has a stable id ('+Y', '+Y#2') that summer_connect_ports accepts. Both start with the summary block (AABB, origin, the two largest opposite plane pairs with one_sided flags, port-like loop ids)."
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Measure a 3D asset file

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_inspect_asset",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine inspect-asset
  ```
</CodeGroup>

***

### inspect\_node

`engine.inspect_node`: **Read a node's properties**

Read one node of the open scene: every editable property with its value and type, or only the fields you name (transform, global\_transform, scene\_file\_path, aabb). Next: engine.set\_prop.

| | |
| - | - |
| **MCP** | `summer_inspect_node` in the npm MCP |
| **CLI** | `summer engine inspect-node` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_inspect_node` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Node path from scene tree, e.g. 'Player', 'World/Enemies/Boss', 'DirectionalLight3D' |
| `fields` | string\[] | No | Only these fields: property names or globs (e.g. 'position', 'surface\_material\_override/\*') and the derived fields transform, global\_transform, scene\_file\_path, aabb, warnings. Omit for every property. Items 0 to 48. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Node path from scene tree, e.g. 'Player', 'World/Enemies/Boss', 'DirectionalLight3D'"
      },
      "fields": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "maxItems": 48,
        "description": "Only these fields: property names or globs (e.g. 'position', 'surface_material_override/*') and the derived fields transform, global_transform, scene_file_path, aabb, warnings. Omit for every property."
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read a node's properties

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_inspect_node",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine inspect-node
  ```
</CodeGroup>

***

### inspect\_resource

`engine.inspect_resource`: **Read a resource**

Read a resource file (a mesh's bounds and surfaces, a scene's nodes, any resource's non-default properties) or a resource a node holds (nodePath and property). Next: engine.set\_resource\_property.

| | |
| - | - |
| **MCP** | `summer_inspect_resource` in the npm MCP |
| **CLI** | `summer engine inspect-resource` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_inspect_resource` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | No | A resource FILE, e.g. 'res\://materials/ground.tres', a mesh 'res\://kit/meshes/wall\_01.res', or a scene/model 'res\://models/player.glb'. Loaded read-only in the editor. Do not combine with nodePath. Length 1 to 512. |
| `nodePath` | string | No | With property, a node of the ACTIVE scene tab whose resource to read, e.g. 'Floor'. Length 1 to 256. |
| `property` | string | No | With nodePath, the node property holding the resource, e.g. 'mesh', 'material\_override', 'shape', 'environment'. Length 1 to 128. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "A resource FILE, e.g. 'res://materials/ground.tres', a mesh 'res://kit/meshes/wall_01.res', or a scene/model 'res://models/player.glb'. Loaded read-only in the editor. Do not combine with nodePath."
      },
      "nodePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "With property, a node of the ACTIVE scene tab whose resource to read, e.g. 'Floor'."
      },
      "property": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "description": "With nodePath, the node property holding the resource, e.g. 'mesh', 'material_override', 'shape', 'environment'."
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read a resource

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_inspect_resource",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine inspect-resource
  ```
</CodeGroup>

***

### inspect\_runtime\_node

`engine.inspect_runtime_node`: **Read a node in the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read the live properties of one node in the RUNNING game (transform, visibility, physics state...) without stopping it. Paths are absolute; take them from engine.get\_runtime\_tree.

| | |
| - | - |
| **MCP** | `summer_inspect_runtime_node` in the npm MCP |
| **CLI** | `summer engine inspect-runtime-node` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_inspect_runtime_node` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Runtime node path, e.g. '/root/Main/Player'. Get it from summer\_get\_runtime\_tree. |
| `maxCharacters` | integer | No | Most characters of text to return (default 4000). A longer result is cut and says so. Range 500 to 1000000. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Runtime node path, e.g. '/root/Main/Player'. Get it from summer_get_runtime_tree."
      },
      "maxCharacters": {
        "type": "integer",
        "minimum": 500,
        "maximum": 1000000,
        "description": "Most characters of text to return (default 4000). A longer result is cut and says so."
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read a node in the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_inspect_runtime_node",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine inspect-runtime-node
  ```
</CodeGroup>

***

### instantiate\_scene

`engine.instantiate_scene`: **Add a scene or model as a node**

Add an existing .tscn, .glb or .gltf as a child node in the scene at scenePath, placed in the same call (position, rotation\_degrees, scale or transform). Pass target\_size for imported models. Next: engine.screenshot.

| | |
| - | - |
| **MCP** | `summer_instantiate_scene` in the npm MCP |
| **CLI** | `summer engine instantiate-scene` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_instantiate_scene` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene to receive the instance, e.g. 'res\://main.tscn' |
| `parent` | string | Yes | Parent node path, e.g. `./World` |
| `scene` | string | Yes | Scene/model path, e.g. 'res\://player.tscn' or 'res\://models/tree.glb' |
| `name` | string | No | Override the instance name |
| `target_size` | number | No | Normalize the instance's physical size - uniformly scale it so its largest world-AABB dimension equals this many units (chair 1.0, car 4.5, person 1.7). Strongly recommended for imported .glb/.gltf models. Older engine builds ignore it; the result then lacks scale\_applied and carries a target\_size\_note. |
| `position` | number\[] | No | Parent-local position \[x, y, z], set right after the instance is created (on the node path its receipt reports). Items 3 to 3. |
| `rotation_degrees` | number\[] | No | Parent-local rotation in degrees \[x, y, z]. Items 3 to 3. |
| `scale` | number\[] | No | Local scale \[x, y, z]. Not with target\_size. Items 3 to 3. |
| `transform` | string | No | Full local transform as "Transform3D(xx, xy, xz, yx, yy, yz, zx, zy, zz, ox, oy, oz)". Not with position, rotation\_degrees, scale or target\_size. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene to receive the instance, e.g. 'res://main.tscn'"
      },
      "parent": {
        "type": "string",
        "description": "Parent node path, e.g. './World'"
      },
      "scene": {
        "type": "string",
        "description": "Scene/model path, e.g. 'res://player.tscn' or 'res://models/tree.glb'"
      },
      "name": {
        "type": "string",
        "description": "Override the instance name"
      },
      "target_size": {
        "type": "number",
        "exclusiveMinimum": 0,
        "description": "Normalize the instance's physical size - uniformly scale it so its largest world-AABB dimension equals this many units (chair 1.0, car 4.5, person 1.7). Strongly recommended for imported .glb/.gltf models. Older engine builds ignore it; the result then lacks scale_applied and carries a target_size_note."
      },
      "position": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Parent-local position [x, y, z], set right after the instance is created (on the node path its receipt reports)."
      },
      "rotation_degrees": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Parent-local rotation in degrees [x, y, z]."
      },
      "scale": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Local scale [x, y, z]. Not with target_size."
      },
      "transform": {
        "type": "string",
        "description": "Full local transform as \"Transform3D(xx, xy, xz, yx, yy, yz, zx, zy, zz, ox, oy, oz)\". Not with position, rotation_degrees, scale or target_size."
      }
    },
    "required": [
      "scenePath",
      "parent",
      "scene"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Add a scene or model as a node

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_instantiate_scene",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine instantiate-scene
  ```
</CodeGroup>

***

### invoke\_ui\_action

`engine.invoke_ui_action`: **Run an editor action**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Run one named editor action exactly as its menu item or shortcut would: open Project Settings, switch the main screen, toggle a panel. Editor work only; scene work is engine.run\_script. Read the effect back with engine.ui\_tree.

| | |
| - | - |
| **MCP** | `summer_engine_invoke_ui_action` in the npm MCP |
| **CLI** | `summer engine invoke-ui-action` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_ui_actions#invoke` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `action_name` | string | Yes | mode 'invoke' only (required there). The exact action name from a 'list' result — the stable shortcut path such as 'editor/project\_settings', 'editor/save\_scene', 'spatial\_editor/focus\_selection'. Palette-only commands are accepted too. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "action_name": {
        "type": "string",
        "description": "mode 'invoke' only (required there). The exact action name from a 'list' result — the stable shortcut path such as 'editor/project_settings', 'editor/save_scene', 'spatial_editor/focus_selection'. Palette-only commands are accepted too."
      }
    },
    "required": [
      "action_name"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Run an editor action

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_engine_invoke_ui_action",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine invoke-ui-action
  ```
</CodeGroup>

***

### is\_running

`engine.is_running`: **Check whether the game runs**

Check whether the game is running, and which scene it runs.

| | |
| - | - |
| **MCP** | `summer_is_running` in the npm MCP |
| **CLI** | `summer engine is-running` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_is_running` |

**Inputs:**

No inputs.

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Check whether the game runs

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_is_running",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine is-running
  ```
</CodeGroup>

***

### list\_camera\_bookmarks

`engine.list_camera_bookmarks`: **List camera bookmarks**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

List the camera viewpoints saved in this project: names, poses and dates. A bookmark gives screenshots that line up before and after a change: engine.screenshot with framing bookmark.

| | |
| - | - |
| **MCP** | `summer_engine_list_camera_bookmarks` in the npm MCP |
| **CLI** | `summer engine list-camera-bookmarks` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_camera_bookmark` |

**Inputs:**

No inputs.

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** List camera bookmarks

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_engine_list_camera_bookmarks",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine list-camera-bookmarks
  ```
</CodeGroup>

***

### list\_ui\_actions

`engine.list_ui_actions`: **List editor actions**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

List the editor's named actions (menu items and shortcuts) with labels and shortcuts, filtered by text. Actions marked denied are refused. Next: engine.invoke\_ui\_action.

| | |
| - | - |
| **MCP** | `summer_engine_list_ui_actions` in the npm MCP |
| **CLI** | `summer engine list-ui-actions` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_ui_actions` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `filter` | string | No | mode 'list' only. Case-insensitive substring over action name and label, e.g. 'project\_settings', 'save', 'spatial\_editor', 'bottom\_panel'. |
| `limit` | integer | No | mode 'list' only. Maximum actions returned (engine default 200, max 2000). The result carries total + truncated — never assume a capped list is complete. Range 1 to …. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "filter": {
        "type": "string",
        "description": "mode 'list' only. Case-insensitive substring over action name and label, e.g. 'project_settings', 'save', 'spatial_editor', 'bottom_panel'."
      },
      "limit": {
        "type": "integer",
        "minimum": 1,
        "description": "mode 'list' only. Maximum actions returned (engine default 200, max 2000). The result carries total + truncated — never assume a capped list is complete."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** List editor actions

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_engine_list_ui_actions",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine list-ui-actions
  ```
</CodeGroup>

***

### measure

`engine.measure`: **Measure between nodes**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Measure the gap or overlap on each axis between two placed nodes, or check that one face of many nodes lies on one plane. Finds facade gaps and modules that stand out. Changes nothing.

| | |
| - | - |
| **MCP** | `summer_measure` in the npm MCP |
| **CLI** | `summer engine measure` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_measure` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene, e.g. 'res\://levels/street.tscn'. It must be open in the editor (any tab). Length 1 to 512. |
| `mode` | "pair" \| "plane" | No | pair: gap or overlap per axis between nodes a and b. plane: whether one face of every node in nodes lies on one plane. Default `"pair"`. |
| `a` | string | No | pair mode, first node (exact path from the scene root). |
| `b` | string | No | pair mode, second node. |
| `axis` | "x" \| "y" \| "z" | No | pair mode, report only this axis. |
| `nodes` | string\[] | No | plane mode, 2-32 nodes whose face is checked. Items 2 to 32. |
| `face` | "+x" \| "-x" \| "+y" \| "-y" \| "+z" \| "-z" | No | plane mode, which face, e.g. '+z' for the face pointing along +z. |
| `space` | "world" \| "local" | No | world axes, or the axes of a (pair) / nodes\[0] (plane) for rotated facades. Default `"world"`. |
| `tolerance` | number | No | Distance treated as touching (pair) or coplanar (plane). Default 5 mm. Default `0.005`. Range 0 to 1. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene, e.g. 'res://levels/street.tscn'. It must be open in the editor (any tab)."
      },
      "mode": {
        "type": "string",
        "enum": [
          "pair",
          "plane"
        ],
        "default": "pair",
        "description": "pair: gap or overlap per axis between nodes a and b. plane: whether one face of every node in nodes lies on one plane."
      },
      "a": {
        "type": "string",
        "description": "pair mode, first node (exact path from the scene root)."
      },
      "b": {
        "type": "string",
        "description": "pair mode, second node."
      },
      "axis": {
        "type": "string",
        "enum": [
          "x",
          "y",
          "z"
        ],
        "description": "pair mode, report only this axis."
      },
      "nodes": {
        "type": "array",
        "minItems": 2,
        "maxItems": 32,
        "items": {
          "type": "string"
        },
        "description": "plane mode, 2-32 nodes whose face is checked."
      },
      "face": {
        "type": "string",
        "enum": [
          "+x",
          "-x",
          "+y",
          "-y",
          "+z",
          "-z"
        ],
        "description": "plane mode, which face, e.g. '+z' for the face pointing along +z."
      },
      "space": {
        "type": "string",
        "enum": [
          "world",
          "local"
        ],
        "default": "world",
        "description": "world axes, or the axes of a (pair) / nodes[0] (plane) for rotated facades."
      },
      "tolerance": {
        "type": "number",
        "minimum": 0,
        "maximum": 1,
        "default": 0.005,
        "description": "Distance treated as touching (pair) or coplanar (plane). Default 5 mm."
      }
    },
    "required": [
      "scenePath"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Measure between nodes

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_measure",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine measure
  ```
</CodeGroup>

***

### navigation\_probe

`engine.navigation_probe`: **Check a navigation route**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Check whether two world points are connected on the scene's navigation map: readiness, snapped end points, route length and route points. ready false means no evidence, not no route.

| | |
| - | - |
| **MCP** | `summer_navigation_probe` in the npm MCP |
| **CLI** | `summer engine navigation-probe` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_navigation_probe` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact 3D scene whose World3D navigation map should be queried. Length 1 to 512. |
| `start` | number\[] | Yes | Requested world-space route start \[x,y,z]. Items 3 to 3. |
| `end` | number\[] | Yes | Requested world-space route destination \[x,y,z]. Items 3 to 3. |
| `navigationLayers` | integer | No | Godot navigation-layer bitmask; only enabled matching regions are used. Default `1`. Range 1 to 4294967295. |
| `optimize` | boolean | No | Use Godot's corridor-funnel path post-processing; false uses edge-centered points. Default `true`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact 3D scene whose World3D navigation map should be queried."
      },
      "start": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 3,
        "maxItems": 3,
        "description": "Requested world-space route start [x,y,z]."
      },
      "end": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 3,
        "maxItems": 3,
        "description": "Requested world-space route destination [x,y,z]."
      },
      "navigationLayers": {
        "type": "integer",
        "minimum": 1,
        "maximum": 4294967295,
        "default": 1,
        "description": "Godot navigation-layer bitmask; only enabled matching regions are used."
      },
      "optimize": {
        "type": "boolean",
        "default": true,
        "description": "Use Godot's corridor-funnel path post-processing; false uses edge-centered points."
      }
    },
    "required": [
      "scenePath",
      "start",
      "end"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Check a navigation route

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_navigation_probe",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine navigation-probe
  ```
</CodeGroup>

***

### open\_main\_scene

`engine.open_main_scene`: **Open the main scene**

Open the project's main scene (from project settings) in the editor, instead of guessing a scene file name.

| | |
| - | - |
| **MCP** | `summer_open_main_scene` in the npm MCP |
| **CLI** | `summer engine open-main-scene` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_open_main_scene` |

**Inputs:**

No inputs.

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Open the main scene

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_open_main_scene",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine open-main-scene
  ```
</CodeGroup>

***

### open\_scene

`engine.open_scene`: **Open a scene in the editor**

Open a scene file in the editor and show its tab. A visible tab change for the person, not a target for edits: edits take scenePath. Take paths from engine.get\_project\_context; never guess them.

| | |
| - | - |
| **MCP** | `summer_open_scene` in the npm MCP |
| **CLI** | `summer engine open-scene` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_open_scene` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Scene path, e.g. 'res\://main.tscn' or 'res\://levels/level1.tscn' |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Scene path, e.g. 'res://main.tscn' or 'res://levels/level1.tscn'"
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Open a scene in the editor

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_open_scene",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine open-scene
  ```
</CodeGroup>

***

### place\_adjacent

`engine.place_adjacent`: **Place a node against another**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Move one node so its bounds face sits against another node's, lining up the other axes: modules edge to edge, storeys stacked. Saves the scene and verifies the gap.

| | |
| - | - |
| **MCP** | `summer_place_adjacent` in the npm MCP |
| **CLI** | `summer engine place-adjacent` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_place_adjacent` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene, e.g. 'res\://levels/street.tscn'. It must be open in the editor (any tab). Length 1 to 512. |
| `subject` | string | Yes | Node to move (exact path from the scene root). Length 1 to 256. |
| `reference` | string | Yes | Node that stays put. Length 1 to 256. |
| `axis` | "x" \| "y" \| "z" | Yes | Axis along which the two pieces meet. |
| `side` | "min" \| "max" | Yes | max: subject on the reference's +axis side (its min face against the reference's max face). min: the -axis side. |
| `gap` | number | No | Distance between the two faces along axis. 0 = flush; negative = overlap. Default `0`. Range -100 to 1000. |
| `alignOtherAxes` | "min" \| "center" \| "max" \| "none" \| object | No | How to line up the other two axes: one mode for both, or per axis, e.g. \{y: min, z: max} for same base height and one front plane. Default `"none"`. |
| `space` | "world" \| "local" | No | world axes, or the reference's own axes for a rotated facade. Default `"world"`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene, e.g. 'res://levels/street.tscn'. It must be open in the editor (any tab)."
      },
      "subject": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Node to move (exact path from the scene root)."
      },
      "reference": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Node that stays put."
      },
      "axis": {
        "type": "string",
        "enum": [
          "x",
          "y",
          "z"
        ],
        "description": "Axis along which the two pieces meet."
      },
      "side": {
        "type": "string",
        "enum": [
          "min",
          "max"
        ],
        "description": "max: subject on the reference's +axis side (its min face against the reference's max face). min: the -axis side."
      },
      "gap": {
        "type": "number",
        "minimum": -100,
        "maximum": 1000,
        "default": 0,
        "description": "Distance between the two faces along axis. 0 = flush; negative = overlap."
      },
      "alignOtherAxes": {
        "oneOf": [
          {
            "type": "string",
            "enum": [
              "min",
              "center",
              "max",
              "none"
            ]
          },
          {
            "type": "object",
            "properties": {
              "x": {
                "type": "string",
                "enum": [
                  "min",
                  "center",
                  "max",
                  "none"
                ]
              },
              "y": {
                "type": "string",
                "enum": [
                  "min",
                  "center",
                  "max",
                  "none"
                ]
              },
              "z": {
                "type": "string",
                "enum": [
                  "min",
                  "center",
                  "max",
                  "none"
                ]
              }
            },
            "additionalProperties": false
          }
        ],
        "default": "none",
        "description": "How to line up the other two axes: one mode for both, or per axis, e.g. {y: min, z: max} for same base height and one front plane."
      },
      "space": {
        "type": "string",
        "enum": [
          "world",
          "local"
        ],
        "default": "world",
        "description": "world axes, or the reference's own axes for a rotated facade."
      }
    },
    "required": [
      "scenePath",
      "subject",
      "reference",
      "axis",
      "side"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Place a node against another

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_place_adjacent",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine place-adjacent
  ```
</CodeGroup>

***

### play

`engine.play`: **Play the game**

Start the game quietly (the editor keeps its tab and focus): the main scene or a given one, embedded or as a hidden offscreen instance, with an optional seed and fixed frame rate, or a local multiplayer session (players). Next: engine.is\_running, then engine.get\_diagnostics.

| | |
| - | - |
| **MCP** | `summer_play` in the npm MCP |
| **CLI** | `summer engine play` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_play` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scene` | string | No | Scene to run instead of main scene, e.g. 'res\://levels/test\_level.tscn' |
| `instance` | string | No | Name a game instance. 'main' (default) = the editor's embedded game. Any other name with mode 'offscreen' spawns a disposable parallel instance (at most 3) that the runtime tools address by this name. |
| `mode` | "embedded" \| "offscreen" | No | 'embedded' (default) plays in the editor; 'offscreen' spawns a hidden child process (requires instance != 'main'). |
| `deterministic` | boolean | No | Offscreen only — launch with --fixed-fps 60 --summer-seed \<seed> --audio-driver Dummy so the run is reproducible and input replays with seed are accepted. |
| `seed` | integer | No | Pin the game's GLOBAL RNG for this launch (child gets --summer-seed \<seed>; default 20260725 when deterministic:true and seed is omitted). Pins randi/randf/randi\_range/randf\_range/randfn, Array.shuffle/pick\_random. Does NOT pin RandomNumberGenerator instances, scripts calling randomize(), or wall-clock reads. Omitted = randomized, as always. |
| `fixed_fps` | integer | No | Fixed timestep for this launch (child gets --fixed-fps \<n>): scene time decouples from the wall clock, the game runs as fast as it renders, frame-count-derived state repeats run to run, and at\_ms input timing / GameStep frames map exactly. Opt-in per launch, never the default. |
| `time_scale` | number | No | Engine time scale for this launch (child gets --time-scale \<f>). Not a determinism pin on its own. |
| `speed` | number | No | User time scale applied on session start, (0, 100] — e.g. 0.5 for half speed. |
| `focus` | boolean | No | Default false = QUIET play (PlayGame agent:true): the editor does not switch to the Game tab or grab focus for the embedded game, so the user keeps working. Pass true to launch the way the toolbar Play button does (Game tab + focus) — only when the user is watching and asked to see it. The result echoes agent\_quiet:true when honoured; a launch result without it (posture\_note) means the engine predates quiet play and most likely took focus. |
| `players` | integer | No | Local Play for a Summer multiplayer game (engine with Local Play): start the game's authority headless plus this many clients on this machine, each joining through the game's own Summer.client.join. The scenes and queue come from the project's summer.build.json WorldDefinition; no account, Docker or game flags are needed. Omit it and pass queue to start the queue's minPlayers from summer.build.json; 0 forces one ordinary run. The result's local\_play block lists every process and persona, plus warnings when the roster is outside the queue's minPlayers..maxPlayers. Range 0 to 64. |
| `spectators` | integer | No | Local Play: also start this many spectator clients (only with players). Range 0 to …. |
| `queue` | string | No | Local Play: the summer.build.json queue the local World stands in for (default: the first declared queue). |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scene": {
        "type": "string",
        "description": "Scene to run instead of main scene, e.g. 'res://levels/test_level.tscn'"
      },
      "instance": {
        "type": "string",
        "description": "Name a game instance. 'main' (default) = the editor's embedded game. Any other name with mode 'offscreen' spawns a disposable parallel instance (at most 3) that the runtime tools address by this name."
      },
      "mode": {
        "type": "string",
        "enum": [
          "embedded",
          "offscreen"
        ],
        "description": "'embedded' (default) plays in the editor; 'offscreen' spawns a hidden child process (requires instance != 'main')."
      },
      "deterministic": {
        "type": "boolean",
        "description": "Offscreen only — launch with --fixed-fps 60 --summer-seed <seed> --audio-driver Dummy so the run is reproducible and input replays with seed are accepted."
      },
      "seed": {
        "type": "integer",
        "description": "Pin the game's GLOBAL RNG for this launch (child gets --summer-seed <seed>; default 20260725 when deterministic:true and seed is omitted). Pins randi/randf/randi_range/randf_range/randfn, Array.shuffle/pick_random. Does NOT pin RandomNumberGenerator instances, scripts calling randomize(), or wall-clock reads. Omitted = randomized, as always."
      },
      "fixed_fps": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Fixed timestep for this launch (child gets --fixed-fps <n>): scene time decouples from the wall clock, the game runs as fast as it renders, frame-count-derived state repeats run to run, and at_ms input timing / GameStep frames map exactly. Opt-in per launch, never the default."
      },
      "time_scale": {
        "type": "number",
        "exclusiveMinimum": 0,
        "description": "Engine time scale for this launch (child gets --time-scale <f>). Not a determinism pin on its own."
      },
      "speed": {
        "type": "number",
        "description": "User time scale applied on session start, (0, 100] — e.g. 0.5 for half speed."
      },
      "focus": {
        "type": "boolean",
        "description": "Default false = QUIET play (PlayGame agent:true): the editor does not switch to the Game tab or grab focus for the embedded game, so the user keeps working. Pass true to launch the way the toolbar Play button does (Game tab + focus) — only when the user is watching and asked to see it. The result echoes agent_quiet:true when honoured; a launch result without it (posture_note) means the engine predates quiet play and most likely took focus."
      },
      "players": {
        "type": "integer",
        "minimum": 0,
        "maximum": 64,
        "description": "Local Play for a Summer multiplayer game (engine with Local Play): start the game's authority headless plus this many clients on this machine, each joining through the game's own Summer.client.join. The scenes and queue come from the project's summer.build.json WorldDefinition; no account, Docker or game flags are needed. Omit it and pass queue to start the queue's minPlayers from summer.build.json; 0 forces one ordinary run. The result's local_play block lists every process and persona, plus warnings when the roster is outside the queue's minPlayers..maxPlayers."
      },
      "spectators": {
        "type": "integer",
        "minimum": 0,
        "description": "Local Play: also start this many spectator clients (only with players)."
      },
      "queue": {
        "type": "string",
        "description": "Local Play: the summer.build.json queue the local World stands in for (default: the first declared queue)."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Play the game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_play",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine play
  ```
</CodeGroup>

***

### project\_setting

`engine.project_setting`: **Set a project setting**

Set one project.godot setting, such as application/run/main\_scene, the window size, the renderer or the default gravity.

| | |
| - | - |
| **MCP** | `summer_project_setting` in the npm MCP |
| **CLI** | `summer engine project-setting` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_project_setting` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `key` | string | Yes | Setting key path, e.g. 'application/config/name' |
| `value` | string \| number \| boolean | Yes | Setting value |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "key": {
        "type": "string",
        "description": "Setting key path, e.g. 'application/config/name'"
      },
      "value": {
        "type": [
          "string",
          "number",
          "boolean"
        ],
        "description": "Setting value"
      }
    },
    "required": [
      "key",
      "value"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Set a project setting

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_project_setting",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine project-setting
  ```
</CodeGroup>

***

### raycast

`engine.raycast`: **Cast a ray in a scene**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Cast one ray from any point in a scene: the node it hits, the point and the normal. Physics first, visible bounds as a declared fallback. Changes nothing.

| | |
| - | - |
| **MCP** | `summer_raycast` in the npm MCP |
| **CLI** | `summer engine raycast` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_raycast` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene, e.g. 'res\://levels/street.tscn'. It must be open; physics needs it to be the active tab. Length 1 to 512. |
| `origin` | number\[] | Yes | Ray start \[x, y, z] in scene (world) space. Items 3 to 3. |
| `direction` | number\[] | Yes | Ray direction \[x, y, z], non-zero; normalized for you. Items 3 to 3. |
| `maxDistance` | number | No | Maximum ray length in scene units. Default `100`. Range … to 10000. |
| `collisionMask` | integer | No | Godot 3D physics layer mask for physics queries. Default `4294967295`. Range 0 to 4294967295. |
| `collideWithAreas` | boolean | No | Also hit Area3D volumes (physics only). Default `false`. |
| `evidence` | "auto" \| "physics" \| "visual\_aabb" | No | auto: physics first, visual AABB fallback when physics finds nothing (declared). physics or visual\_aabb: that channel only. Default `"auto"`. |
| `exclude` | string\[] | No | Nodes (with descendants) the ray ignores. Items 0 to 16. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene, e.g. 'res://levels/street.tscn'. It must be open; physics needs it to be the active tab."
      },
      "origin": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Ray start [x, y, z] in scene (world) space."
      },
      "direction": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Ray direction [x, y, z], non-zero; normalized for you."
      },
      "maxDistance": {
        "type": "number",
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "default": 100,
        "description": "Maximum ray length in scene units."
      },
      "collisionMask": {
        "type": "integer",
        "minimum": 0,
        "maximum": 4294967295,
        "default": 4294967295,
        "description": "Godot 3D physics layer mask for physics queries."
      },
      "collideWithAreas": {
        "type": "boolean",
        "default": false,
        "description": "Also hit Area3D volumes (physics only)."
      },
      "evidence": {
        "type": "string",
        "enum": [
          "auto",
          "physics",
          "visual_aabb"
        ],
        "default": "auto",
        "description": "auto: physics first, visual AABB fallback when physics finds nothing (declared). physics or visual_aabb: that channel only."
      },
      "exclude": {
        "type": "array",
        "maxItems": 16,
        "items": {
          "type": "string"
        },
        "description": "Nodes (with descendants) the ray ignores."
      }
    },
    "required": [
      "scenePath",
      "origin",
      "direction"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Cast a ray in a scene

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_raycast",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine raycast
  ```
</CodeGroup>

***

### read\_file

`engine.read_file`: **Read a project file**

Read a text file of the project (res\://), a line or byte window of it, or parts of a .json, with the whole file's sha256. Pass that sha256 to engine.write\_file or engine.replace\_text to change the file safely.

| | |
| - | - |
| **MCP** | `summer_read_file` in the npm MCP |
| **CLI** | `summer engine read-file` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_read_file` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Project path, e.g. res\://scripts/player.gd |
| `max_bytes` | integer | No | Most bytes of content to return (UTF-8). Default 200000. A window or JSON selection is cut at this size too. Default `200000`. Range … to 1000000. |
| `offset` | integer | No | Skip this many units (lines by default, see unit) before returning content. 0 = from the start. Range 0 to …. |
| `limit` | integer | No | Return at most this many units (lines by default). The result's window\.next\_offset continues the read. |
| `unit` | "lines" \| "bytes" | No | What offset/limit count: 'lines' (default) or 'bytes' (cut on UTF-8 character boundaries). |
| `json_path` | string | No | For a JSON file: return only this value, e.g. 'pieces.wall\_a', 'pieces\["a b"]', 'items\[3].size\_m'. |
| `keys` | string\[] | No | For a JSON object (the file root or the json\_path value): keep only these keys; \* and ? wildcards, e.g. \['wall\_\*']. Items 0 to 64. |
| `keys_only` | boolean | No | For a JSON object: return only its key names (after the keys filter), not the values — a cheap table of contents. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Project path, e.g. res://scripts/player.gd"
      },
      "max_bytes": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "maximum": 1000000,
        "default": 200000,
        "description": "Most bytes of content to return (UTF-8). Default 200000. A window or JSON selection is cut at this size too."
      },
      "offset": {
        "type": "integer",
        "minimum": 0,
        "description": "Skip this many units (lines by default, see unit) before returning content. 0 = from the start."
      },
      "limit": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Return at most this many units (lines by default). The result's window.next_offset continues the read."
      },
      "unit": {
        "type": "string",
        "enum": [
          "lines",
          "bytes"
        ],
        "description": "What offset/limit count: 'lines' (default) or 'bytes' (cut on UTF-8 character boundaries)."
      },
      "json_path": {
        "type": "string",
        "description": "For a JSON file: return only this value, e.g. 'pieces.wall_a', 'pieces[\"a b\"]', 'items[3].size_m'."
      },
      "keys": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "maxItems": 64,
        "description": "For a JSON object (the file root or the json_path value): keep only these keys; * and ? wildcards, e.g. ['wall_*']."
      },
      "keys_only": {
        "type": "boolean",
        "description": "For a JSON object: return only its key names (after the keys filter), not the values — a cheap table of contents."
      }
    },
    "required": [
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read a project file

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_read_file",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine read-file
  ```
</CodeGroup>

***

### recent\_events

`engine.recent_events`: **Read recent engine events**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read the newest engine events (saves, plays, op results, script errors, imports) at once, and next\_seq, the cursor to pass to engine.wait\_for\_event.

| | |
| - | - |
| **MCP** | `summer_recent_events` in the npm MCP |
| **CLI** | `summer engine recent-events` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_recent_events` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `since` | integer | No | Deliver events with seq > since. Omit = the newest `limit` sequence numbers. 0 = the whole retained ring from the oldest (paged: pass next\_seq back while truncated is true). Range 0 to …. |
| `kinds` | string\[] | No | Event kinds to deliver (default: all). v1 kinds: op.applied, op.failed, script.error, play.started, play.stopped, scene.saved, scene.opened, import.completed, selection.changed, snapshot.published. |
| `limit` | integer | No | Maximum events to return (default 50, cap 200). Default `50`. Range 1 to 200. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "since": {
        "type": "integer",
        "minimum": 0,
        "description": "Deliver events with seq > since. Omit = the newest `limit` sequence numbers. 0 = the whole retained ring from the oldest (paged: pass next_seq back while truncated is true)."
      },
      "kinds": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "Event kinds to deliver (default: all). v1 kinds: op.applied, op.failed, script.error, play.started, play.stopped, scene.saved, scene.opened, import.completed, selection.changed, snapshot.published."
      },
      "limit": {
        "type": "integer",
        "minimum": 1,
        "maximum": 200,
        "default": 50,
        "description": "Maximum events to return (default 50, cap 200)."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read recent engine events

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_recent_events",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine recent-events
  ```
</CodeGroup>

***

### remove\_node

`engine.remove_node`: **Remove a node**

Remove a node and all its children from the scene at scenePath and save it. The root cannot be removed. One undo step. Remove top-level nodes only when the person asked for it.

| | |
| - | - |
| **MCP** | `summer_remove_node` in the npm MCP |
| **CLI** | `summer engine remove-node` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_remove_node` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene path, e.g. 'res\://main.tscn' |
| `path` | string | Yes | Node path to remove, e.g. `./World/OldEnemy` |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene path, e.g. 'res://main.tscn'"
      },
      "path": {
        "type": "string",
        "description": "Node path to remove, e.g. './World/OldEnemy'"
      }
    },
    "required": [
      "scenePath",
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Remove a node

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_remove_node",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine remove-node
  ```
</CodeGroup>

***

### repeat\_along

`engine.repeat_along`: **Repeat a scene along a line**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Place copies of one scene along a line in one call: fence posts, clamps, a row of windows (at most 64). Returns the created node paths and saves the scene once.

| | |
| - | - |
| **MCP** | `summer_repeat_along` in the npm MCP |
| **CLI** | `summer engine repeat-along` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_repeat_along` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene, e.g. 'res\://levels/street.tscn'. Length 1 to 512. |
| `template` | string | Yes | Scene to instance for every copy (.tscn, .scn, .glb, .gltf). Length 1 to 512. |
| `parent` | string | Yes | Parent for the copies; start/end/direction are in this parent's local space. Length 1 to 256. |
| `start` | number\[] | Yes | First copy's position \[x, y, z]. Items 3 to 3. |
| `end` | number\[] | No | Line end. With spacing as many copies as fit; with count, count copies from start to end. Items 3 to 3. |
| `direction` | number\[] | No | Instead of end, the row direction; needs count and spacing. Items 3 to 3. |
| `count` | integer | No | Number of copies. Range 1 to 64. |
| `spacing` | number | No | Distance between neighbouring copies' origins. Range … to 1000. |
| `align` | "start" \| "center" \| "end" | No | With end + spacing, where the leftover length goes. Default `"start"`. |
| `rotationDegrees` | number\[] | No | rotation\_degrees for every copy. Items 3 to 3. |
| `scale` | number\[] | No | scale for every copy. Items 3 to 3. |
| `namePrefix` | string | No | Copies are named \<namePrefix>\_\<n> (default the template file name). Length 1 to 64. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene, e.g. 'res://levels/street.tscn'."
      },
      "template": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Scene to instance for every copy (.tscn, .scn, .glb, .gltf)."
      },
      "parent": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Parent for the copies; start/end/direction are in this parent's local space."
      },
      "start": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "First copy's position [x, y, z]."
      },
      "end": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Line end. With spacing as many copies as fit; with count, count copies from start to end."
      },
      "direction": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "Instead of end, the row direction; needs count and spacing."
      },
      "count": {
        "type": "integer",
        "minimum": 1,
        "maximum": 64,
        "description": "Number of copies."
      },
      "spacing": {
        "type": "number",
        "exclusiveMinimum": 0,
        "maximum": 1000,
        "description": "Distance between neighbouring copies' origins."
      },
      "align": {
        "type": "string",
        "enum": [
          "start",
          "center",
          "end"
        ],
        "default": "start",
        "description": "With end + spacing, where the leftover length goes."
      },
      "rotationDegrees": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "rotation_degrees for every copy."
      },
      "scale": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "scale for every copy."
      },
      "namePrefix": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "description": "Copies are named <namePrefix>_<n> (default the template file name)."
      }
    },
    "required": [
      "scenePath",
      "template",
      "parent",
      "start"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Repeat a scene along a line

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_repeat_along",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine repeat-along
  ```
</CodeGroup>

***

### replace\_node

`engine.replace_node`: **Replace a node**

Replace a node with another scene or node type, keeping its parent, index, name, transform and children; the saved file is read back to prove it. Next: engine.get\_scene\_tree.

| | |
| - | - |
| **MCP** | `summer_replace_node` in the npm MCP |
| **CLI** | `summer engine replace-node` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_replace_node` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene path, e.g. 'res\://main.tscn' |
| `path` | string | Yes | Node path to replace, e.g. `./House3/Front/G_f2_door` |
| `type` | string | No | New node type, e.g. 'RigidBody3D'. Give exactly one of type or scene. |
| `scene` | string | No | Scene or model to replace with, e.g. 'res\://kit/wall\_door\_02.tscn'. Give exactly one of type or scene. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene path, e.g. 'res://main.tscn'"
      },
      "path": {
        "type": "string",
        "description": "Node path to replace, e.g. './House3/Front/G_f2_door'"
      },
      "type": {
        "type": "string",
        "description": "New node type, e.g. 'RigidBody3D'. Give exactly one of type or scene."
      },
      "scene": {
        "type": "string",
        "description": "Scene or model to replace with, e.g. 'res://kit/wall_door_02.tscn'. Give exactly one of type or scene."
      }
    },
    "required": [
      "scenePath",
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Replace a node

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_replace_node",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine replace-node
  ```
</CodeGroup>

***

### replace\_text

`engine.replace_text`: **Replace text in a project file**

Replace text in an existing project file. The text must match exactly once unless replace\_all is set; the write is guarded by the file's sha256. Then check scripts with engine.get\_script\_errors.

| | |
| - | - |
| **MCP** | `summer_replace_text` in the npm MCP |
| **CLI** | `summer engine replace-text` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_replace_text` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Project path, e.g. res\://scripts/player.gd |
| `old_text` | string | Yes | Exact text to replace. Length 1 to …. |
| `new_text` | string | Yes | Replacement text; may be empty. |
| `replace_all` | boolean | No | Replace every exact occurrence instead of requiring one unique match. Default `false`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Project path, e.g. res://scripts/player.gd"
      },
      "old_text": {
        "type": "string",
        "minLength": 1,
        "description": "Exact text to replace."
      },
      "new_text": {
        "type": "string",
        "description": "Replacement text; may be empty."
      },
      "replace_all": {
        "type": "boolean",
        "default": false,
        "description": "Replace every exact occurrence instead of requiring one unique match."
      }
    },
    "required": [
      "path",
      "old_text",
      "new_text"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Replace text in a project file

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_replace_text",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine replace-text
  ```
</CodeGroup>

***

### run\_editor\_script

`engine.run_editor_script`: **Run a script in a headless editor**

Run an EditorScript func \_run() in a fresh headless editor against the project on disk: batch and project-wide jobs such as re-saving many scenes. It cannot see unsaved edits. For the open scene use engine.run\_script.

| | |
| - | - |
| **MCP** | `summer_run_editor_script` in the npm MCP |
| **CLI** | `summer engine run-editor-script` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_run_editor_script` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `source` | string | Yes | EditorScript GDScript source with `func _run():`. '@tool' / 'extends EditorScript' are optional — missing lines are prepended and reported in normalizations. |
| `max_seconds` | number | No | Time budget in seconds for the child editor (default 120, clamped 15-600). Include boot time — large projects can take 30s+ just to start. |
| `checkpoint` | boolean | No | Take a SummerGit checkpoint before the child editor runs. The result confesses (no\_rewind\_point) when none could be taken. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "source": {
        "type": "string",
        "description": "EditorScript GDScript source with `func _run():`. '@tool' / 'extends EditorScript' are optional — missing lines are prepended and reported in normalizations."
      },
      "max_seconds": {
        "type": "number",
        "description": "Time budget in seconds for the child editor (default 120, clamped 15-600). Include boot time — large projects can take 30s+ just to start."
      },
      "checkpoint": {
        "type": "boolean",
        "description": "Take a SummerGit checkpoint before the child editor runs. The result confesses (no_rewind_point) when none could be taken."
      }
    },
    "required": [
      "source"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Run a script in a headless editor

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_run_editor_script",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine run-editor-script
  ```
</CodeGroup>

***

### run\_script

`engine.run_script`: **Run a script on a scene**

Run one GDScript func run(ctx) in the live editor on the scene at scenePath: the way to make 3 or more scene edits, loops, grids and procedural meshes. Returns reports, output and errors. Loop: engine.world\_snapshot, this, engine.snapshot\_diff, engine.screenshot.

| | |
| - | - |
| **MCP** | `summer_run_script` in the npm MCP |
| **CLI** | `summer engine run-script` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_run_script` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | The scene to run against, e.g. 'res\://main.tscn'. Opened first when it is not the edited scene, then the person's tab is restored. Omit only to run against whatever scene is open. |
| `source` | string | Yes | GDScript source containing `func run(ctx):`. No extends/@tool line — just the function (plus any helpers). |
| `max_seconds` | number | No | Time budget in seconds (default 20, clamped 5-120). The script blocks the editor while it runs — keep it short. |
| `checkpoint` | boolean | No | Take a SummerGit checkpoint before running (default true). The result confesses (no\_rewind\_point) when no checkpoint could be taken. |
| `undo` | "action" \| "none" | No | Transaction mode (newer engines). 'action' (engine default) makes the run one undo action and rolls back on a runtime error; 'none' is checkpoint only. Older engines ignore this. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "The scene to run against, e.g. 'res://main.tscn'. Opened first when it is not the edited scene, then the person's tab is restored. Omit only to run against whatever scene is open."
      },
      "source": {
        "type": "string",
        "description": "GDScript source containing `func run(ctx):`. No extends/@tool line — just the function (plus any helpers)."
      },
      "max_seconds": {
        "type": "number",
        "description": "Time budget in seconds (default 20, clamped 5-120). The script blocks the editor while it runs — keep it short."
      },
      "checkpoint": {
        "type": "boolean",
        "description": "Take a SummerGit checkpoint before running (default true). The result confesses (no_rewind_point) when no checkpoint could be taken."
      },
      "undo": {
        "type": "string",
        "enum": [
          "action",
          "none"
        ],
        "description": "Transaction mode (newer engines). 'action' (engine default) makes the run one undo action and rolls back on a runtime error; 'none' is checkpoint only. Older engines ignore this."
      }
    },
    "required": [
      "source"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Run a script on a scene

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_run_script",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine run-script
  ```
</CodeGroup>

***

### runtime\_animate

`engine.runtime_animate`: **Drive animation in the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read and drive animation in the RUNNING game: AnimationPlayer clips, AnimationTree states and Skeleton3D bone poses. cmd state only reads. Prove motion with two reads around engine.game\_control step.

| | |
| - | - |
| **MCP** | `summer_runtime_animate` in the npm MCP |
| **CLI** | `summer engine runtime-animate` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_runtime_animate` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `target` | "player" \| "tree" \| "bones" | Yes | 'player' = AnimationPlayer (RuntimeAnimation), 'tree' = AnimationTree state machine (RuntimeAnimationTree), 'bones' = Skeleton3D poses (GetRuntimeBones). |
| `path` | string | Yes | ABSOLUTE runtime path of the AnimationPlayer / AnimationTree / Skeleton3D. |
| `cmd` | "state" \| "play" \| "pause" \| "stop" \| "seek" \| "speed" \| "travel" \| "start" \| "set\_param" \| "get\_param" | No | Default 'state' (read-only). target player: state\|play\|pause\|stop\|seek\|speed. target tree: state\|travel\|start\|stop\|set\_param\|get\_param. Ignored for target bones. |
| `name` | string | No | target player play — clip name (unknown\_animation lists the clips). |
| `position` | number | No | target player seek — position in seconds. |
| `speed` | number | No | target player speed — speed\_scale (1.0 = normal, negative plays backwards). |
| `from_end` | boolean | No | target player play — start from the end (backwards). |
| `blend` | number | No | target player play — custom blend time in seconds. |
| `update` | boolean | No | target player seek — apply the pose immediately (default true). |
| `state` | string | No | target tree travel/start — state machine node name (unknown\_state lists them). |
| `reset` | boolean | No | target tree travel/start — reset the destination clip (default true). |
| `param` | string | No | target tree set\_param/get\_param — parameter path, e.g. 'parameters/Blend/blend\_amount'. |
| `value` | string \| number \| boolean | No | target tree set\_param — new value (JSON scalar or Godot literal string). |
| `playback_path` | string | No | target tree — state machine playback parameter (default 'parameters/playback'; nested machines use 'parameters/\<Node>/playback'). |
| `bones` | string\[] | No | target bones — bone names to read (omit for the first 256; page larger rigs with this filter). |
| `space` | "global" \| "local" \| "both" | No | target bones — 'global' (default, skeleton-space global\_pose), 'local' (pose), or 'both'. |
| `include_rest` | boolean | No | target bones — also return each bone's rest Transform3D. |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; summer\_game\_control action 'instances' lists them. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "target": {
        "type": "string",
        "enum": [
          "player",
          "tree",
          "bones"
        ],
        "description": "'player' = AnimationPlayer (RuntimeAnimation), 'tree' = AnimationTree state machine (RuntimeAnimationTree), 'bones' = Skeleton3D poses (GetRuntimeBones)."
      },
      "path": {
        "type": "string",
        "description": "ABSOLUTE runtime path of the AnimationPlayer / AnimationTree / Skeleton3D."
      },
      "cmd": {
        "type": "string",
        "enum": [
          "state",
          "play",
          "pause",
          "stop",
          "seek",
          "speed",
          "travel",
          "start",
          "set_param",
          "get_param"
        ],
        "description": "Default 'state' (read-only). target player: state|play|pause|stop|seek|speed. target tree: state|travel|start|stop|set_param|get_param. Ignored for target bones."
      },
      "name": {
        "type": "string",
        "description": "target player play — clip name (unknown_animation lists the clips)."
      },
      "position": {
        "type": "number",
        "description": "target player seek — position in seconds."
      },
      "speed": {
        "type": "number",
        "description": "target player speed — speed_scale (1.0 = normal, negative plays backwards)."
      },
      "from_end": {
        "type": "boolean",
        "description": "target player play — start from the end (backwards)."
      },
      "blend": {
        "type": "number",
        "description": "target player play — custom blend time in seconds."
      },
      "update": {
        "type": "boolean",
        "description": "target player seek — apply the pose immediately (default true)."
      },
      "state": {
        "type": "string",
        "description": "target tree travel/start — state machine node name (unknown_state lists them)."
      },
      "reset": {
        "type": "boolean",
        "description": "target tree travel/start — reset the destination clip (default true)."
      },
      "param": {
        "type": "string",
        "description": "target tree set_param/get_param — parameter path, e.g. 'parameters/Blend/blend_amount'."
      },
      "value": {
        "type": [
          "string",
          "number",
          "boolean"
        ],
        "description": "target tree set_param — new value (JSON scalar or Godot literal string)."
      },
      "playback_path": {
        "type": "string",
        "description": "target tree — state machine playback parameter (default 'parameters/playback'; nested machines use 'parameters/<Node>/playback')."
      },
      "bones": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "target bones — bone names to read (omit for the first 256; page larger rigs with this filter)."
      },
      "space": {
        "type": "string",
        "enum": [
          "global",
          "local",
          "both"
        ],
        "description": "target bones — 'global' (default, skeleton-space global_pose), 'local' (pose), or 'both'."
      },
      "include_rest": {
        "type": "boolean",
        "description": "target bones — also return each bone's rest Transform3D."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; summer_game_control action 'instances' lists them."
      }
    },
    "required": [
      "target",
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Drive animation in the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_runtime_animate",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine runtime-animate
  ```
</CodeGroup>

***

### runtime\_call

`engine.runtime_call`: **Call a method in the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Call one method on a node in the RUNNING game and return its result, to trigger gameplay code directly. A call is an action, not proof: check what it did with engine.game\_probe.

| | |
| - | - |
| **MCP** | `summer_runtime_call` in the npm MCP |
| **CLI** | `summer engine runtime-call` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_runtime_call` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | ABSOLUTE runtime node path, e.g. '/root/Main/Player'. |
| `method` | string | Yes | Method name to call on the node, e.g. 'take\_damage', 'get\_velocity'. |
| `args` | any\[] | No | Positional arguments. JSON scalars, arrays and objects pass as-is; math values as Godot literal strings ('Vector3(0, 1, 0)'). Object and RID arguments are refused (bad\_args). |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; summer\_game\_control action 'instances' lists them. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "ABSOLUTE runtime node path, e.g. '/root/Main/Player'."
      },
      "method": {
        "type": "string",
        "description": "Method name to call on the node, e.g. 'take_damage', 'get_velocity'."
      },
      "args": {
        "type": "array",
        "items": {},
        "description": "Positional arguments. JSON scalars, arrays and objects pass as-is; math values as Godot literal strings ('Vector3(0, 1, 0)'). Object and RID arguments are refused (bad_args)."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; summer_game_control action 'instances' lists them."
      }
    },
    "required": [
      "path",
      "method"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Call a method in the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_runtime_call",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine runtime-call
  ```
</CodeGroup>

***

### runtime\_set

`engine.runtime_set`: **Set a property in the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Set one property on a node in the RUNNING game (the live object, never the scene file) and read back whether it applied: move the player, set health, flip a flag. Then check with engine.game\_probe.

| | |
| - | - |
| **MCP** | `summer_runtime_set` in the npm MCP |
| **CLI** | `summer engine runtime-set` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_runtime_set` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | ABSOLUTE runtime node path, e.g. '/root/Main/Player' (from summer\_game\_probe tree). |
| `property` | string | Yes | Property name, e.g. 'position', 'health', 'visible'. 'script' and 'owner' are refused. |
| `value` | string \| number \| boolean | Yes | New value. JSON scalars for primitives; Godot literal strings for math types ('Vector3(1, 2, 3)', 'Color(1, 0, 0, 1)'). Compared with Variant equality, so 1 and 1.0 both count as applied. |
| `field` | string | No | Optional sub-field to set instead of the whole value, e.g. 'x' on a Vector3 property. |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; summer\_game\_control action 'instances' lists them. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "ABSOLUTE runtime node path, e.g. '/root/Main/Player' (from summer_game_probe tree)."
      },
      "property": {
        "type": "string",
        "description": "Property name, e.g. 'position', 'health', 'visible'. 'script' and 'owner' are refused."
      },
      "value": {
        "type": [
          "string",
          "number",
          "boolean"
        ],
        "description": "New value. JSON scalars for primitives; Godot literal strings for math types ('Vector3(1, 2, 3)', 'Color(1, 0, 0, 1)'). Compared with Variant equality, so 1 and 1.0 both count as applied."
      },
      "field": {
        "type": "string",
        "description": "Optional sub-field to set instead of the whole value, e.g. 'x' on a Vector3 property."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; summer_game_control action 'instances' lists them."
      }
    },
    "required": [
      "path",
      "property",
      "value"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Set a property in the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_runtime_set",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine runtime-set
  ```
</CodeGroup>

***

### runtime\_spawn

`engine.runtime_spawn`: **Spawn or free in the running game**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Spawn a scene into the RUNNING game (action spawn) or free a live node (action free) to set up a test. The scene file is not touched. Then check with engine.game\_probe.

| | |
| - | - |
| **MCP** | `summer_runtime_spawn` in the npm MCP |
| **CLI** | `summer engine runtime-spawn` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_runtime_spawn` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `action` | "spawn" \| "free" | Yes | 'spawn' instantiates a PackedScene under parent (SpawnRuntimeScene); 'free' removes a node (FreeRuntimeNode). |
| `parent` | string | No | action spawn — ABSOLUTE runtime path of the parent, e.g. '/root/Main/Enemies'. |
| `scene` | string | No | action spawn — PackedScene to instantiate, e.g. 'res\://enemies/goblin.tscn'. |
| `name` | string | No | action spawn — node name; the engine renames on collision and reports renamed\_to. |
| `props` | object | No | action spawn — properties set on the new node before it enters the tree (\{position 'Vector3(0, 1, 0)', health 50}). Unknown ones land in prop\_warnings, never fail the spawn. |
| `path` | string | No | action free — ABSOLUTE runtime path of the node to free. |
| `mode` | "queue\_free" \| "free" | No | action free — 'queue\_free' (default, frees at the end of the frame) or 'free' (immediate). |
| `instance` | string | No | Game instance to address (default 'main'). Offscreen instances are named by summer\_play with instance + mode offscreen; summer\_game\_control action 'instances' lists them. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": [
          "spawn",
          "free"
        ],
        "description": "'spawn' instantiates a PackedScene under parent (SpawnRuntimeScene); 'free' removes a node (FreeRuntimeNode)."
      },
      "parent": {
        "type": "string",
        "description": "action spawn — ABSOLUTE runtime path of the parent, e.g. '/root/Main/Enemies'."
      },
      "scene": {
        "type": "string",
        "description": "action spawn — PackedScene to instantiate, e.g. 'res://enemies/goblin.tscn'."
      },
      "name": {
        "type": "string",
        "description": "action spawn — node name; the engine renames on collision and reports renamed_to."
      },
      "props": {
        "type": "object",
        "additionalProperties": {
          "type": [
            "string",
            "number",
            "boolean"
          ]
        },
        "description": "action spawn — properties set on the new node before it enters the tree ({position 'Vector3(0, 1, 0)', health 50}). Unknown ones land in prop_warnings, never fail the spawn."
      },
      "path": {
        "type": "string",
        "description": "action free — ABSOLUTE runtime path of the node to free."
      },
      "mode": {
        "type": "string",
        "enum": [
          "queue_free",
          "free"
        ],
        "description": "action free — 'queue_free' (default, frees at the end of the frame) or 'free' (immediate)."
      },
      "instance": {
        "type": "string",
        "description": "Game instance to address (default 'main'). Offscreen instances are named by summer_play with instance + mode offscreen; summer_game_control action 'instances' lists them."
      }
    },
    "required": [
      "action"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Spawn or free in the running game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_runtime_spawn",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine runtime-spawn
  ```
</CodeGroup>

***

### save\_camera\_bookmark

`engine.save_camera_bookmark`: **Save a camera bookmark**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Save a named camera viewpoint in the project (res\://.summer/camera\_bookmarks.json): position and look\_at as Vector3 literals, or neither to take the editor's 3D camera. The scene file is not touched. Next: engine.screenshot.

| | |
| - | - |
| **MCP** | `summer_engine_save_camera_bookmark` in the npm MCP |
| **CLI** | `summer engine save-camera-bookmark` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_camera_bookmark#save` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `name` | string | Yes | Bookmark name for save/delete: 1-64 characters from A-Z a-z 0-9 \\\_ - (e.g. "hero\_closeup"). |
| `position` | string | No | save only. Camera position as a Godot literal, e.g. "Vector3(0, 5, 12)". Goes together with look\_at; omit BOTH to capture the current editor 3D viewport camera. |
| `look_at` | string | No | save only. Point the camera looks at, e.g. "Vector3(0, 1, 0)". Must differ from position. |
| `fov` | number | No | save only. Vertical field of view in degrees (1..179, default 60). With a captured viewport pose the viewport camera's fov wins. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Bookmark name for save/delete: 1-64 characters from A-Z a-z 0-9 _ - (e.g. \"hero_closeup\")."
      },
      "position": {
        "type": "string",
        "description": "save only. Camera position as a Godot literal, e.g. \"Vector3(0, 5, 12)\". Goes together with look_at; omit BOTH to capture the current editor 3D viewport camera."
      },
      "look_at": {
        "type": "string",
        "description": "save only. Point the camera looks at, e.g. \"Vector3(0, 1, 0)\". Must differ from position."
      },
      "fov": {
        "type": "number",
        "description": "save only. Vertical field of view in degrees (1..179, default 60). With a captured viewport pose the viewport camera's fov wins."
      }
    },
    "required": [
      "name"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Save a camera bookmark

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_engine_save_camera_bookmark",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine save-camera-bookmark
  ```
</CodeGroup>

***

### save\_scene

`engine.save_scene`: **Save a scene**

Save the scene at scenePath, or save it under a new path. Scene edits already save once; use this for a standalone save or a save-as.

| | |
| - | - |
| **MCP** | `summer_save_scene` in the npm MCP |
| **CLI** | `summer engine save-scene` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_save_scene` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Scene to save, e.g. 'res\://main.tscn' |
| `path` | string | No | Optional save-as path, e.g. 'res\://levels/level2.tscn' |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to save, e.g. 'res://main.tscn'"
      },
      "path": {
        "type": "string",
        "description": "Optional save-as path, e.g. 'res://levels/level2.tscn'"
      }
    },
    "required": [
      "scenePath"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Save a scene

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_save_scene",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine save-scene
  ```
</CodeGroup>

***

### scene\_audit

`engine.scene_audit`: **Audit a 3D scene**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Check a saved 3D scene for visual and placement problems: holes, exposed edges, floor gaps, floating or sunken props, overlaps, z-fighting, light limits. Returns issues by severity, each with the next tool. Changes nothing.

| | |
| - | - |
| **MCP** | `summer_scene_audit` in the npm MCP |
| **CLI** | `summer engine scene-audit` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_scene_audit` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Scene to audit, e.g. "res\://levels/town.tscn" (the SAVED file). Omit for the scene open in the editor. |
| `checks` | "through\_hole" \| "floor\_gap" \| "floating" \| "sunken" \| "interpenetration" \| "exposed\_edge" \| "open\_fixture\_end" \| "orientation" \| "uv\_stretch" \| "duplicate" \| "z\_fight" \| "depth\_step" \| "lights" \| "transform" \| "resource"\[] | No | Only these checks (default all 15). Fewer checks run faster (duplicate, lights, transform and resource need no physics); rerun a check budget\_ms left partial on its own. Items 1 to 15. |
| `root` | string | No | Report only issues under this node (subtree), e.g. "Block3". The whole scene is still loaded, so walls and floors outside it count as surroundings. |
| `min_severity` | "error" \| "warn" \| "look" | No | "error" (only errors), "warn" (errors and warnings) or "look" (default: everything, including look items that only ask you to look). |
| `offset` | integer | No | Skip this many issues of the sorted, filtered list (paging; the result names the next offset). Range 0 to 100000. |
| `limit` | integer | No | Issues per page (default 15, max 50). The result is capped at 5 KB; a page that does not fit is cut and says so. Range 1 to 50. |
| `budget_ms` | integer | No | Editor time for the whole audit (default 3000 ms). Each check gets a share weighted by its usual cost (unused time passes on); a check past its share stops and counts.\<check>.partial gives the share it covered. Under load, rerun the partial checks with checks or a larger budget. Range 250 to 60000. |
| `accept` | object\[] | No | Accept look or warn items you judged fine (up to 50 per call): \[\{key, reason}] with keys from this scene's issues. Written to res\://.summer/audit-accept.json (the only file the audit writes), then counted (counts.\<check>.accepted) but hidden on every later audit until their evidence changes materially (severity rises, or the measured size moves by over 25%): then they show again with accept\_stale. Errors cannot be accepted. Items 0 to 50. |
| `accept[].key` | string | Yes | The issue's key from a previous result (issues\[].key). Length 8 to 360. |
| `accept[].reason` | string | Yes | Why it is fine, e.g. "coplanar faces hidden behind a sign". Length 3 to 200. |
| `show_accepted` | boolean | No | List accepted items too (each with its accepted reason). Default false: hidden, only counted. |
| `render` | "sheet" \| "none" | No | "sheet": also return ONE inline image of the first 6 issues of this page framed up close from their open side, each tile labelled with its issue number. Default "none". |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to audit, e.g. \"res://levels/town.tscn\" (the SAVED file). Omit for the scene open in the editor."
      },
      "checks": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "through_hole",
            "floor_gap",
            "floating",
            "sunken",
            "interpenetration",
            "exposed_edge",
            "open_fixture_end",
            "orientation",
            "uv_stretch",
            "duplicate",
            "z_fight",
            "depth_step",
            "lights",
            "transform",
            "resource"
          ]
        },
        "minItems": 1,
        "maxItems": 15,
        "description": "Only these checks (default all 15). Fewer checks run faster (duplicate, lights, transform and resource need no physics); rerun a check budget_ms left partial on its own."
      },
      "root": {
        "type": "string",
        "description": "Report only issues under this node (subtree), e.g. \"Block3\". The whole scene is still loaded, so walls and floors outside it count as surroundings."
      },
      "min_severity": {
        "type": "string",
        "enum": [
          "error",
          "warn",
          "look"
        ],
        "description": "\"error\" (only errors), \"warn\" (errors and warnings) or \"look\" (default: everything, including look items that only ask you to look)."
      },
      "offset": {
        "type": "integer",
        "minimum": 0,
        "maximum": 100000,
        "description": "Skip this many issues of the sorted, filtered list (paging; the result names the next offset)."
      },
      "limit": {
        "type": "integer",
        "minimum": 1,
        "maximum": 50,
        "description": "Issues per page (default 15, max 50). The result is capped at 5 KB; a page that does not fit is cut and says so."
      },
      "budget_ms": {
        "type": "integer",
        "minimum": 250,
        "maximum": 60000,
        "description": "Editor time for the whole audit (default 3000 ms). Each check gets a share weighted by its usual cost (unused time passes on); a check past its share stops and counts.<check>.partial gives the share it covered. Under load, rerun the partial checks with checks or a larger budget."
      },
      "accept": {
        "type": "array",
        "maxItems": 50,
        "items": {
          "type": "object",
          "properties": {
            "key": {
              "type": "string",
              "minLength": 8,
              "maxLength": 360,
              "description": "The issue's key from a previous result (issues[].key)."
            },
            "reason": {
              "type": "string",
              "minLength": 3,
              "maxLength": 200,
              "description": "Why it is fine, e.g. \"coplanar faces hidden behind a sign\"."
            }
          },
          "required": [
            "key",
            "reason"
          ],
          "additionalProperties": false
        },
        "description": "Accept look or warn items you judged fine (up to 50 per call): [{key, reason}] with keys from this scene's issues. Written to res://.summer/audit-accept.json (the only file the audit writes), then counted (counts.<check>.accepted) but hidden on every later audit until their evidence changes materially (severity rises, or the measured size moves by over 25%): then they show again with accept_stale. Errors cannot be accepted."
      },
      "show_accepted": {
        "type": "boolean",
        "description": "List accepted items too (each with its accepted reason). Default false: hidden, only counted."
      },
      "render": {
        "type": "string",
        "enum": [
          "sheet",
          "none"
        ],
        "description": "\"sheet\": also return ONE inline image of the first 6 issues of this page framed up close from their open side, each tile labelled with its issue number. Default \"none\"."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Audit a 3D scene

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_scene_audit",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine scene-audit
  ```
</CodeGroup>

***

### screenshot

`engine.screenshot`: **Take a screenshot**

Return a frame as an image you see: the editor viewport, an offscreen render of a scene (preset, camera, bookmark or free pose, numbered marks) or the running game. A blank viewport frame means no redraw yet: capture again.

| | |
| - | - |
| **MCP** | `summer_screenshot` in the npm MCP |
| **CLI** | `summer engine screenshot` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_screenshot` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `target` | "viewport" \| "scene" \| "game" | No | "viewport" = editor current view (default), "scene" = offscreen render of a scene file, "game" = running game frame Default `"viewport"`. |
| `scenePath` | string | No | target:"scene" only. Full scene path, e.g. "res\://main.tscn". Omit to render the currently-open scene. |
| `framing` | "auto" \| "iso" \| "top" \| "front" \| "back" \| "left" \| "right" \| "camera" \| "free" \| "bookmark" | No | target:"scene" only, 3D scenes. Camera direction preset: "iso" = 3/4 diagonal view, "top" = straight down, "front" = camera at +Z, "back" = camera at -Z, "left" = camera at -X, "right" = camera at +X. "auto" (default) is an alias of "iso". "camera" = render through the scene's OWN Camera3D with its REAL WorldEnvironment - the only edit-time framing that truthfully shows lighting/mood. "bookmark" (+ bookmark\_name) = the fixed pose saved with summer\_camera\_bookmark; "free" (+ camera\_position, camera\_look\_at, fov) = an explicit fixed pose. Both keep the REAL WorldEnvironment and repeat exactly, so before/after frames line up. The result reports the resolved framing - an older engine echoes a preset instead, and the caption warns. |
| `bookmark_name` | string | No | framing:"bookmark" only (implies it when framing is omitted). Name of a bookmark saved with summer\_camera\_bookmark (list them with action:"list"). Fails with failure\_reason "unknown\_bookmark" (+ the available names) when it does not exist. |
| `size` | integer\[] | No | target:"scene" only. Output image \[width, height] in pixels. Items 2 to 2. |
| `nodePath` | string | No | target:"scene" only. Node path relative to the scene root (e.g. "Player/Mesh") to frame INSTEAD of the whole scene — the camera fits that node's combined bounds (3D visual AABBs or 2D rects, children included). A bare unique name is also found recursively. Fails with failure\_reason "node\_not\_found" when the path does not resolve (no silent whole-scene fallback). Cannot combine with a fixed pose (framing "camera"/"free"/"bookmark"). |
| `camera_path` | string | No | framing:"camera" only. Path of the Camera3D to render through (relative to the scene root) when the scene has several cameras or none marked current. Omit to use the scene's current/first Camera3D. |
| `camera_position` | string | No | framing:"free" only (implies it when framing is omitted). Camera position as a Godot literal, e.g. "Vector3(0, 5, 12)". Goes together with camera\_look\_at. |
| `camera_look_at` | string | No | framing:"free" only. Point the camera looks at, e.g. "Vector3(0, 1, 0)". Must differ from camera\_position. |
| `fov` | number | No | framing:"free" / "bookmark" only. Vertical field of view in degrees (1..179; default 60 for "free", the bookmark's own for "bookmark"). |
| `marks` | boolean | No | target:"scene" only, 3D scenes. Draw a Set-of-Mark overlay - numbered tags + box outlines over the largest visible VisualInstance3D nodes (lights excluded), ranked by projected screen area. The caption lists label -> node path (scene-root-relative) so you can name what you see, and an occlusion test (centre + 4 bounds points from the rendered camera) notes "(hidden behind \<path>)" on labels whose node is hidden - ignore those. Works with every framing. 2D scenes return marks\_unsupported. Default false. |
| `max_marks` | integer | No | marks:true only. Cap on numbered labels (engine default 32, at most 128). The caption says when the cap truncated the list. Range 1 to 128. |
| `compare_previous` | boolean | No | framing:"bookmark" only. Return ONE image of \[previous render \| now \| difference map] for the bookmark, with the share of changed pixels (summer\_shot\_sheet compare\_previous with this one bookmark); this render then replaces the bookmark's previous image in res\://.summer/shots/\<bookmark>.jpg. A plain bookmark render (no marks, at most 1024 px) only creates that image when it is missing and never overwrites the compare baseline. |
| `update_previous` | boolean | No | framing:"bookmark" only. Replace the bookmark's previous image (its compare baseline) with this clean render. Default false: an existing baseline is kept. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "target": {
        "type": "string",
        "enum": [
          "viewport",
          "scene",
          "game"
        ],
        "default": "viewport",
        "description": "\"viewport\" = editor current view (default), \"scene\" = offscreen render of a scene file, \"game\" = running game frame"
      },
      "scenePath": {
        "type": "string",
        "description": "target:\"scene\" only. Full scene path, e.g. \"res://main.tscn\". Omit to render the currently-open scene."
      },
      "framing": {
        "type": "string",
        "enum": [
          "auto",
          "iso",
          "top",
          "front",
          "back",
          "left",
          "right",
          "camera",
          "free",
          "bookmark"
        ],
        "description": "target:\"scene\" only, 3D scenes. Camera direction preset: \"iso\" = 3/4 diagonal view, \"top\" = straight down, \"front\" = camera at +Z, \"back\" = camera at -Z, \"left\" = camera at -X, \"right\" = camera at +X. \"auto\" (default) is an alias of \"iso\". \"camera\" = render through the scene's OWN Camera3D with its REAL WorldEnvironment - the only edit-time framing that truthfully shows lighting/mood. \"bookmark\" (+ bookmark_name) = the fixed pose saved with summer_camera_bookmark; \"free\" (+ camera_position, camera_look_at, fov) = an explicit fixed pose. Both keep the REAL WorldEnvironment and repeat exactly, so before/after frames line up. The result reports the resolved framing - an older engine echoes a preset instead, and the caption warns."
      },
      "bookmark_name": {
        "type": "string",
        "description": "framing:\"bookmark\" only (implies it when framing is omitted). Name of a bookmark saved with summer_camera_bookmark (list them with action:\"list\"). Fails with failure_reason \"unknown_bookmark\" (+ the available names) when it does not exist."
      },
      "size": {
        "type": "array",
        "items": {
          "type": "integer",
          "exclusiveMinimum": 0
        },
        "minItems": 2,
        "maxItems": 2,
        "description": "target:\"scene\" only. Output image [width, height] in pixels."
      },
      "nodePath": {
        "type": "string",
        "description": "target:\"scene\" only. Node path relative to the scene root (e.g. \"Player/Mesh\") to frame INSTEAD of the whole scene — the camera fits that node's combined bounds (3D visual AABBs or 2D rects, children included). A bare unique name is also found recursively. Fails with failure_reason \"node_not_found\" when the path does not resolve (no silent whole-scene fallback). Cannot combine with a fixed pose (framing \"camera\"/\"free\"/\"bookmark\")."
      },
      "camera_path": {
        "type": "string",
        "description": "framing:\"camera\" only. Path of the Camera3D to render through (relative to the scene root) when the scene has several cameras or none marked current. Omit to use the scene's current/first Camera3D."
      },
      "camera_position": {
        "type": "string",
        "description": "framing:\"free\" only (implies it when framing is omitted). Camera position as a Godot literal, e.g. \"Vector3(0, 5, 12)\". Goes together with camera_look_at."
      },
      "camera_look_at": {
        "type": "string",
        "description": "framing:\"free\" only. Point the camera looks at, e.g. \"Vector3(0, 1, 0)\". Must differ from camera_position."
      },
      "fov": {
        "type": "number",
        "description": "framing:\"free\" / \"bookmark\" only. Vertical field of view in degrees (1..179; default 60 for \"free\", the bookmark's own for \"bookmark\")."
      },
      "marks": {
        "type": "boolean",
        "description": "target:\"scene\" only, 3D scenes. Draw a Set-of-Mark overlay - numbered tags + box outlines over the largest visible VisualInstance3D nodes (lights excluded), ranked by projected screen area. The caption lists label -> node path (scene-root-relative) so you can name what you see, and an occlusion test (centre + 4 bounds points from the rendered camera) notes \"(hidden behind <path>)\" on labels whose node is hidden - ignore those. Works with every framing. 2D scenes return marks_unsupported. Default false."
      },
      "max_marks": {
        "type": "integer",
        "minimum": 1,
        "maximum": 128,
        "description": "marks:true only. Cap on numbered labels (engine default 32, at most 128). The caption says when the cap truncated the list."
      },
      "compare_previous": {
        "type": "boolean",
        "description": "framing:\"bookmark\" only. Return ONE image of [previous render | now | difference map] for the bookmark, with the share of changed pixels (summer_shot_sheet compare_previous with this one bookmark); this render then replaces the bookmark's previous image in res://.summer/shots/<bookmark>.jpg. A plain bookmark render (no marks, at most 1024 px) only creates that image when it is missing and never overwrites the compare baseline."
      },
      "update_previous": {
        "type": "boolean",
        "description": "framing:\"bookmark\" only. Replace the bookmark's previous image (its compare baseline) with this clean render. Default false: an existing baseline is kept."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Take a screenshot

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_screenshot",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine screenshot
  ```
</CodeGroup>

***

### select\_node

`engine.select_node`: **Select a node in the editor**

Select a node in the editor's scene tree and show it in the inspector, so the person sees it. The scene does not change.

| | |
| - | - |
| **MCP** | `summer_select_node` in the npm MCP |
| **CLI** | `summer engine select-node` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_select_node` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `nodePath` | string | Yes | Node path to select |
| `scenePath` | string | No | Open this scene first, then select the node |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "nodePath": {
        "type": "string",
        "description": "Node path to select"
      },
      "scenePath": {
        "type": "string",
        "description": "Open this scene first, then select the node"
      }
    },
    "required": [
      "nodePath"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Select a node in the editor

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_select_node",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine select-node
  ```
</CodeGroup>

***

### set\_prop

`engine.set_prop`: **Set a node property**

Set one property of a node in the scene at scenePath and save it. Values use Godot syntax: "Vector3(0, 1, 0)", "Color(1, 0, 0, 1)", or a resource class such as "BoxMesh". For 3 or more edits, write one engine.run\_script.

| | |
| - | - |
| **MCP** | `summer_set_prop` in the npm MCP |
| **CLI** | `summer engine set-prop` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_set_prop` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene path, e.g. 'res\://main.tscn' |
| `path` | string | Yes | Node path, e.g. `./World/Player` |
| `key` | string | Yes | Property name, e.g. 'position', 'mesh', 'visible' |
| `value` | string \| number \| boolean | Yes | Value in Summer Engine variant-string format for complex types, native JSON for primitives |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene path, e.g. 'res://main.tscn'"
      },
      "path": {
        "type": "string",
        "description": "Node path, e.g. './World/Player'"
      },
      "key": {
        "type": "string",
        "description": "Property name, e.g. 'position', 'mesh', 'visible'"
      },
      "value": {
        "type": [
          "string",
          "number",
          "boolean"
        ],
        "description": "Value in Summer Engine variant-string format for complex types, native JSON for primitives"
      }
    },
    "required": [
      "scenePath",
      "path",
      "key",
      "value"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Set a node property

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_set_prop",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine set-prop
  ```
</CodeGroup>

***

### set\_resource\_property

`engine.set_resource_property`: **Set a property of a node's resource**

Set a property inside a resource a node holds, such as a collision shape's size or a material's albedo\_color, and save the scene. The resource must exist first: assign it with engine.set\_prop.

| | |
| - | - |
| **MCP** | `summer_set_resource_property` in the npm MCP |
| **CLI** | `summer engine set-resource-property` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_set_resource_property` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Target scene path, e.g. 'res\://main.tscn' |
| `nodePath` | string | Yes | Node path, e.g. `./Player/CollisionShape3D` |
| `resourceProperty` | string | Yes | Resource property on the node, e.g. 'shape', 'mesh', 'material\_override' |
| `subProperty` | string | Yes | Property on the resource, e.g. 'size', 'radius', 'albedo\_color' |
| `value` | string \| number \| boolean | Yes | Value in Summer Engine variant-string format |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Target scene path, e.g. 'res://main.tscn'"
      },
      "nodePath": {
        "type": "string",
        "description": "Node path, e.g. './Player/CollisionShape3D'"
      },
      "resourceProperty": {
        "type": "string",
        "description": "Resource property on the node, e.g. 'shape', 'mesh', 'material_override'"
      },
      "subProperty": {
        "type": "string",
        "description": "Property on the resource, e.g. 'size', 'radius', 'albedo_color'"
      },
      "value": {
        "type": [
          "string",
          "number",
          "boolean"
        ],
        "description": "Value in Summer Engine variant-string format"
      }
    },
    "required": [
      "scenePath",
      "nodePath",
      "resourceProperty",
      "subProperty",
      "value"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Set a property of a node's resource

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_set_resource_property",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine set-resource-property
  ```
</CodeGroup>

***

### shot\_sheet

`engine.shot_sheet`: **Render a sheet of views**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Render several bookmarks or poses into one labelled grid with real lighting, and compare each bookmark with its last render (difference map). The quick look at every hero view after a change.

| | |
| - | - |
| **MCP** | `summer_shot_sheet` in the npm MCP |
| **CLI** | `summer engine shot-sheet` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_shot_sheet` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Scene to look at, e.g. "res\://levels/town.tscn" (the SAVED file). Omit for the scene open in the editor. |
| `shots` | object\[] | Yes | 1-12 shots, each a bookmark\_name OR camera\_position + camera\_look\_at (+ fov), with an optional label. Rendered in this order, left to right, top to bottom. Items 1 to 12. |
| `shots[].bookmark_name` | string | No | Pose from a camera bookmark (summer\_camera\_bookmark). Use INSTEAD of camera\_position/camera\_look\_at. |
| `shots[].camera_position` | string | No | Explicit pose: camera position, "Vector3(x, y, z)". Goes with camera\_look\_at. |
| `shots[].camera_look_at` | string | No | Explicit pose: point the camera looks at, "Vector3(x, y, z)". |
| `shots[].fov` | number | No | Vertical field of view in degrees (1..179). Default: the bookmark's own, or 60. |
| `shots[].label` | string | No | Tile label (1-64 printable characters, no quotes, backslashes or \$). Default: the bookmark name or 'shot N'. |
| `view` | "beauty" \| "lighting" \| "unshaded" \| "normals" \| "overdraw" \| "wireframe" | No | "beauty" (default: real environment, lights, fog, tonemap), "lighting" (light only), "unshaded" (albedo/texture only), "normals" (world normals, x red y green z blue), "overdraw", "wireframe". |
| `compare_previous` | boolean | No | For bookmark shots: one row per bookmark of \[previous render \| now \| difference map], with the share of changed pixels in the caption. The previous render is the bookmark's slot in res\://.summer/shots/; this render replaces it (it is the next baseline). |
| `update_previous` | boolean | No | Replace each bookmark's previous image (its compare baseline) with this render without comparing. Default false: a sheet without compare\_previous only creates a missing slot and never overwrites an existing baseline. |
| `max_size` | integer | No | Longest edge of the returned JPEG in pixels (default 1536). Bigger costs more context; up to 4096 for detail work on a PC. Range 64 to 4096. |
| `aspect` | number | No | Frame width/height (default 1.7778 = 16:9). Every tile uses it. |
| `save_to` | string | No | Also write the returned image to res\://.summer/shots/saved/\<name>.jpg (1-64 of A-Z a-z 0-9 \\\_ -; needs max\_size \<= 1024). Nothing is written without it, except one previous-image slot per rendered bookmark (created when missing; replaced only by compare\_previous or update\_previous). |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to look at, e.g. \"res://levels/town.tscn\" (the SAVED file). Omit for the scene open in the editor."
      },
      "shots": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "bookmark_name": {
              "type": "string",
              "description": "Pose from a camera bookmark (summer_camera_bookmark). Use INSTEAD of camera_position/camera_look_at."
            },
            "camera_position": {
              "type": "string",
              "description": "Explicit pose: camera position, \"Vector3(x, y, z)\". Goes with camera_look_at."
            },
            "camera_look_at": {
              "type": "string",
              "description": "Explicit pose: point the camera looks at, \"Vector3(x, y, z)\"."
            },
            "fov": {
              "type": "number",
              "description": "Vertical field of view in degrees (1..179). Default: the bookmark's own, or 60."
            },
            "label": {
              "type": "string",
              "description": "Tile label (1-64 printable characters, no quotes, backslashes or $). Default: the bookmark name or 'shot N'."
            }
          },
          "additionalProperties": false
        },
        "minItems": 1,
        "maxItems": 12,
        "description": "1-12 shots, each a bookmark_name OR camera_position + camera_look_at (+ fov), with an optional label. Rendered in this order, left to right, top to bottom."
      },
      "view": {
        "type": "string",
        "enum": [
          "beauty",
          "lighting",
          "unshaded",
          "normals",
          "overdraw",
          "wireframe"
        ],
        "description": "\"beauty\" (default: real environment, lights, fog, tonemap), \"lighting\" (light only), \"unshaded\" (albedo/texture only), \"normals\" (world normals, x red y green z blue), \"overdraw\", \"wireframe\"."
      },
      "compare_previous": {
        "type": "boolean",
        "description": "For bookmark shots: one row per bookmark of [previous render | now | difference map], with the share of changed pixels in the caption. The previous render is the bookmark's slot in res://.summer/shots/; this render replaces it (it is the next baseline)."
      },
      "update_previous": {
        "type": "boolean",
        "description": "Replace each bookmark's previous image (its compare baseline) with this render without comparing. Default false: a sheet without compare_previous only creates a missing slot and never overwrites an existing baseline."
      },
      "max_size": {
        "type": "integer",
        "minimum": 64,
        "maximum": 4096,
        "description": "Longest edge of the returned JPEG in pixels (default 1536). Bigger costs more context; up to 4096 for detail work on a PC."
      },
      "aspect": {
        "type": "number",
        "description": "Frame width/height (default 1.7778 = 16:9). Every tile uses it."
      },
      "save_to": {
        "type": "string",
        "description": "Also write the returned image to res://.summer/shots/saved/<name>.jpg (1-64 of A-Z a-z 0-9 _ -; needs max_size <= 1024). Nothing is written without it, except one previous-image slot per rendered bookmark (created when missing; replaced only by compare_previous or update_previous)."
      }
    },
    "required": [
      "shots"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Render a sheet of views

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_shot_sheet",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine shot-sheet
  ```
</CodeGroup>

***

### snap\_to\_surface

`engine.snap_to_surface`: **Snap a node onto a surface**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Move one 3D node along a ray until it sits at the given gap on the first surface (floor, ramp, shelf, table), then save the scene. Returns before and after transforms and the evidence.

| | |
| - | - |
| **MCP** | `summer_snap_to_surface` in the npm MCP |
| **CLI** | `summer engine snap-to-surface` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_snap_to_surface` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene containing the subject, e.g. 'res\://levels/market.tscn'. Length 1 to 512. |
| `subjectPath` | string | Yes | Exact Node3D path relative to the scene root, e.g. `./Props/Crate`. Length 1 to 256. |
| `direction` | number\[] | No | Finite world-space cast direction \[x,y,z] whose squared length exceeds 0.00001. Defaults downward. Default `[0,-1,0]`. Items 3 to 3. |
| `maxDistance` | number | No | Maximum cast and overlap-recovery distance in scene units. Default `20`. Range … to 10000. |
| `gap` | number | No | Requested separation from the support surface; must not exceed maxDistance. Default `0`. Range 0 to 10000. |
| `alignUp` | boolean | No | Rotate the subject's current world up toward an exact physics contact normal before seating it. Default `false`. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene containing the subject, e.g. 'res://levels/market.tscn'."
      },
      "subjectPath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Exact Node3D path relative to the scene root, e.g. './Props/Crate'."
      },
      "direction": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 3,
        "maxItems": 3,
        "default": [
          0,
          -1,
          0
        ],
        "description": "Finite world-space cast direction [x,y,z] whose squared length exceeds 0.00001. Defaults downward."
      },
      "maxDistance": {
        "type": "number",
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "default": 20,
        "description": "Maximum cast and overlap-recovery distance in scene units."
      },
      "gap": {
        "type": "number",
        "minimum": 0,
        "maximum": 10000,
        "default": 0,
        "description": "Requested separation from the support surface; must not exceed maxDistance."
      },
      "alignUp": {
        "type": "boolean",
        "default": false,
        "description": "Rotate the subject's current world up toward an exact physics contact normal before seating it."
      }
    },
    "required": [
      "scenePath",
      "subjectPath"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Snap a node onto a surface

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_snap_to_surface",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine snap-to-surface
  ```
</CodeGroup>

***

### snapshot\_diff

`engine.snapshot_diff`: **Compare two scene snapshots**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Compare two scene snapshots: added, removed and changed nodes and count changes. The proof that a change did what you meant; an empty diff after a change means it did not land. Next: engine.screenshot.

| | |
| - | - |
| **MCP** | `summer_snapshot_diff` in the npm MCP |
| **CLI** | `summer engine snapshot-diff` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_snapshot_diff` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `from_id` | string | Yes | snapshot\_id of the BEFORE snapshot (from summer\_world\_snapshot). |
| `to_id` | string | No | snapshot\_id of the AFTER snapshot. Omit to snapshot the current state now and diff against that. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "from_id": {
        "type": "string",
        "description": "snapshot_id of the BEFORE snapshot (from summer_world_snapshot)."
      },
      "to_id": {
        "type": "string",
        "description": "snapshot_id of the AFTER snapshot. Omit to snapshot the current state now and diff against that."
      }
    },
    "required": [
      "from_id"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Compare two scene snapshots

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_snapshot_diff",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine snapshot-diff
  ```
</CodeGroup>

***

### starcast

`engine.starcast`: **Read the space around a node**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read the clearance around one 3D node in 26 directions: what blocks each side and how far, contact, grounding and nearby objects. Changes nothing. Use it before and after placing.

| | |
| - | - |
| **MCP** | `summer_starcast` in the npm MCP |
| **CLI** | `summer engine starcast` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_starcast` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene containing the subject, e.g. 'res\://levels/level1.tscn'. Length 1 to 512. |
| `path` | string | Yes | Exact Node3D path relative to the scene root, e.g. `./World/Crate`. Length 1 to 256. |
| `detail` | "summary" \| "full" | No | summary: compact placement report (at most 5 KB). full: adds bounded hit geometry, an objects table, and nearby lists (at most 12 KB; the engine downgrades to summary rather than exceed it). Default `"summary"`. |
| `maxDistance` | number | No | Maximum outward cast distance in scene units. Default `20`. Range … to 10000. |
| `nearbyRadius` | number | No | Maximum gap from the subject bounds for the nearby-object lists (full detail). Default `10`. Range 0 to 10000. |
| `directionSpace` | "world" \| "local" | No | Cast along world axes, or along the subject's orthonormalized local axes for rotated subjects. Default `"world"`. |
| `collisionMask` | integer | No | Godot 3D physics layer mask queried by rays, shape contacts/overlaps, and nearby-collider scans. Default `4294967295`. Range 0 to 4294967295. |
| `collideWithAreas` | boolean | No | Include Area3D objects as well as physics bodies. Default `true`. |
| `maxHitsPerDirection` | integer | No | Maximum physics hits and visual AABB hits retained for each direction. Default `3`. Range 1 to 8. |
| `maxResults` | integer | No | Maximum retained contact/overlap and nearby entries per evidence channel. Default `64`. Range 1 to 128. |
| `margin` | number | No | Tolerance for exact-geometry physics shape intersection queries; touching and candidates within this margin are reported as contact\_or\_overlap. Default `0.001`. Range 0 to 1. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene containing the subject, e.g. 'res://levels/level1.tscn'."
      },
      "path": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Exact Node3D path relative to the scene root, e.g. './World/Crate'."
      },
      "detail": {
        "type": "string",
        "enum": [
          "summary",
          "full"
        ],
        "default": "summary",
        "description": "summary: compact placement report (at most 5 KB). full: adds bounded hit geometry, an objects table, and nearby lists (at most 12 KB; the engine downgrades to summary rather than exceed it)."
      },
      "maxDistance": {
        "type": "number",
        "exclusiveMinimum": 0,
        "maximum": 10000,
        "default": 20,
        "description": "Maximum outward cast distance in scene units."
      },
      "nearbyRadius": {
        "type": "number",
        "minimum": 0,
        "maximum": 10000,
        "default": 10,
        "description": "Maximum gap from the subject bounds for the nearby-object lists (full detail)."
      },
      "directionSpace": {
        "type": "string",
        "enum": [
          "world",
          "local"
        ],
        "default": "world",
        "description": "Cast along world axes, or along the subject's orthonormalized local axes for rotated subjects."
      },
      "collisionMask": {
        "type": "integer",
        "minimum": 0,
        "maximum": 4294967295,
        "default": 4294967295,
        "description": "Godot 3D physics layer mask queried by rays, shape contacts/overlaps, and nearby-collider scans."
      },
      "collideWithAreas": {
        "type": "boolean",
        "default": true,
        "description": "Include Area3D objects as well as physics bodies."
      },
      "maxHitsPerDirection": {
        "type": "integer",
        "minimum": 1,
        "maximum": 8,
        "default": 3,
        "description": "Maximum physics hits and visual AABB hits retained for each direction."
      },
      "maxResults": {
        "type": "integer",
        "minimum": 1,
        "maximum": 128,
        "default": 64,
        "description": "Maximum retained contact/overlap and nearby entries per evidence channel."
      },
      "margin": {
        "type": "number",
        "minimum": 0,
        "maximum": 1,
        "default": 0.001,
        "description": "Tolerance for exact-geometry physics shape intersection queries; touching and candidates within this margin are reported as contact_or_overlap."
      }
    },
    "required": [
      "scenePath",
      "path"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read the space around a node

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_starcast",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine starcast
  ```
</CodeGroup>

***

### stop

`engine.stop`: **Stop the game**

Stop the running game, or one offscreen instance by name. Scene edits stay as they are; nothing is undone or saved.

| | |
| - | - |
| **MCP** | `summer_stop` in the npm MCP |
| **CLI** | `summer engine stop` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_stop` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `instance` | string | No | Offscreen instance name to stop (from summer\_play instance); omit for the main embedded game. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "instance": {
        "type": "string",
        "description": "Offscreen instance name to stop (from summer_play instance); omit for the main embedded game."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Stop the game

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_stop",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine stop
  ```
</CodeGroup>

***

### test\_placement

`engine.test_placement`: **Test a placement without moving**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Test one 3D node at a candidate world position and rotation without moving it: overlaps, grounded state and the gap to the floor. Changes nothing. Then place it with engine.set\_prop or engine.snap\_to\_surface.

| | |
| - | - |
| **MCP** | `summer_test_placement` in the npm MCP |
| **CLI** | `summer engine test-placement` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_test_placement` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | Yes | Exact scene path containing the subject, e.g. 'res\://levels/workshop.tscn'. Length 1 to 512. |
| `subjectPath` | string | Yes | Exact node path relative to the scene root, e.g. `./World/Crate`. Length 1 to 256. |
| `candidateGlobalPosition` | number\[] | Yes | Candidate global/world position as \[x, y, z]. Items 3 to 3. |
| `candidateGlobalRotationDegrees` | number\[] | Yes | Candidate global/world Euler rotation in degrees as \[x, y, z]; current global scale is preserved. Items 3 to 3. |
| `collisionMask` | integer | No | Godot 3D physics layers included in overlap and floor queries. Default `4294967295`. Range 0 to 4294967295. |
| `collideWithAreas` | boolean | No | Include Area3D objects as placement obstacles/support candidates. Default `true`. |
| `maxFloorDistance` | number | No | Maximum world-space distance searched below the candidate footprint; range 0.001..1000. Default `5`. Range 0.001 to 1000. |
| `groundTolerance` | number | No | Absolute floor-gap tolerance used to classify grounded support. Default `0.05`. Range 0 to 1. |
| `margin` | number | No | Physics shape-intersection margin; only an exact physics support collider+shape contact is excluded from overlaps. Default `0.001`. Range 0 to 1. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512,
        "description": "Exact scene path containing the subject, e.g. 'res://levels/workshop.tscn'."
      },
      "subjectPath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 256,
        "description": "Exact node path relative to the scene root, e.g. './World/Crate'."
      },
      "candidateGlobalPosition": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 3,
        "maxItems": 3,
        "description": "Candidate global/world position as [x, y, z]."
      },
      "candidateGlobalRotationDegrees": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 3,
        "maxItems": 3,
        "description": "Candidate global/world Euler rotation in degrees as [x, y, z]; current global scale is preserved."
      },
      "collisionMask": {
        "type": "integer",
        "minimum": 0,
        "maximum": 4294967295,
        "default": 4294967295,
        "description": "Godot 3D physics layers included in overlap and floor queries."
      },
      "collideWithAreas": {
        "type": "boolean",
        "default": true,
        "description": "Include Area3D objects as placement obstacles/support candidates."
      },
      "maxFloorDistance": {
        "type": "number",
        "minimum": 0.001,
        "maximum": 1000,
        "default": 5,
        "description": "Maximum world-space distance searched below the candidate footprint; range 0.001..1000."
      },
      "groundTolerance": {
        "type": "number",
        "minimum": 0,
        "maximum": 1,
        "default": 0.05,
        "description": "Absolute floor-gap tolerance used to classify grounded support."
      },
      "margin": {
        "type": "number",
        "minimum": 0,
        "maximum": 1,
        "default": 0.001,
        "description": "Physics shape-intersection margin; only an exact physics support collider+shape contact is excluded from overlaps."
      }
    },
    "required": [
      "scenePath",
      "subjectPath",
      "candidateGlobalPosition",
      "candidateGlobalRotationDegrees"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Test a placement without moving

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_test_placement",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine test-placement
  ```
</CodeGroup>

***

### ui\_activate

`engine.ui_activate`: **Use an editor control**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Use one editor control by its tree path (press, toggle, focus, select a tab, type text, set a value) or dismiss a dialog; the control's state is read back. Only when no named action fits.

| | |
| - | - |
| **MCP** | `summer_ui_activate` in the npm MCP |
| **CLI** | `summer engine ui-activate` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_ui_activate` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `action` | "press" \| "toggle" \| "focus" \| "select\_tab" \| "set\_text" \| "set\_value" \| "dismiss\_dialog" | No | Default 'press'. press = synthetic left click on a button / ItemList item / PopupMenu item (index); toggle = flip a toggle-mode button; focus = grab\_focus on any control; select\_tab = TabContainer/TabBar by value (title) or index — and the synthetic path 'main\_screen' switches the 2D/3D/Script/Game/AssetLib editor; set\_text = LineEdit/TextEdit text (submit true also emits text\_submitted); set\_value = Range (SpinBox/Slider) number; dismiss\_dialog = close a visible dialog by path or title (UiDismissDialog). |
| `path` | string | No | A control path from summer\_ui\_tree (required for every action except dismiss\_dialog, which may use title instead), or 'main\_screen' with action select\_tab. Auto-named paths are stable within a session only — re-read the tree rather than persist them. |
| `value` | string \| number | No | select\_tab: tab title (or the main-screen editor name '2D', '3D', 'Script', 'Game', 'AssetLib'); set\_text: the text; set\_value: the number. |
| `index` | integer | No | select\_tab: tab index; press on an ItemList / PopupMenu: item index. Range 0 to …. |
| `submit` | boolean | No | set\_text on a LineEdit only — also emit text\_submitted (the Enter key), e.g. to run a search box. |
| `title` | string | No | dismiss\_dialog only — a visible window title (case-insensitive; exact wins, one substring match accepted, otherwise ambiguous\_dialog) from summer\_ui\_tree root dialogs. |
| `button` | string | No | dismiss\_dialog only. 'cancel' (default — the safe close), 'ok', or the exact text of a button in the dialog's row. Buttons whose label quits or reloads the editor are denied by the engine. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": [
          "press",
          "toggle",
          "focus",
          "select_tab",
          "set_text",
          "set_value",
          "dismiss_dialog"
        ],
        "description": "Default 'press'. press = synthetic left click on a button / ItemList item / PopupMenu item (index); toggle = flip a toggle-mode button; focus = grab_focus on any control; select_tab = TabContainer/TabBar by value (title) or index — and the synthetic path 'main_screen' switches the 2D/3D/Script/Game/AssetLib editor; set_text = LineEdit/TextEdit text (submit true also emits text_submitted); set_value = Range (SpinBox/Slider) number; dismiss_dialog = close a visible dialog by path or title (UiDismissDialog)."
      },
      "path": {
        "type": "string",
        "description": "A control path from summer_ui_tree (required for every action except dismiss_dialog, which may use title instead), or 'main_screen' with action select_tab. Auto-named paths are stable within a session only — re-read the tree rather than persist them."
      },
      "value": {
        "type": [
          "string",
          "number"
        ],
        "description": "select_tab: tab title (or the main-screen editor name '2D', '3D', 'Script', 'Game', 'AssetLib'); set_text: the text; set_value: the number."
      },
      "index": {
        "type": "integer",
        "minimum": 0,
        "description": "select_tab: tab index; press on an ItemList / PopupMenu: item index."
      },
      "submit": {
        "type": "boolean",
        "description": "set_text on a LineEdit only — also emit text_submitted (the Enter key), e.g. to run a search box."
      },
      "title": {
        "type": "string",
        "description": "dismiss_dialog only — a visible window title (case-insensitive; exact wins, one substring match accepted, otherwise ambiguous_dialog) from summer_ui_tree root dialogs."
      },
      "button": {
        "type": "string",
        "description": "dismiss_dialog only. 'cancel' (default — the safe close), 'ok', or the exact text of a button in the dialog's row. Buttons whose label quits or reloads the editor are denied by the engine."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Use an editor control

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_ui_activate",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine ui-activate
  ```
</CodeGroup>

***

### ui\_screenshot

`engine.ui_screenshot`: **Screenshot the editor UI**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Return an image of the editor window, or of one dock, dialog or control: the last resort to look at the UI, never to pick click points. For scene views use engine.screenshot.

| | |
| - | - |
| **MCP** | `summer_ui_screenshot` in the npm MCP |
| **CLI** | `summer engine ui-screenshot` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_ui_screenshot` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `root` | string | No | Same grammar as summer\_ui\_tree root — 'window' (default; the whole editor window), 'main', 'dock:\<title\|id>', 'dialog:\<title>', 'path:\<node path>'. A Control or embedded dialog is cropped out of the root viewport texture; a native OS sub-window is not in it (native\_subwindow). |
| `max_size` | integer | No | Longest edge in pixels after downscale (engine default 1024, clamped 16-4096). Smaller is cheaper to look at; the result reports scale. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "root": {
        "type": "string",
        "description": "Same grammar as summer_ui_tree root — 'window' (default; the whole editor window), 'main', 'dock:<title|id>', 'dialog:<title>', 'path:<node path>'. A Control or embedded dialog is cropped out of the root viewport texture; a native OS sub-window is not in it (native_subwindow)."
      },
      "max_size": {
        "type": "integer",
        "description": "Longest edge in pixels after downscale (engine default 1024, clamped 16-4096). Smaller is cheaper to look at; the result reports scale."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Screenshot the editor UI

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_ui_screenshot",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine ui-screenshot
  ```
</CodeGroup>

***

### ui\_tree

`engine.ui_tree`: **Read the editor UI**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Read the live editor UI as a tree (controls, paths, text, state), or every visible dialog and whether one blocks input. Its paths are what engine.ui\_activate takes.

| | |
| - | - |
| **MCP** | `summer_ui_tree` in the npm MCP |
| **CLI** | `summer engine ui-tree` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_ui_tree` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `root` | string | No | Where to start. 'main' (default) = the whole editor chrome; 'window' = the SceneTree root incl. every sub-window; 'dock:\<title\|id>' = one dock (ids file\_system \| scene\_tree \| inspector, or any dock title, case-insensitive); 'dialog:\<title>' = one visible window; 'path:\<node path>' = a path from an earlier result. 'dialogs' = list every visible dialog/popup with its blocking flag and buttons instead of a tree (UiDialogs). |
| `depth` | integer | No | Tree depth (engine default 4, max 32). Plain Nodes between Controls do not consume depth. Range 1 to …. |
| `limit` | integer | No | Maximum Control nodes emitted (engine default 500, max 5000). The result carries truncated + child\_count so a cut is visible. Range 1 to …. |
| `visible_only` | boolean | No | Default true. false also emits hidden controls — readable, but summer\_ui\_activate refuses them with not\_visible. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "root": {
        "type": "string",
        "description": "Where to start. 'main' (default) = the whole editor chrome; 'window' = the SceneTree root incl. every sub-window; 'dock:<title|id>' = one dock (ids file_system | scene_tree | inspector, or any dock title, case-insensitive); 'dialog:<title>' = one visible window; 'path:<node path>' = a path from an earlier result. 'dialogs' = list every visible dialog/popup with its blocking flag and buttons instead of a tree (UiDialogs)."
      },
      "depth": {
        "type": "integer",
        "minimum": 1,
        "description": "Tree depth (engine default 4, max 32). Plain Nodes between Controls do not consume depth."
      },
      "limit": {
        "type": "integer",
        "minimum": 1,
        "description": "Maximum Control nodes emitted (engine default 500, max 5000). The result carries truncated + child_count so a cut is visible."
      },
      "visible_only": {
        "type": "boolean",
        "description": "Default true. false also emits hidden controls — readable, but summer_ui_activate refuses them with not_visible."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Read the editor UI

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_ui_tree",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine ui-tree
  ```
</CodeGroup>

***

### wait\_for\_event

`engine.wait_for_event`: **Wait for an engine event**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Wait for an engine event (game started, op applied or failed, script error, scene saved) instead of sleeping; it says so honestly at the timeout. Take a cursor with engine.recent\_events first.

| | |
| - | - |
| **MCP** | `summer_wait_for_event` in the npm MCP |
| **CLI** | `summer engine wait-for-event` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_wait_for_event` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `kinds` | string\[] | No | Event kinds to deliver (default: all). v1 kinds: op.applied, op.failed, script.error, play.started, play.stopped, scene.saved, scene.opened, import.completed, selection.changed, snapshot.published. Unknown kinds are refused before waiting when the engine advertises its list. |
| `since` | integer | No | Deliver events with seq > since. Omit = live from now (an event that already fired is NOT delivered — take a cursor with summer\_recent\_events first and pass its next\_seq here). 0 = replay the retained ring. Range 0 to …. |
| `timeout_seconds` | number | No | How long to wait for a match (default 30, clamped 1-120). The call long-polls in slices of at most 25 s. Default `30`. |
| `match` | object | No | Extra client-side filters applied after the kinds filter. |
| `match.requestId` | string | No | Only op.applied / op.failed events for this requestId match; every other kind passes through. |
| `max_events` | integer | No | Maximum matched events to return (default 20, cap 500). Default `20`. Range 1 to …. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "kinds": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "Event kinds to deliver (default: all). v1 kinds: op.applied, op.failed, script.error, play.started, play.stopped, scene.saved, scene.opened, import.completed, selection.changed, snapshot.published. Unknown kinds are refused before waiting when the engine advertises its list."
      },
      "since": {
        "type": "integer",
        "minimum": 0,
        "description": "Deliver events with seq > since. Omit = live from now (an event that already fired is NOT delivered — take a cursor with summer_recent_events first and pass its next_seq here). 0 = replay the retained ring."
      },
      "timeout_seconds": {
        "type": "number",
        "default": 30,
        "description": "How long to wait for a match (default 30, clamped 1-120). The call long-polls in slices of at most 25 s."
      },
      "match": {
        "type": "object",
        "description": "Extra client-side filters applied after the kinds filter.",
        "properties": {
          "requestId": {
            "type": "string",
            "description": "Only op.applied / op.failed events for this requestId match; every other kind passes through."
          }
        },
        "additionalProperties": false
      },
      "max_events": {
        "type": "integer",
        "minimum": 1,
        "default": 20,
        "description": "Maximum matched events to return (default 20, cap 500)."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Wait for an engine event

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_wait_for_event",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine wait-for-event
  ```
</CodeGroup>

***

### world\_snapshot

`engine.world_snapshot`: **Take a scene snapshot**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Take a structured snapshot of the edited scene: node paths, transforms, world bounds, fingerprints and counts, filtered by subtree, class or field. Returns snapshot\_id, the baseline to diff after a change. Next: engine.snapshot\_diff.

| | |
| - | - |
| **MCP** | `summer_world_snapshot` in the npm MCP |
| **CLI** | `summer engine world-snapshot` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_world_snapshot` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scene_path` | string | No | Scene to snapshot, e.g. 'res\://main.tscn'. Omit for the currently edited scene. |
| `max_nodes` | integer | No | Most node entries to return (default 200). The engine still snapshots the whole scene for the diff baseline; the result says when the list is cut (truncated, next\_offset). |
| `offset` | integer | No | Skip this many matching nodes (path-sorted) before listing — page with the result's next\_offset. Range 0 to …. |
| `path_prefix` | string | No | Only this subtree, the node at this scene-relative path and everything below it, e.g. 'House3' or 'Lane2/Props'. |
| `classes` | string\[] | No | Only nodes of these classes, e.g. \['MeshInstance3D', 'OmniLight3D'] (\* wildcards allowed). Items 0 to 32. |
| `fields` | string\[] | No | Only these per-node fields (path is always kept): class, name, pos, rot\_deg, scale, visible, aabb, scene\_file, script\_fp, material\_fps, z\_index, rect, view\_rect, limit\_rect. Items 0 to 16. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scene_path": {
        "type": "string",
        "description": "Scene to snapshot, e.g. 'res://main.tscn'. Omit for the currently edited scene."
      },
      "max_nodes": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "description": "Most node entries to return (default 200). The engine still snapshots the whole scene for the diff baseline; the result says when the list is cut (truncated, next_offset)."
      },
      "offset": {
        "type": "integer",
        "minimum": 0,
        "description": "Skip this many matching nodes (path-sorted) before listing — page with the result's next_offset."
      },
      "path_prefix": {
        "type": "string",
        "description": "Only this subtree, the node at this scene-relative path and everything below it, e.g. 'House3' or 'Lane2/Props'."
      },
      "classes": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "maxItems": 32,
        "description": "Only nodes of these classes, e.g. ['MeshInstance3D', 'OmniLight3D'] (* wildcards allowed)."
      },
      "fields": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "maxItems": 16,
        "description": "Only these per-node fields (path is always kept): class, name, pos, rot_deg, scale, visible, aabb, scene_file, script_fp, material_fps, z_index, rect, view_rect, limit_rect."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Take a scene snapshot

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_world_snapshot",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine world-snapshot
  ```
</CodeGroup>

***

### write\_file

`engine.write_file`: **Write a project file**

Create a text file (create\_only true) or overwrite one (expected\_sha256 from engine.read\_file); exactly one guard is required, so a stale write fails. Scripts, scenes, resources, JSON. Then check scripts with engine.get\_script\_errors.

| | |
| - | - |
| **MCP** | `summer_write_file` in the npm MCP |
| **CLI** | `summer engine write-file` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Changes your own drafts, files or settings. Nobody else sees it yet. |
| **Asks you first** | No: **Make and build** is on by default in Agent permissions. When it is off, your agent asks you first. |
| **3.x names** | `summer_write_file` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `path` | string | Yes | Project path, e.g. res\://scenes/player.tscn |
| `content` | string | Yes | Complete new UTF-8 file content. |
| `create_only` | boolean | No | Required for a new file; refuses if the path already exists. |
| `expected_sha256` | string | No | Required for overwriting an existing file; obtain from summer\_read\_file. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "Project path, e.g. res://scenes/player.tscn"
      },
      "content": {
        "type": "string",
        "description": "Complete new UTF-8 file content."
      },
      "create_only": {
        "type": "boolean",
        "description": "Required for a new file; refuses if the path already exists."
      },
      "expected_sha256": {
        "type": "string",
        "description": "Required for overwriting an existing file; obtain from summer_read_file."
      }
    },
    "required": [
      "path",
      "content"
    ],
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Write a project file

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_write_file",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine write-file
  ```
</CodeGroup>

***

### zoom

`engine.zoom`: **Zoom into part of a frame**

<Note>Preview: search finds it and `summer_call` runs it. It may still change.</Note>

Render a close-up of part of a frame (a region, or mark N of a marks render) at full resolution: real detail, seams and gaps, not enlarged pixels.

| | |
| - | - |
| **MCP** | `summer_zoom` in the npm MCP |
| **CLI** | `summer engine zoom` |
| **Runs** | In Summer Engine on your computer, through the npm MCP. Open your project first. |
| **Effect** | Reads only. Changes nothing. |
| **Asks you first** | No. It changes nothing. |
| **3.x names** | `summer_zoom` |

**Inputs:**

| Input | Type | Required | Description |
| - | - | - | - |
| `scenePath` | string | No | Scene to look at, e.g. "res\://levels/town.tscn" (the SAVED file). Omit for the scene open in the editor. |
| `bookmark_name` | string | No | Pose from a camera bookmark (summer\_camera\_bookmark). Use INSTEAD of camera\_position/camera\_look\_at. |
| `camera_position` | string | No | Explicit pose: camera position, "Vector3(x, y, z)". Goes with camera\_look\_at. |
| `camera_look_at` | string | No | Explicit pose: point the camera looks at, "Vector3(x, y, z)". |
| `fov` | number | No | Vertical field of view in degrees (1..179). Default: the bookmark's own, or 60. |
| `region` | number\[] | No | \[x, y, w, h] as fractions (0..1) of the frame from the same pose, x/y from the TOP-LEFT. Use this OR mark. Rendered EXACTLY (no padding by default, never widened to an aspect ratio): the image takes the region's own aspect, with dark bars only for extreme shapes. Items 4 to 4. |
| `mark` | integer | No | A label number from a marks:true render of the SAME pose and reference\_size (summer\_frame\_nodes, or summer\_screenshot framing free/bookmark at that size). The caption warns when that node is hidden behind other geometry at this pose. |
| `reference_size` | integer\[] | No | \[width, height] of the frame region/mark refer to (default \[1024, 576]). Sets the zoom's aspect. Items 2 to 2. |
| `pad` | number | No | Margin added around the region on each side, as a fraction of its size (0..1; default 0 for region, 0.15 for mark). The caption's widened\_because says when the rendered window is larger than asked. |
| `view` | "beauty" \| "lighting" \| "unshaded" \| "normals" \| "overdraw" \| "wireframe" | No | "beauty" (default: real environment, lights, fog, tonemap), "lighting" (light only), "unshaded" (albedo/texture only), "normals" (world normals, x red y green z blue), "overdraw", "wireframe". |
| `max_size` | integer | No | Longest edge of the returned JPEG in pixels (default 1024). Bigger costs more context; up to 4096 for detail work on a PC. Range 64 to 4096. |
| `save_to` | string | No | Also write the returned image to res\://.summer/shots/saved/\<name>.jpg (1-64 of A-Z a-z 0-9 \\\_ -; needs max\_size \<= 1024). Nothing is written without it, except one previous-image slot per rendered bookmark. |

<Accordion title="Input JSON schema">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "scenePath": {
        "type": "string",
        "description": "Scene to look at, e.g. \"res://levels/town.tscn\" (the SAVED file). Omit for the scene open in the editor."
      },
      "bookmark_name": {
        "type": "string",
        "description": "Pose from a camera bookmark (summer_camera_bookmark). Use INSTEAD of camera_position/camera_look_at."
      },
      "camera_position": {
        "type": "string",
        "description": "Explicit pose: camera position, \"Vector3(x, y, z)\". Goes with camera_look_at."
      },
      "camera_look_at": {
        "type": "string",
        "description": "Explicit pose: point the camera looks at, \"Vector3(x, y, z)\"."
      },
      "fov": {
        "type": "number",
        "description": "Vertical field of view in degrees (1..179). Default: the bookmark's own, or 60."
      },
      "region": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "minItems": 4,
        "maxItems": 4,
        "description": "[x, y, w, h] as fractions (0..1) of the frame from the same pose, x/y from the TOP-LEFT. Use this OR mark. Rendered EXACTLY (no padding by default, never widened to an aspect ratio): the image takes the region's own aspect, with dark bars only for extreme shapes."
      },
      "mark": {
        "type": "integer",
        "description": "A label number from a marks:true render of the SAME pose and reference_size (summer_frame_nodes, or summer_screenshot framing free/bookmark at that size). The caption warns when that node is hidden behind other geometry at this pose."
      },
      "reference_size": {
        "type": "array",
        "items": {
          "type": "integer"
        },
        "minItems": 2,
        "maxItems": 2,
        "description": "[width, height] of the frame region/mark refer to (default [1024, 576]). Sets the zoom's aspect."
      },
      "pad": {
        "type": "number",
        "description": "Margin added around the region on each side, as a fraction of its size (0..1; default 0 for region, 0.15 for mark). The caption's widened_because says when the rendered window is larger than asked."
      },
      "view": {
        "type": "string",
        "enum": [
          "beauty",
          "lighting",
          "unshaded",
          "normals",
          "overdraw",
          "wireframe"
        ],
        "description": "\"beauty\" (default: real environment, lights, fog, tonemap), \"lighting\" (light only), \"unshaded\" (albedo/texture only), \"normals\" (world normals, x red y green z blue), \"overdraw\", \"wireframe\"."
      },
      "max_size": {
        "type": "integer",
        "minimum": 64,
        "maximum": 4096,
        "description": "Longest edge of the returned JPEG in pixels (default 1024). Bigger costs more context; up to 4096 for detail work on a PC."
      },
      "save_to": {
        "type": "string",
        "description": "Also write the returned image to res://.summer/shots/saved/<name>.jpg (1-64 of A-Z a-z 0-9 _ -; needs max_size <= 1024). Nothing is written without it, except one previous-image slot per rendered bookmark."
      }
    },
    "additionalProperties": false
  }
  ```
</Accordion>

**Example:** Zoom into part of a frame

<CodeGroup>
  ```json MCP theme={null}
  {
    "name": "summer_zoom",
    "arguments": {}
  }
  ```

  ```bash CLI theme={null}
  summer engine zoom
  ```
</CodeGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.