Skip to main content
Scenes, nodes, scripts, project files, the planning board and Summer Studio. 71 tools. What each column means, and how to connect: MCP tools reference.
Generated from the tools’ own definitions: the summer-engine npm package 3.3.0 (its MCP server’s tools/list, library/tools/*/resource.yaml and registry/generated/index.json in SummerEngine/summer) and the hosted Summer Engine MCP (src/lib/mcp/hosted at commit 8c4351ee30). If something here is wrong, the tool definition is wrong.

summer_account

On the hosted MCP. Show the signed-in Summer account: plan, spendable credits (USD), whether cloud generation is unlocked, and pricing/top-up links. Free. Inputs: No inputs.
Output: MCP text content holding JSON; errors set isError.
Example call

summer_add_node

On the local MCP (summer-engine npm). Add a new node to the scene tree. Pass the exact res:// scenePath to mutate. The scene does not need to be the active editor tab. Common node types:
  • 3D: Node3D, MeshInstance3D, CharacterBody3D, RigidBody3D, StaticBody3D, Camera3D, DirectionalLight3D, OmniLight3D, SpotLight3D, WorldEnvironment, CollisionShape3D, Area3D
  • 2D: Node2D, Sprite2D, CharacterBody2D, RigidBody2D, StaticBody2D, Camera2D, CollisionShape2D, Area2D, TileMapLayer
  • UI: Control, Label, Button, TextEdit, Panel, VBoxContainer, HBoxContainer, MarginContainer
  • Audio: AudioStreamPlayer, AudioStreamPlayer3D
The parent path uses ”./” prefix for relative paths from scene root. E.g., ”./World” means the “World” child of the root node. Use when:
  • building out scene structure node by node
  • “add a Camera3D / DirectionalLight3D / Area2D / Timer to this scene”
  • giving the player a child node for a hitbox, sprite, or audio player
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_align_distribute_3d

On the local MCP (summer-engine npm). Align or equal-space an explicit ordered list of 3D subjects along one world-space axis, then save the exact target scene. Every anchor and extent comes from visible descendant GeometryInstance3D world AABBs (evidence: visual_aabb). The tool never uses editor selection and fails instead of fabricating bounds. It preserves each subject’s authored basis and scale, translates only along the normalized axis, and records all changed transforms in one undoable editor operation. Alignment modes use the first ordered subject’s minimum, center, or maximum projected anchor. Distribution modes keep the first and last subjects fixed and honor caller order. distribute_gaps accounts for each subject’s projected half-extent and fails if the endpoint span cannot fit non-overlapping equal gaps. The compact result returns ordered before/after origins, resolved spacing, and numeric residuals under 5 KB. On an engine build that predates AlignDistribute3D the result is a structured engine_lacks_op failure naming the fallback. Use when:
  • lining up props, stalls, pillars, or lights along one axis
  • spacing a row of objects evenly by center or by visible edge gap
Do not use when:
  • seating objects on a surface — summer_snap_to_surface (alignment solves one axis only)
  • the subjects have no visible GeometryInstance3D descendants (the tool fails instead of fabricating bounds)
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_api_docs

On the local MCP (summer-engine npm). Offline engine class-reference lookup — verify a property, method, signal, or constant BEFORE writing script code, instead of guessing names. No engine connection needed. Returns for a class: inherits, brief description, properties (name/type/default), method signatures, signals, constants. Pass ‘member’ to fetch one member (e.g. class_name:‘BoxShape3D’, member:‘size’ -> {name:‘size’, type:‘Vector3’, default:‘Vector3(1, 1, 1)’}). Unknown names return closest-match suggestions. Entries list only members DECLARED on that class — walk ‘inherits’ for inherited ones (e.g. ‘position’ lives on Node3D, not MeshInstance3D). Data is compiled from the engine’s class reference and stamped with the engine technical base it was generated from (technical_base in every successful result) — trust it over training memory for version-sensitive APIs; descriptions are trimmed to one line. When the bundled reference is missing from this install, the result says so (api_docs_not_installed) instead of guessing. Use when:
  • checking an exact property/method/signal/constant name or default before summer_run_script or a .gd edit
  • “does Node3D have look_at?” / “what is the CharacterBody3D velocity property called?”
  • “which signal fires when a body enters an Area3D?”
Do not use when:
  • the bundled reference is missing from this install (the tool says api_docs_not_installed) — verify against the engine with summer_inspect_node instead
  • you need the live value of a property on a node in the scene — summer_inspect_node
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns for a class: inherits, brief description, properties (name/type/default), method signatures, signals, constants.
Example call

summer_attach_to_surface

On the local MCP (summer-engine npm). Mount a piece on a surface: turn it so its given LOCAL backAxis faces into the surface (opposite the hit normal) with its upAxis kept toward worldUp, then seat its measured back face (the extreme of its visible bounds along backAxis, not its origin) at standoff from the surface. Pipes, gutters, lamps, AC units, signs, fire escapes. Place the piece near its mount first (summer_instantiate_scene with position); this tool turns it and pushes it onto the surface. Find the surface with surface (a node: the ray runs from the subject’s origin to the nearest point of that node’s bounds) or ray {origin, direction} (both: the ray, and hits on other nodes are skipped). The ray is physics first; if physics finds nothing it falls back to visual AABBs and says so (the normal is then an AABB face normal). Get backAxis from summer_inspect_asset (the piece’s back plane normal), not from a guess. placeAt “current” (default): the piece keeps its height and its place along the surface and only moves along the surface normal. placeAt “hit”: it also slides so the centre of its back face lands on the ray hit point. Steps (existing ops): a read-only probe (RunSceneScript) reads the piece’s bounds in its own axes and casts the ray; one SetProp turns the piece and puts its back face 5 cm in front of the planned seat; SnapToSurface sweeps it along -normal (at most standoff + 0.3) and seats it at standoff (its own physics/visual_aabb evidence). Before saving, the seat is checked:
  • with surface: the seat must be on that node (or inside it), else it is refused;
  • with a ray only: a seat on another node is refused unless it lies on the hit plane (a coplanar neighbour module, warned);
  • the piece must end within maxMove (default 2) of where it started; a longer planned move is refused before anything changes, and so is (with placeAt “current”) a ray hit farther than maxMove along the surface from the piece (hit_far_from_piece: aim at the piece, or pass placeAt “hit”). A refused or failed seat puts the piece back where it started (restored: true), saves nothing, and names the cause: seated_on, the seat’s failure_reason, blockers {overlapping, overlaps, first_contact} and a next_step.
Returns {seated_on, final_gap (collider gap from SnapToSurface), back_face_gap (visible back face to the hit plane), moved_by, surface_hit, orientation, back_face_offset, seat {evidence, supportPath, finalGap, gapErrorBound, initiallyOverlapping, …}, saved, warnings}. A warning visible_back_X_into_surface means the piece’s collider sits behind its visible back: add X to standoff. Use when:
  • mounting a downpipe, gutter, lamp, AC unit, sign or fire escape on a facade
  • turning a piece so its back faces a wall instead of guessing its rotation
  • seating a piece against a surface at an exact standoff
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {seated_on, final_gap (collider gap from SnapToSurface), back_face_gap (visible back face to the hit plane), moved_by, surface_hit, orientation, back_face_offset, seat {evidence, supportPath, finalGap, gapErrorBound, initiallyOverlapping, …}, saved, warnings}.
Example call

summer_batch

On the local MCP (summer-engine npm). Execute multiple operations in a single call. Each op is forwarded to the engine VERBATIM, so this is also how you reach engine ops that have no dedicated tool. UNDO: when nothing in the list forces a split (see the single-op contract below), the whole batch is ONE undo step — the user undoes everything with a single Ctrl+Z. When single-only ops are present the list is split into sequential requests and EACH chunk is its own undo step (one Ctrl+Z per chunk; the receipt shows the chunks). Use this when building something that involves multiple nodes and properties — e.g., creating a player character with collision, camera, and properties. Each op in the array uses the same format as the individual tools:
  • {“op”: “AddNode”, “parent”: ”/”, “type”: “MeshInstance3D”, “name”: “Floor”}
  • {“op”: “SetProp”, “path”: “Floor”, “key”: “position”, “value”: “Vector3(0, -1, 0)”}
  • {“op”: “SetProp”, “path”: “Floor”, “key”: “mesh”, “value”: “PlaneMesh”}
  • {“op”: “SetResourceProperty”, “nodePath”: “Floor”, “resourceProperty”: “mesh”, “subProperty”: “size”, “value”: “Vector2(20, 20)”}
RAW RUNTIME OPS (interactive verification — structured failure_reason passes through verbatim):
  • RunVerification — spawn a hidden, disposable game instance that runs a GDScript probe and dies (never touches the editor): {“op”: “RunVerification”, “probe_source”: ”…”, “max_seconds”: 20}. Returns {ok, results, frames, out_dir}. Probe API: report(name, value) / save_frame(name) / press(action) / key(keycode) / finish(). save_frame REQUIRES a name argument — save_frame() with no args is a script error. Mount scenes deferred: get_tree().root.add_child.call_deferred(instance); await get_tree().process_frame; await settle() — a direct add_child in _ready can hit the parent-busy guard and capture a black frame.
  • SimulateInput — inject an action/key/mouse/axis into the RUNNING game (summer_play first): {“op”: “SimulateInput”, “type”: “action”, “action”: “jump”, “pressed”: true}. It MUST be sent alone (single-op batch). failure_reason “not_running” = start the game first; “unsupported” = the running game build predates the handler — fall back to RunVerification or ask the user.
A raw ReplaceNode with scene is refused (it saves the old scene reference); use summer_replace_node. A raw ConnectSignal is refused (the engine connects without CONNECT_PERSIST, so the file never holds it); use summer_connect_signal. REPARENTNODE KEEPS ITS SUBTREE AND IS VERIFIED: the engine’s ReparentNode re-owns only the moved node, so its children and grandchildren were dropped from the saved file. A batch with ReparentNode saves first, reads the saved .tscn, sends each ReparentNode in its own request with an in-place ReparentNode (same parent, same index) per scene-owned descendant to give it back to the scene, then reads the saved file again: persisted:true / verified:true only when every moved node and descendant is at its new path; otherwise an error with failure_reason not_persisted. A move onto a parent that already has a child of that name is refused (failure_reason name_collision). The scenePath must be a .tscn, and Undo cannot share the batch. Do not mix OpenScene with scene mutations in one batch. OpenScene is a UI action; send it separately. scenePath selects every mutation target. The tool appends one final SaveScene when the batch mutates a scene; if supplied explicitly, SaveScene must appear exactly once and be the final operation. The engine requires SaveScene, InstantiateScene, ReplaceNode, SimulateInput, the runtime reads (GetRuntimeSceneTree/GetRuntimeNode), and the Run*/Import* ops to travel as their own request, so this tool automatically splits your op list into sequential requests around them — each split chunk is its own undo step (NOT one step for the whole batch), and if a later chunk fails the receipt reports exactly which earlier ops already applied. PLACED INSTANCES: an InstantiateScene op may also carry position, rotation_degrees, scale ([x, y, z] or “Vector3(…)”) or transform (“Transform3D(…)”); the tool sets them on the created node. One op per piece. Other ops are forwarded verbatim. Cost: each InstantiateScene is its own engine request (the engine requires it); the transforms of a run of InstantiateScene ops are then sent together (up to 200 per request) before the next other op, so N placed pieces plus the save cost about N + 2 requests and N + 2 undo steps. Every later op (a SetProp, SnapToSurface, the save) sees the pieces already placed; if an InstantiateScene fails, the pieces created before it still get their transforms. RECEIPTS: receipt “summary” returns only counts, failures [{index, op, error}] (index = position in your ops list), created node paths and renames, under 5 KB with any cut declared. Use it for any batch over a few ops; the full receipt of a large batch overflows the tool-output limit. scenePersistence.saved means the SaveScene ran; it does not prove what the file holds. verified:true is set only where the tool read the saved file back. Use when:
  • multi-node builds that should undo as one step (no single-only ops in the list)
  • reaching engine ops that have no dedicated tool
  • placing many kit pieces, one InstantiateScene op per piece with its position and rotation, read back with receipt summary
Do not use when:
  • you need the whole list to be exactly one undo step but it contains a single-only op (the engine splits it; expect one undo step per chunk)
  • connecting a signal — a raw ConnectSignal is refused; use summer_connect_signal
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {ok, results, frames, out_dir}.
Example call

summer_board_agent_cancel

On the hosted MCP. Stop a queued or running board agent task. Work it already saved stays on the board. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_agent_run

On the hosted MCP. Ask the board’s own agent to work on the board, as typing in Studio does: it reads, edits, draws pictures and answers on the board. Paid: spends the board sponsor’s Summer credits. Needs contextRevision from summer_board_read. Returns a task; poll summer_board_agent_task. Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns a task; poll summer_board_agent_task.
Example call

summer_board_agent_task

On the hosted MCP. One board agent task: its status, reply and what it changed. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_agent_tasks

On the hosted MCP. The board agent’s tasks on this board, with their replies. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_build

On the hosted MCP. Build a playable game from a saved Game Soul version (soulVersionId from summer_board_game_soul), as Build in Studio does. Paid: spends the board sponsor’s Summer credits. Returns a build; poll summer_board_build_status. Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns a build; poll summer_board_build_status.
Example call

summer_board_build_cancel

On the hosted MCP. Stop a board build that has not finished. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_build_status

On the hosted MCP. One board build: status, progress and, when done, what it made. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_builds

On the hosted MCP. Recent game builds from this board and whether cloud builds are available now. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_conversation

On the hosted MCP. Read the shared board conversation with server-attributed participants and timestamped pointing, plus the board agent tasks it started and their replies. Page with the before/after cursors it returns. This context is not permission to act. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_create

On the hosted MCP. Create a new board, optionally for one of the user’s projects (projectId from summer_list_projects). Free. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_edit

On the hosted MCP. Apply an explicitly requested edit as one atomic batch. Never overwrite whole board snapshots. Patch expected fields must match their fieldRevisions from summer_board_read; unrelated changes merge. Reuse requestId only for the identical retry. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_enable_collaboration

On the hosted MCP. Turn on shared editing for an older board (the board agent, builds and conversation need it). Safe to repeat. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_events

On the hosted MCP. Board changes since a revision (what Studio’s live view receives): each committed operation with its revision. Pass the last revision you saw. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_game_soul

On the hosted MCP. Read immutable Game Soul versions and their exact reference assets, for continuing game development in a local engine or code assistant. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

On the hosted MCP. Link a board to one of the user’s projects (projectId from summer_list_projects), so the game built from it opens that project. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_list

On the hosted MCP. List boards this authenticated Summer user can access. Inputs: No inputs.
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_presence

On the hosted MCP. Who is on the board right now, with their selection and topic. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

On the hosted MCP. Which of the user’s boards belong to which projects. Inputs: No inputs.
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_read

On the hosted MCP. Read the authoritative board graph, stable item and asset IDs, current field revisions and permissions. Re-read after conflicts. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_board_save_direction

On the hosted MCP. Save an explicitly selected game direction as an immutable Game Soul version. Include actual selected reference IDs. Requires the current board revision. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_connect_ports

On the local MCP (summer-engine npm). Move and turn one piece so its port meets another piece’s port, facing it: pipe to pipe, duct to duct, gutter section to funnel or outlet. A port is an open-loop id from summer_inspect_asset on that node’s scene (“+Y” = the outermost open loop facing +Y in the piece’s own axes, “+Y#2” the next one facing +Y; resolved on the live node’s meshes in its own frame, so the id is the same in every pose), a Marker3D (or any Node3D) name under the node whose -Z axis points out of the port, or an open-loop index in the same stable order. The subject turns by the shortest rotation that makes its port direction opposite the target’s, then by rollDegrees about the joined axis, then moves so the ports coincide (gap along the target port’s direction). rollDegrees: axis = roll_axis in the receipt (the target port direction reversed, pointing into the target); right-hand rule, positive = counter-clockwise seen from inside the target looking back at the subject; zero = the shortest turn from the subject’s CURRENT orientation, so the same value differs between start poses. Once the ports are joined, a second call turns by exactly rollDegrees (180 flips a bend’s free end to the other side). Tilt guard: a join that would tilt the subject’s up axis (its local +Y) more than maxTiltDegrees (default 5) is refused before anything changes (failure_reason tilt_exceeds_limit, with tilt_degrees and ports_within_limit: the subject ports that would join within the limit, least tilt first). Turning about the up axis is never tilt. Pass allowTilt true for an intended tilt (a bend laid on its side). One SetProp on transform, saved; a fresh read verifies {distance, angle_degrees, tilt_degrees}. Returns {subject_port {kind, id|name, index, position, direction, radius}, target_port, roll_axis, roll_degrees, rotated_degrees, tilt_degrees, max_tilt_degrees, moved_by, other_ports, verify, warnings}. other_ports: every other port of the subject (its other Marker3D anchors, or its other open loops for an open-loop port) with world position and outward direction AFTER the move, measured by the verify read: read where a bend’s free end now points instead of measuring it. Open-loop ports are only as exact as the mesh: check direction_ambiguous warnings and a screenshot. Use when:
  • joining a pipe, duct or gutter section end to end with the previous one
  • fitting a bend, funnel or outlet onto a run
  • snapping any two pieces together by named Marker3D anchors
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {subject_port {kind, id|name, index, position, direction, radius}, target_port, roll_axis, roll_degrees, rotated_degrees, tilt_degrees, max_tilt_degrees, moved_by, other_ports, verify, warnings}.
Example call

summer_connect_signal

On the local MCP (summer-engine npm). Connect a signal between two nodes so the connection is SAVED in the scene. Signals are Godot’s event system — they notify when something happens. Common signals:
  • “body_entered” / “body_exited” — Area3D/Area2D detects physics bodies
  • “pressed” — Button clicked
  • “timeout” — Timer finished
  • “area_entered” — Area detects another area
  • “input_event” — CollisionObject received input
The receiver should have the method (a script method, or a built-in such as queue_free); a missing one is saved anyway and reported in warnings. scenePath must be a .tscn. PERSISTENCE IS VERIFIED: the engine’s ConnectSignal op connects without CONNECT_PERSIST, so its connection never reached the file. This tool connects through a RunSceneScript probe with CONNECT_PERSIST (replacing a non-persistent connection of the same pair), saves, reads the saved .tscn back and returns persisted:true / verified:true only when the [connection] line is there; otherwise an error with failure_reason not_persisted. The probe runs in the active tab: a scene in a background tab is brought forward and the user’s tab restored (tab_switched). One Ctrl+Z reverts it. Use when:
  • wiring events like body_entered, pressed, or timeout
  • “when the button is pressed, call my function”
  • running code when the player enters an Area3D or a Timer finishes
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_create_scene

On the local MCP (summer-engine npm). Create a new empty scene file. Writes a minimal .tscn through the identity-bound engine with a create-only guard: it fails if the path already exists, and it never touches the currently open scene. The new scene is on disk but NOT opened. Call summer_open_scene to start editing it, then summer_add_node to build it out. Recommended workflow:
  1. Call summer_get_project_context
  2. Call summer_create_scene with a new res:// path
  3. Call summer_open_scene with that path
Use when:
  • starting a new level, prefab, or UI scene file
  • “make a new empty scene file for the enemy prefab”
  • starting Level2.tscn from scratch as its own file
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_get_agent_playbook

On the local MCP (summer-engine npm). AI-first operating guide for Summer Engine MCP. Call this at the start of a fresh chat before touching scenes. It returns the observe-first loop, content routing (reuse -> import -> generate -> script), physical invariants, cost rules, the verification ladder, honesty rules, anti-patterns, and recovery steps. Use when:
  • at the start of a fresh session, before touching scenes
  • a new chat is about to touch a project it has never seen
  • the agent is unsure of Summer’s safety rules or verification ladder
Do not use when:
  • mid-task lookups of a specific tool’s arguments — read that tool’s description instead
Inputs: No inputs.
Output: MCP text content holding JSON; errors set isError.
Example call

summer_get_project_context

On the local MCP (summer-engine npm). Get essential project context before editing. The default payload is COMPACT (a few KB):
  • project name and project path, current scene path, main scene path
  • sceneSummary: the open scene’s root node and node count (not its tree)
  • health: the engine’s scalar status fields plus capability COUNTS
  • projectMemory: the .summer summary — GameSoul/build-plan/memory files and pin (.summer/project.json: which template at which commit started this project, toolkit version, created_at)
  • warnings: capabilitySkewWarning (only when the engine build and this CLI have drifted apart — non-fatal; explains upcoming ‘unknown op’ failures), rebindError, summerUpdateNotice
  • omitted: how to ask for each heavy block that was left out
Use this first in every fresh chat to avoid guessing scene filenames or editing the wrong scene. It also binds the session to the open project. Heavy blocks are opt-in with include: ‘scene_tree’ (the open scene’s tree, up to 200 nodes; for one subtree prefer summer_world_snapshot path_prefix), ‘capabilities’ (the engine’s full op lists), ‘settings’ (project settings in project.data.entries, trimmed to the curated default groups: application/, display/window/, the project’s input/ actions, default gravity, rendering/renderer/, the 2D default texture filter; the trim is declared in settingsTruncated / totalSettings / settingsPrefixesIncluded / settingsPrefixesExcluded). settingsPrefixes (e.g. [“audio/”, “layer_names/”]) or settingsPrefix read other settings groups and imply ‘settings’. Use when:
  • first call in every fresh session, to avoid guessing scene filenames
  • deliberately rebinding after the engine switched projects
  • reading the open scene’s tree, the engine’s op list or project settings (include)
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_get_scene_tree

On the local MCP (summer-engine npm). Get a scene tree. Pass scenePath to read that exact in-memory/open scene; omit it only when you intentionally want the currently visible editor scene. Scene mutations load their explicit target, so a follow-up targeted read does not require OpenScene. The engine defaults to depth 2 and limit 200 nodes and SILENTLY truncates deeper hierarchies (the response then carries truncated: true and a visited count lower than the real node count). Pass an explicit depth (e.g. 10) to read a full tree — a 102-node scene returns only 61 nodes at the defaults. Use when:
  • inspecting scene structure before or after mutations
  • “what nodes are in this scene?” / “how is the level structured?”
  • finding the path of the player node before editing it
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_grep

On the local MCP (summer-engine npm). Search project files with a regular expression (ripgrep, through the engine) and get file + line + text per match, optionally with context lines around each. Use it to find things in big files without reading them whole: every ‘“fits_into”’ in a kit manifest, the scenes of a kit (glob ‘*.tscn’), where a signal handler is defined. Then read exactly the part you need with summer_read_file (offset/limit, or json_path for JSON).
  • path: a res:// directory or file (default: the whole project; .godot/ and .import/ are never searched).
  • glob: ripgrep —glob filter (‘*.gd’, ’**/*.json’, ‘!addons/**’). Ripgrep skips files ignored by .gitignore unless a glob names them.
  • context_lines (0-10): lines before/after each match, as before[] / after[].
  • max_results (default 50, max 500) caps the matches; truncated:true says there were more. Lines are clipped to max_line_chars. Case-insensitive unless case_sensitive:true. Read-only.
Use when:
  • finding where something is in big project files without reading them whole
  • “which entries of a big JSON file list fits_into?” / “every mount_side entry”
  • “where is _on_door_body_entered defined?” / “which scenes use this material?”
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_input_map_bind

On the local MCP (summer-engine npm). Set up input controls. Creates the action if it doesn’t exist, then binds events to it. Event format:
  • Keyboard: { type: “key”, key: “W” } or { type: “key”, key: “Space” }
  • Mouse button: { type: “mouse_button”, button: 1 } (1=left, 2=right, 3=middle)
  • Common keys: “W”, “A”, “S”, “D”, “Space”, “Shift”, “E”, “Escape”, “Up”, “Down”, “Left”, “Right”
Example: Bind jump to Space and W: name: “jump”, events: [{ type: “key”, key: “Space” }, { type: “key”, key: “W” }] Use when:
  • setting up player controls like jump, move, or interact
  • “make E interact” / “bind shoot to left mouse”
  • adding a gamepad button for an existing action
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_inspect_asset

On the local MCP (summer-engine npm). Measure a 3D asset file (.tscn/.scn/.glb/.gltf, or a Mesh resource) WITHOUT adding it to any scene: it is loaded and instanced off-scene in the editor, measured, and freed. Call it once per kit piece before placing it, instead of guessing size, origin or facing. Returns (all in the asset root’s own frame, the frame position/rotation apply in), the facing evidence first:
  • summary {aabb, origin {fraction, label e.g. “x:center y:min z:min”}, plane_pairs, port_like_loops [loop ids], triangles, mesh_count, anchor_count, collision_count, warnings?}. plane_pairs: the 2 largest pairs of opposite planes (a pair under 1% of the largest one’s area is left out), each {larger, opposite (null for a single sheet), separation}; every plane {axis (e.g. “+z”, only when the normal is within about 1 degree of it), normal, offset, area, one_sided}. one_sided true = its material culls back faces, so the plane is invisible from behind its normal: a single sheet that is one_sided faces along its normal and its back is the opposite axis. An oblique normal (no axis) means a baked yaw or a 45-degree corner face. warnings says when the triangle budget cut the analysis and which maxTriangles covers the whole mesh
  • aabb, origin, meshes [{path, tris, min, max}], triangles total
  • planes: the 6 largest planar face groups {normal, offset, area, tris, cull_back, one_sided}; normals follow the triangle winding (outward faces). You decide the front; the tool does not label facing
  • open_loops: open boundary loops {id, index, mesh, center, direction (outward), radius, vertices, max_dev} in a stable order: grouped by the piece axis the direction is nearest (+X, -X, +Y, -Y, +Z, -Z; ~X/~Y/~Z when undecided), the outermost along that axis first, then by centre; never by radius. id names the loop by that order: “+Y” is the outermost loop facing +Y, “+Y#2” the next. summer_connect_ports accepts the id (or the index); the same id names the same loop on the placed node in any pose. detail “summary” (default) lists only port-like loops (radius over 2 cm with a partner loop facing more than 60 degrees away: the ends of a pipe, duct or bend; or the one opening of an end piece, such as an outlet’s socket, on its bounding-box face) and says how many it omitted; detail “full” lists every loop, including the outline of flat sheets
  • anchors: Marker3D nodes {name, path, position, forward (-Z), up}
  • collision: CollisionShape3D nodes {path, shape, size/radius/height/faces, center, min, max}
  • analysis {triangles_analyzed, triangle_budget, truncated}; a “truncated” object when a list was cut to fit 5 KB
maxTriangles 100-300000 (default 60000). Evidence is mesh_triangles. Uses the existing RunSceneScript op (in the live editor, read-only); an engine without it answers engine_lacks_op. Use when:
  • learning a kit piece’s real size, origin and which way it faces before placing it
  • finding a piece’s front and back planes (largest planar faces with their normals) or its pipe and duct ends (open boundary loops)
  • reading the Marker3D anchors or collision shapes a kit piece ships with
Do not use when:
  • the piece is already in the scene and you need what surrounds it — summer_starcast
  • you need the measurement between two placed nodes — summer_measure
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns (all in the asset root’s own frame, the frame position/rotation apply in), the facing evidence first: - summary {aabb, origin {fraction, label e.g.
Example call

summer_inspect_node

On the local MCP (summer-engine npm). Get all editable properties of a node with their current values, types, and resource info. Call this before modifying a node to understand its current state. Returns every property the Godot inspector would show. Each prop carries the engine’s raw Variant.Type integer as “type” plus its name as “type_name” (e.g. type 5 = TYPE_VECTOR2, 20 = TYPE_COLOR, 24 = TYPE_OBJECT); resource-valued props also carry resource_type / resource_path. Reads the currently OPEN scene — “path” is relative to its root (there is no scenePath argument; open the scene first if needed). Example: inspect a light to see its energy, color, shadow settings before changing them. The full read is about 5 KB. To read only what you need, pass fields: property names or globs (‘position’, ‘surface_material_override/*’), plus derived fields: transform (local position / rotation_degrees / scale, and a Transform3D literal for 3D nodes), global_transform (world origin + Transform3D, composed from the world snapshot), scene_file_path (the scene this node instances), aabb (world bounds), warnings. Example: fields:[‘transform’,‘global_transform’,‘scene_file_path’] is a few hundred bytes. missing_fields and unavailable say what could not be read. Use when:
  • before modifying a node, to understand its current state
  • “what is the player’s speed / position / collision layer?”
  • “which material and mesh does this MeshInstance3D use?”
  • “where is this piece, locally and in the world, and which scene is it?” — fields:[transform, global_transform, scene_file_path]
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns every property the Godot inspector would show.
Example call

summer_inspect_resource

On the local MCP (summer-engine npm). Read a resource: a material, mesh, shape, texture, environment, or a scene/model file. Two forms, pass exactly one:
  • path: a resource FILE (‘res://materials/ground.tres’, a mesh ‘res://kit/meshes/wall_01.res’, ‘res://models/player.glb’), loaded read-only in the editor. A Mesh returns its AABB, surface_count and per surface the primitive, vertex and index counts, attributes, triangles and material (class, path or embedded, albedo for standard materials), plus the unique materials and blend shapes. A scene or model (.tscn/.glb/.gltf) returns its node count, the first 40 nodes with type, instanced scene and mesh, and its meshes; summer_inspect_asset measures it (AABB, planes, ports). Every other resource (and a mesh) returns its editor properties that differ from the class default (props), with props_at_default counting the rest.
  • nodePath + property: a resource a node of the ACTIVE scene tab holds, e.g. nodePath ‘Floor’, property ‘mesh’. For example, summer_inspect_node tells you a MeshInstance3D has a “StandardMaterial3D” material_override — this form returns its albedo_color, metallic, roughness, etc.
Use when:
  • reading sub-properties that the node inspector only names
  • “how many surfaces, triangles and which materials does this mesh .res have?”
  • “what colour is this material?” / “how big is this collision shape?”
  • “what settings does the WorldEnvironment resource have?”
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_instantiate_scene

On the local MCP (summer-engine npm). Add an existing scene or 3D model as a child node. Use this to:
  • Add a .tscn prefab (reusable scene) as a child
  • Add a .glb/.gltf 3D model into the scene
  • Compose scenes from smaller scenes (e.g., add a “Player” scene into a “Level” scene)
The scene must already exist in the project. Use summer_import_from_url first if importing from external sources. PASS target_size FOR IMPORTED MODELS. Downloaded/generated .glb assets arrive at arbitrary scale (a “chair” can be 40 units tall). target_size uniformly scales the instanced subtree so its largest world-AABB dimension equals that many units — commit to real-world size: chair 1.0, door 2.0, car 4.5, person 1.7, tree 6-10. The result then reports dimensions + scale_applied; verify placement afterwards (summer_world_snapshot AABBs, summer_screenshot). Older engine builds ignore target_size — when the result lacks scale_applied, this tool appends a note and you must scale the node yourself (summer_set_prop scale) and re-check. PLACE IT IN THE SAME CALL: position, rotation_degrees and scale ([x, y, z], parent-local, like summer_set_prop), or transform (a “Transform3D(…)” string). The instance is created, then those properties are set on the exact node path the receipt reports (a name collision rename is followed), then the scene is saved: one call per piece, no window at the origin. The result adds placement {nodePath, applied, fields}. Do not combine transform with the others, or scale/transform with target_size. Measure a kit piece first with summer_inspect_asset. Use when:
  • placing a .tscn prefab or imported 3D model into a scene
  • “put three copies of the enemy prefab in the level”
  • “add the imported car.glb to the scene”
  • placing a kit piece at an exact position and rotation in one call per piece
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: The result then reports dimensions + scale_applied; verify placement afterwards (summer_world_snapshot AABBs, summer_screenshot). The result adds placement {nodePath, applied, fields}.
Example call

summer_library_feedback

On the local MCP (summer-engine npm). Report how library entries (skills, examples, templates, collections, references, tools) worked out, so Summer can fix and re-rank them — reports fix the entries this user’s own future sessions load. Call once at a natural checkpoint with all entries used; fire-and-forget (1s cap, silent failure, never blocks). Only report outcome ‘worked’ after in-engine verification (playtest or screenshot passed). What is sent: the library entry ids you used (entry_id), one outcome word per entry, your optional note and deviation (280 characters max each, about the entry itself), engine_version, agent_model (your self-reported model id), toolkit_version (this CLI’s version), client (the host app name/version from the MCP handshake), session_id (a random id per MCP server process, never persisted), and — only when not logged in — install_id (a random uuid stored in ~/.summer/; no hardware, user, or project identity). When logged in, the Summer account bearer token is sent instead of install_id. The schema has no field for project files, chat content, or code. The very first call on a machine sends nothing and returns {recorded:false, first_run:true, notice} — call again to send. Otherwise recorded:true means the gateway accepted the batch; {recorded:false, dropped:true, status, reason} means the 1s POST failed and the batch is gone (no retry) — reason is endpoint_missing (404), rejected (other 4xx), server_error (5xx) or network. The user can opt out entirely with SUMMER_NO_TELEMETRY=1 or DO_NOT_TRACK=1 — then nothing is sent and this tool returns {recorded:false, disabled:true}. Use when:
  • a natural checkpoint after using library entries, batching all outcomes in one call
  • an entry was wrong, outdated, incomplete, or misrouted and Summer should know
Do not use when:
  • reporting outcome worked without in-engine verification
  • the note would describe the user’s project, files, or code instead of the entry
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_measure

On the local MCP (summer-engine npm). Measure placement between specific nodes from their visible-mesh bounds (evidence visual_aabb). Read-only, never saves. Complements summer_starcast (which reports clearance around ONE node in 26 directions). mode pair (a, b): per axis {gap (> 0 clearance, < 0 overlap depth), relation gap|touching|overlap, a/b intervals, delta_min/max/center (b minus a)} and boxes_overlap. Catches facade gaps and modules that overlap. mode plane (nodes, face): whether that face of every node lies on one plane: {coplanar, plane (median), spread, nodes [{path, face, deviation, off_plane: proud|recessed}]}. Catches modules standing proud of a facade line. face ‘+z’ = the face pointing along +z. space “local” measures along the axes of a (pair) or nodes[0] (plane), for rotated facades. tolerance (default 5 mm) decides touching / coplanar. Use when:
  • checking that two facade modules meet edge to edge, or how far apart or overlapping two pieces are on each axis
  • checking that every module of a facade line has its front on one plane (plane mode) and which ones stand proud or sit recessed
  • verifying a placement numerically before the screenshot
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_navigation_probe

On the local MCP (summer-engine npm). Inspect whether two explicit world-space points are connected by the targeted 3D scene’s built-in Godot navigation map without changing or saving the scene. Returns navigation readiness and its reason, map iteration and region counts, requested and layer-filtered snapped endpoints, snap distances, conservative reachability, full route length, and at most 16 deterministic route points. A path is reachable only when it terminates at both snapped endpoints within the reported tolerance. ready:false means navigation evidence is unavailable, not that the route is unreachable. In particular, map iteration 0 precedes the first usable synchronization and can return silently empty paths; iteration 1 and later are usable. evidence is always navigation. Normal results are capped below 5 KB. Always pass an exact scenePath and finite world-space start/end points. This read-only tool never uses editor selection, creates undo history, or calls SaveScene. On an engine build that predates NavigationProbe3D the result is a structured engine_lacks_op failure naming the fallback. Use when:
  • placing an NPC, pickup, portal, or encounter anchor whose route from spawn matters
  • checking that a moved prop did not cut the navigation mesh between two areas
Do not use when:
  • the scene has no NavigationRegion3D (ready is false; there is nothing to probe)
  • you need live agent behaviour — playtest with summer_play and read summer_get_runtime_tree
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns navigation readiness and its reason, map iteration and region counts, requested and layer-filtered snapped endpoints, snap distances, conservative reachability, full route length, and at most 16 deterministic route points.
Example call

summer_open

On the local MCP (summer-engine npm). Open the exact summerengine.com page or Summer Engine editor surface the user wants to LOOK at, by intent name — or, with open:false, return the URL / engine op without opening anything. The result ALWAYS carries the resolved url or op, also after opening, so you can tell the user where they landed. WHEN: the user wants to see, check, or decide something: “open my billing page”, “show me my published games”, “take me to pricing”, “open the MCP setup guide for Cursor”, “show me the scene”, “select the Player node”, “open player.gd”. NOT for getting a result (add a node, set a property, publish) — use the mutation tools; opening a UI is a user-visible action, do it because the user asked to look, and say what will open. target: an id (billing, usage, account, settings, team, my-games, game, pricing, download, mcp-guide, templates, asset-store, docs, scene, main-scene, node, script, file, files, scene-tree, inspector, screen-3d, assistant, project-settings, output, debugger, editor-window, …), an intent phrase (“change my plan”), a res:// path (routed by extension: .tscn -> scene, .gd -> script, else file), or a summerengine.com path (“/pricing”). Omit target to LIST every destination with surface/status/requires. params: slot values — gameId + section (builds, releases, store-page, analytics, …) for game; guide (agent name: cursor, claude-code, codex, gemini, …) for mcp-guide; username; version; path / node / scene / line / col / tab for editor targets. open: false resolves only and returns url (+ login_url when the page needs login) or op; nothing opens, no engine needed. Result: { ok, action: opened | printed | listed | ambiguous | unsupported | engine_not_running | engine_error | not_found | invalid_params | open_failed | blocked_origin, target (with availability for editor ids), url, login_url, logged_in, opened_url, op, engine, failure_reason, matches, hint }.
  • Web targets that require login open through /login?returnUrl=<path> when this machine holds no Summer login token (logged_in:false) — the destination loads after sign-in.
  • Editor targets need Summer Engine running with the project open; otherwise action engine_not_running with the op that would have been sent and a ‘summer run’ hint. Nothing was opened.
  • Editor destinations are forwarded to the engine’s own navigation table (op Navigate; ids advertised in /api/health capabilities.navigation). On an engine that predates it, scene/node/script/file and the three docks still work through their original ops; anything else answers action unsupported with failure_reason engine_lacks_op and an update hint. Never claim those opened. Listing (no target) shows each editor id’s availability from the connected engine.
  • ambiguous: several destinations match; call again with one of matches[].id. Only summerengine.com (and subdomains) are ever opened — a gateway configured elsewhere is refused (blocked_origin); res:// paths with .. or other escapes are refused; a machine with no browser gets open_failed with the url to hand over.
Use when:
  • the user wants to SEE or DECIDE something on the website — “open my billing page”, “show me my published games”, “take me to pricing”, “open the MCP setup guide for Cursor”
  • the user wants to LOOK at something in the running editor — “show me the scene”, “select the Player node”, “open player.gd”, “reveal that texture in the file dock”
  • “open the main scene in the editor” / “open the scene I am editing so I can look at it” — an editor surface the USER should see, navigated for them (the scene tools open a tab for the agent, not for the user)
  • handing the user a link instead of opening a browser (open: false), or checking which destination an intent maps to
  • resolving where a user intent lives (“where do I change my plan?”) before acting
Do not use when:
  • the user wants a result, not a view — add the node, set the property, publish; use the mutation tools (summer_add_node, summer_set_prop, summer_publish_build)
  • opening a project directory in the engine — that is the CLI’s summer open <path> / summer run <path> project launcher, not a navigation target
  • the destination is not on summerengine.com or docs.summerengine.com — the tool refuses other origins
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: The result ALWAYS carries the resolved url or op, also after opening, so you can tell the user where they landed. Result: { ok, action: opened | printed | listed | ambiguous | unsupported | engine_not_running | engine_error | not_found | invalid_params | open_failed | blocked_origin, target (with availability for editor ids), url, login_url, logged_in, opened_url, op, engine, failure_reason, matches, hint }.
Example call

summer_open_main_scene

On the local MCP (summer-engine npm). Open the project’s configured main scene from project settings. Safer than guessing scene names like main.tscn/Main.tscn. Call this when you get “no scene open”. Use when:
  • any tool reports that no scene is open
  • “get me back to the game’s main scene”
  • a fresh session with no active scene tab
Do not use when: Inputs: No inputs.
Output: MCP text content holding JSON; errors set isError.
Example call

summer_open_scene

On the local MCP (summer-engine npm). Open a scene file in the editor. Use this to switch between scenes. Do not guess paths. Prefer:
  1. summer_get_project_context (read mainScene)
  2. summer_open_main_scene (open known main scene)
  3. summer_open_scene only when user gave an explicit path.
Use when:
  • switching the editor to an explicitly known scene path
  • “switch to level2.tscn” / “open the player prefab in the editor”
  • a tool needs a different scene to be the active tab
Do not use when:
  • guessing scene filenames (resolve them from project context first)
  • the project’s main scene — summer_open_main_scene
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_place_adjacent

On the local MCP (summer-engine npm). Move one node so its bounds face sits against another node’s bounds face along one axis: facade modules edge to edge, a storey stacked on the one below, a cornice on a wall. Optionally line up the other two axes (min, center or max), per axis. Example: next module to the right, same base height, same front plane: {axis:“x”, side:“max”, gap:0, alignOtherAxes:{y:“min”, z:“max”}}. Bounds are the visible GeometryInstance3D AABBs (the definition summer_align_distribute_3d uses; evidence visual_aabb). space “local” uses the reference’s own axes for rotated facades. When the subject is inside the reference, its geometry is left out of the reference’s bounds. One SetProp on position, one undo step, then the scene is saved; a fresh read verifies the achieved gap and residuals (verify). Returns {moved_by, position, verify:{gap, residuals}}. The scene must be open in the editor (any tab). Use when:
  • laying facade or wall modules edge to edge along a street line
  • stacking a storey, cornice or crown on the piece below
  • putting a piece flush beside another with the same base height and front plane
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {moved_by, position, verify:{gap, residuals}}.
Example call

summer_project_setting

On the local MCP (summer-engine npm). Set a project setting in project.godot. Common settings:
  • “application/config/name” — project name
  • “application/run/main_scene” — main scene path
  • “rendering/renderer/rendering_method” — “forward_plus”, “mobile”, or “gl_compatibility”
  • “display/window/size/viewport_width” — window width
  • “display/window/size/viewport_height” — window height
  • “physics/3d/default_gravity” — gravity value (float)
Use when:
  • configuring project-level behavior
  • “make the game start on Level1” — changing the main scene
  • “set the resolution / fullscreen / gravity / physics tick rate”
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_raycast

On the local MCP (summer-engine npm). Cast one ray from any point in an open scene, before anything is placed there: find the wall, floor or ceiling in front of a point and its normal. (summer_starcast casts from an existing node’s bounds; this casts from an arbitrary origin.) evidence auto (default): physics first (collider hit: exact point and normal); if physics hits nothing, the nearest visible-mesh AABB hit, declared with fallback:true and fallback_reason. Physics needs the scene to be the active editor tab (only that scene’s bodies are in the editor’s physics space); otherwise auto falls back to visual AABBs. When physics hits but a mesh-only object is nearer, nearer_visual_only names it. Returns {hit, evidence, path, point, normal, distance, origin, direction, physics_available, warnings}. Read-only (RunSceneScript probe, undo “none”); never saves. Use when:
  • finding the wall, floor or ceiling in front of a point and its normal before anything is placed there
  • choosing where a lamp, pipe or sign mounts on a facade
  • checking what a line of sight or a drop line hits
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {hit, evidence, path, point, normal, distance, origin, direction, physics_available, warnings}.
Example call

summer_read_file

On the local MCP (summer-engine npm). Read a text file from the engine-bound project and return its full-file sha256 receipt. Use the returned sha256 as expected_sha256 when overwriting an existing file. Paths must begin with res://. READ BIG FILES IN PARTS instead of all at once:
  • offset + limit page the file: lines by default (unit:‘bytes’ for a byte range on UTF-8 boundaries). The result’s data.window gives start_line/end_line, total_lines, next_offset (null at the end) and eof.
  • For JSON: json_path picks one value (‘pieces.wall_a’, ‘items[3]’); keys keeps matching object keys ([‘wall_*’]); keys_only lists key names only. data.json says what matched. offset/limit then page the selection. The sha256 always covers the WHOLE file, so a windowed read still guards a later overwrite. Files over 1 MB can be paged only within their first 1 MB.
Use when:
  • reading project files through the engine
  • getting the sha256 required before overwriting a file
  • reading a file too big for one result in pages (offset/limit)
  • “read the wall_door_b entry of a kit manifest” — json_path / keys instead of the whole file
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: The result’s data.window gives start_line/end_line, total_lines, next_offset (null at the end) and eof.
Example call

summer_read_library

On the local MCP (summer-engine npm). Load one library entry by id (<kind>/<slug>, as returned by summer_search_library). Skills: the SKILL.md body plus metadata (status, use_when, related) and how to invoke the skill in your host (bare slug). Tools: how to call it (MCP name, summer tool <slug> --args, engine requirement, authority) plus the descriptor. Templates: the pinned repo @ commit and tree digest (or built-in) and the summer create <slug> command. References: the markdown body. Linked files: a body ends with its relative links and the id that loads each; a file an entry links loads by <entry id>/<link as written> (e.g. skill/spatial-placement/references/kit-placement-tools.md), by the relative path alone when one entry ships it, inside library/ only. part: ‘skill’ = body only, ‘resource’ = the resource.yaml descriptor only, ‘all’ (default) = both. The LAST line of every load is the feedback footer — entry_id: <id>@<content-hash>. If this entry is wrong, stale, or you deviate from it, report via summer_library_feedback. — copy that entry_id verbatim into summer_library_feedback once you have verified the outcome in-engine. Unknown id -> {ok:false, error:‘not_found’, nearest:[up to 3 ids]}. No engine needed; reads the library shipped with this package. Use when:
  • summer_search_library returned an id and you need the entry itself before acting
  • re-reading a skill or reference the current version of (entries evolve — never rely on memory of one)
  • checking how to call a tool or how a template is pinned without walking the library folders
Do not use when:
  • you do not know the id yet — summer_search_library first
  • the skill is installed in your host — invoking it there (Claude Code /<slug>) loads the same body
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_remove_node

On the local MCP (summer-engine npm). Remove a node from the scene tree. All children are removed too. Cannot remove the root node. Supports undo. Destructive operation: do not delete multiple top-level nodes unless the user explicitly requests destructive changes. Use when:
  • deleting scene content the user asked to remove
  • “delete the old camera” / “get rid of the debug label”
  • removing the placeholder cube now that the real model is in
Do not use when:
  • bulk-deleting top-level nodes without an explicit user request
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_repeat_along

On the local MCP (summer-engine npm). Instance copies of one scene along a straight line in one call: wall clamps every 0.45 m, braces every 0.8 m, fence posts, a row of window modules. Give start plus end (with spacing or count) or start plus direction (with count and spacing); positions are in the parent’s local space. align (start|center|end) places the leftover length when spacing does not divide the line. Each copy is an InstantiateScene (the engine runs each alone), named <namePrefix>_<n>; the copies’ transforms (position, rotationDegrees, scale) are then set in one request and the scene is saved once: N copies cost N + 2 engine requests. At most 64 copies per call. Returns a compact receipt: {count, spacing, first, last, created [node paths], renamed, failures [{index, error}], saved}. Lists are cut to stay under 5 KB and the cut is declared. Use when:
  • placing wall clamps, gutter braces or duct braces at a fixed spacing along a run
  • a row of fence posts, bollards, lamps or window modules
  • filling a line with as many copies as fit at a spacing
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns a compact receipt: {count, spacing, first, last, created [node paths], renamed, failures [{index, error}], saved}.
Example call

summer_replace_node

On the local MCP (summer-engine npm). Replace a node with a different scene/model or node type, keeping its parent, sibling index, name, transform and property overrides, and the children the scene added under it. Use it to swap a kit piece for another (a wall host for a door host), a placeholder for a prefab, or a StaticBody3D for a RigidBody3D. Give exactly one of scene or type. The scenePath must be a .tscn. PERSISTENCE IS VERIFIED: the tool saves, reads the saved .tscn back and checks that the node at path now instances the new scene (or has the new type), under the same parent, with every child present. persisted:true is proven from the file; a mismatch is an error with failure_reason not_persisted — never report that as done. How: a scene swap runs as InstantiateScene (temporary name) -> SetProp each property override -> ReparentNode the children -> MoveNode to the old index -> RemoveNode the old node -> rename -> SaveScene, because the engine’s own ReplaceNode keeps the OLD scene reference in the saved file. A type change of a plain node uses the engine’s ReplaceNode. State that cannot travel (groups, signal connections, scene-local sub_resource values, overrides of nodes inside the old scene) is listed in not_carried_over. Undo takes one Ctrl+Z per step. Use when:
  • swapping a placeholder for a prefab or changing a body type
  • “turn this StaticBody3D into a RigidBody3D but keep its children”
  • swapping the placeholder cube for the real prefab in place
  • swapping one kit piece for another (a wall host for a door host) without hand-copying its transform
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_replace_text

On the local MCP (summer-engine npm). Safely replace text in an existing project file through the identity-bound engine. The MCP server reads the complete file, requires a unique match by default, computes the new content, and submits a sha256-guarded WriteFile. Set replace_all:true only when every exact occurrence should change. Use when:
  • targeted edits to scripts, scenes, or config without resending the whole file
  • “change speed = 5 to speed = 8 in player.gd”
  • renaming one function call in a script without rewriting the file
Do not use when:
  • writing a new file or rewriting most of it — summer_write_file
  • the same text appears more than once and you have not narrowed the match
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_run_editor_script

On the local MCP (summer-engine npm). Run a GDScript EditorScript in a FRESH HEADLESS editor spawned against the ON-DISK project. Cold path: a whole child editor boots, runs your script once, and exits — seconds to tens of seconds depending on the project and the script (about 2 s end to end on a small template project; large projects can spend 30 s+ just booting). USE FOR batch/project-wide jobs that should not block the live editor: re-saving many scenes, sweeping resources, mass import fixes, generating .tres assets, long bakes. It sees ONLY what is saved on disk — unsaved live edits in the open editor are INVISIBLE to it, and the live editor won’t show its output until files reload. For work on the OPEN scene, use summer_run_script instead. SCRIPT CONTRACT — write a plain EditorScript body: func _run(): var scene = load(“res://main.tscn”).instantiate() # … work … print(“done”) # captured into output[] You may omit the ‘@tool’ and ‘extends EditorScript’ lines — the engine prepends any that are missing and reports each fix in ‘normalizations’ (with ‘line_offset’ so error line numbers map back to your source). Including ‘extends EditorScript’ yourself is also fine. Returns {ok, ran, exit_code, output, errors, boot_errors, result, out_dir, checkpoint, normalizations} plus a failure_reason taxonomy on failure (script_parse_failed, timeout, spawn_failed, …). A top-level no_rewind_point:true means no pre-run checkpoint exists — the run is NOT rewindable; tell the user before doing more destructive work. This headless child has NO renderer: screenshots/pixels are impossible here (see the headless-scripting skill). Use when:
  • re-saving many scenes, sweeping resources, mass import fixes, generating .tres assets, long bakes that should not block the live editor
  • “re-save every scene after the engine upgrade”
  • “fix the import settings on all 200 textures”
Do not use when:
  • work on the currently OPEN scene or anything relying on unsaved live edits — summer_run_script
  • anything needing pixels — the headless child has no renderer
  • you need checkpoint/rollback or the scene-scripting ctx helpers — that is summer_run_script (RunSceneScript, Summer Engine 0.5.66 or newer, preview); RunEditorScript itself ships in current engines
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {ok, ran, exit_code, output, errors, boot_errors, result, out_dir, checkpoint, normalizations} plus a failure_reason taxonomy on failure (script_parse_failed, timeout, spawn_failed, …).
Example call

summer_run_script

On the local MCP (summer-engine npm). Run a GDScript snippet INSIDE the live editor, against the currently OPEN scene. This is the scene-scripting workhorse: one script replaces long chains of add-node/set-prop calls, and it can compute (loops, randomness, math, procedural meshes) what individual CRUD ops cannot. SCRIPT CONTRACT — write ONLY the body below; do not add extends/@tool lines (missing ones are prepended and reported in ‘normalizations’): func run(ctx): var root = ctx.get_scene_root() # root node of the open scene for i in range(10): var m := MeshInstance3D.new() m.mesh = BoxMesh.new() m.position = Vector3(i * 2, 0, 0) root.add_child(m) ctx.set_owner_recursive(m) # REQUIRED or the node is NOT saved ctx.report(“count”, 10) # structured value back to you
  • ctx.get_scene_root() — the open scene’s root node. Full editor API access.
  • ctx.set_owner_recursive(node) — stamps node AND its descendants with the scene-root owner (equivalent to node.owner = root on each). Call it after add_child on every created subtree.
  • ctx.report(key, value) — return structured results (comes back in ‘reports’).
  • print(…) — captured and returned in ‘output’.
  • OWNERSHIP: a created node whose owner is never set silently vanishes when the scene saves — descendants too. ctx.set_owner_recursive covers both.
  • Values here are real GDScript — Vector3(0,10,0), Color(1,0,0,1) — NOT the quoted variant strings used by summer_set_prop.
Newer ctx builds also carry creation helpers that set the owner FOR you and return the node — prefer them: ctx.add_node(type, name, parent, props), ctx.find(name), ctx.get_or_create(type, name, parent), ctx.instance_scene(res_path, parent, name), ctx.add_mesh(shape, name, parent, props) / ctx.add_mesh_with_collision(…), ctx.mesh_from_arrays(…), ctx.make_material(props) / ctx.apply_material(node, material), ctx.grid(count_x, count_z, spacing, maker) / ctx.scatter(area, count, maker, seed), ctx.add_light_rig(target), ctx.ensure_environment(props), ctx.add_camera(position, look_at, make_current), ctx.summary(), ctx.save_scene(path). Unknown props keys are reported in ‘prop_warnings’, never silently dropped. On an older engine a missing helper is a plain GDScript error — fall back to the manual form above. WHEN TO USE: 3+ related ops, anything with computed placement (scatter, grids, rings), procedural geometry (SurfaceTool/ArrayMesh), bulk renames/retunes. For a single property tweak, summer_set_prop is cheaper. Use summer_api_docs to verify property/method names instead of guessing. THE LOOP: summer_world_snapshot (keep snapshot_id) -> summer_run_script -> summer_snapshot_diff + summer_screenshot -> inspect -> iterate. Never claim visual success without the screenshot. Returns {ok, ran, result, reports, output, errors, duration_ms, checkpoint} — newer engines add rolled_back (a runtime error rolled the whole undo action back; the scene is untouched) and budget_enforced (max_seconds was a HARD deadline; when the budget hits, the script errors with “Summer script budget exceeded” — split the work into smaller scripts, never resubmit the same oversized one). Read ‘errors’ even when ok — with undo:‘none’, a partially-failed script may have mutated the scene. If this engine build predates RunSceneScript, the result is a structured engine_lacks_op failure (nothing is sent): use summer_run_editor_script or update Summer Engine. Use when:
  • a change needs 3+ related ops or any computed placement (scatter, grids, procedural meshes, bulk edits)
  • the ctx helpers (add_node, add_mesh, grid, scatter, light rig, environment) fit the job
Do not use when:
  • a single property tweak — summer_set_prop is cheaper
  • a cold project-wide batch job that should not block the live editor — summer_run_editor_script
  • requires an engine build with RunSceneScript (Summer Engine 0.5.66 or newer); older engines return engine_lacks_op
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {ok, ran, result, reports, output, errors, duration_ms, checkpoint} — newer engines add rolled_back (a runtime error rolled the whole undo action back; the scene is untouched) and budget_enforced (max_seconds was a HARD deadline; when the budget hits, the script errors with “Summer script budget exceeded” — split the work into smaller scripts, never resubmit the same oversized one).
Example call

summer_save_scene

On the local MCP (summer-engine npm). Save an explicit scene to disk. Mutation tools already append one save; use this for a standalone save or save-as. Use when:
  • a standalone save or save-as is needed
  • “save a copy of this scene as level1_backup.tscn”
  • the user explicitly asks to save
Do not use when:
  • after ordinary mutation tools, which already append one save
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_search_library

On the local MCP (summer-engine npm). Search the Summer library — skills, tools, templates, references, examples, collections — by describing the task in plain words (‘make stylized water’, ‘the player falls through the floor’, ‘which tool reads script errors’). This is the FIRST MOVE for any task: even a 1% chance the library covers it means you search, then read the entry you pick with summer_read_library before acting — never act on a summary alone. Ranking: BM25 over ids, summaries, use_when lines and facets with kind-aware priors and related-entry boosts (the same ranker the routing eval gates). When this install ships registry/generated/embeddings.json and the embedding endpoint answers within 1.5s, lexical and semantic rankings are fused (reciprocal rank fusion) and each hit’s matched_by says which side found it; offline or without embeddings it is lexical only and never fails for that reason. Returns {query, semantic, count, results: [{id, kind, status, summary, use_when, score, matched_by, mcp_tool_name?}], hint}. Scores compare only within one response. kinds narrows to some of the six kinds; include_preview:false hides preview entries; deprecated entries never surface. No engine needed. Privacy: only when semantic search is active is the query text sent to the Summer gateway to be embedded; nothing else leaves the machine. Use when:
  • the first move for any task, before building anything — find the entry that covers what the user asked
  • not sure which entry (skill, tool, template, reference) applies to the task at hand
  • narrowing the library to one kind with the kinds filter, or hiding preview entries
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {query, semantic, count, results: [{id, kind, status, summary, use_when, score, matched_by, mcp_tool_name?}], hint}.
Example call

summer_select_node

On the local MCP (summer-engine npm). Select a node in the editor’s scene tree and show it in the inspector panel. Useful for focusing the editor on a specific node. Use when:
  • focusing the user’s editor on a specific node
  • highlighting the player in the scene tree so the user can see it
  • showing the user the node whose properties are about to change
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_set_prop

On the local MCP (summer-engine npm). Set a property on a node. This is the primary way to configure nodes after adding them. VALUE FORMAT — Godot string syntax for complex types:
  • Vector3: “Vector3(0, 10, 0)” — position, scale, rotation_degrees
  • Vector2: “Vector2(100, 200)” — 2D position, size
  • Color: “Color(1, 0.5, 0, 1)” — RGBA, always 4 components, values 0.0-1.0
  • Transform3D: “Transform3D(1,0,0, 0,1,0, 0,0,1, 0,5,0)” — basis + origin
  • Resource class name: “BoxMesh”, “SphereMesh”, “StandardMaterial3D” — auto-instantiated
  • Numbers: 1.5, 42 — native JSON
  • Booleans: true, false — native JSON
  • Strings: “hello” — native JSON
COMMON PROPERTIES:
  • position: “Vector3(x, y, z)” — world position
  • rotation_degrees: “Vector3(rx, ry, rz)” — rotation in degrees
  • scale: “Vector3(sx, sy, sz)” — scale factor
  • visible: true/false — visibility
  • mesh: “BoxMesh”, “SphereMesh”, “CapsuleMesh”, “CylinderMesh”, “PlaneMesh”
  • shadow_enabled: true — for lights
  • light_energy: 1.5 — light intensity
  • fov: 75.0 — camera field of view
Use when:
  • configuring nodes after adding them
  • “move the light up” / “put the player at the spawn point” / “make the sprite red” / “rotate the camera 45 degrees”
  • setting one node’s position, rotation, scale, colour, speed, collision layer, or visible flag
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_set_resource_property

On the local MCP (summer-engine npm). Set a nested property on a resource attached to a node. Use when you need to modify a sub-property of a resource, like:
  • CollisionShape3D shape size: nodePath=”./Player/CollisionShape3D”, resourceProperty=“shape”, subProperty=“size”, value=“Vector3(1, 2, 1)”
  • Material albedo color: nodePath=”./Floor”, resourceProperty=“material_override”, subProperty=“albedo_color”, value=“Color(0.2, 0.5, 0.2, 1)”
  • Mesh size: nodePath=”./Box”, resourceProperty=“mesh”, subProperty=“size”, value=“Vector3(2, 2, 2)“
Use when:
  • modifying sub-properties of meshes, materials, or shapes
  • “make the box mesh 2 metres wide” / “change the capsule radius”
  • setting the material albedo colour or roughness on a mesh
Do not use when:
  • the property is on the node itself (position, visible, scale) — summer_set_prop
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_snap_to_surface

On the local MCP (summer-engine npm). Move one exact 3D subject along a world-space ray until its support face sits at the requested gap from the first surface. This changes only the subject’s global transform, saves the scene, and is one reversible editor undo. Use the default downward direction to seat props on floors, ramps, tables, or shelves. Set alignUp only when the prop should tilt to match the support normal. EVIDENCE BOUNDARY:
  • physics means Godot swept the subject’s enabled collider shapes against body colliders and refined the first-contact bracket.
  • visual_aabb is the engine’s broad-phase fallback for mesh-only geometry (no collider on the subject or the support): AABBs swept against AABBs. It does not prove triangle contact, and alignUp is not applied from that approximate normal.
  • visual_mesh: whenever the engine answers with visual_aabb (overlap_recovery_exceeded, gap_exceeds_hit_travel, surface_not_found, or a seat), a read-only probe measures the move from visible triangles instead: the subject’s vertices cast along the direction onto the triangles of the meshes below (a surface cutting through the subject counts as sunk), plus the support’s vertices under it cast back. One SetProp places the subject, a second read verifies the gap (the move is undone if it disagrees by more than 5 mm), and the scene is saved. The receipt says evidence visual_mesh, the engine’s own answer under engine, verify {final_gap, ok}, and evidenceDetails (samples, triangles, whether the subject and the support have colliders). Meshes whose shader writes POSITION (screen-space quads) are not surfaces. When the triangles find no support either, the engine’s failure is returned with mesh_fallback saying why.
  • initiallyOverlapping and backoffDistance expose bounded pre-sweep recovery. The tool fails instead of teleporting when the subject cannot be cleared within maxDistance.
SUNK PROPS: when the subject starts inside its support (gap_exceeds_hit_travel with a start overlap), the tool lifts it against the cast direction by the overlap depth plus 0.02 m (at most 0.5 m and the subject’s own extent), snaps again from there, and keeps that only if it settles on a node it was sunk into; the receipt then carries recovery (lifted_by, original_local_position) and ‘before’ is the lifted pose. Otherwise the original position is restored. FAILURES EXPLAIN THEMSELVES: after gap_exceeds_hit_travel or overlap_recovery_exceeded a read-only starcast at the current pose adds start_overlap, blocking (the nodes it touches or sits inside), below, and a concrete next_step. The normal result is bounded below 5 KB and returns before/after transforms, supportPath, finalGap with an error bound, slopeDeg, evidence, and warnings. scenePath and subjectPath are always required; there is no editor-selection fallback. On an engine build that predates SnapToSurface the result is a structured engine_lacks_op failure naming the fallback. Use when:
  • seating a prop on a floor, ramp, table, or shelf instead of hand-tuning its Y position
  • grounding an imported or instantiated model that floats or sinks into its support
  • lifting a prop that is sunk a few centimetres into the ground back onto it
  • seating a prop without a collider (a fern, a bottle) on a PlaneMesh or other mesh-only ground
Do not use when: Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_starcast

On the local MCP (summer-engine npm). Read a 3D spatial rundown for one exact node in an exact scene without moving it or saving the scene: 26 directional clearance casts (6 axes, 12 edges, 8 corners) from the subject’s bounds, contact-or-overlap evidence, grounded state, and, in full detail, bounded nearby-object lists. Use it before and after placing an object to learn which side is blocked, by what, and at what distance. detail ‘summary’ (default) is a placement report of at most 5 KB: subject position and size, grounded and contactStatus, deduplicated contact paths, one compact record per direction (status open|blocked, nearest distance, object, evidence, relationship), coverage, and warnings. detail ‘full’ adds per-direction hit geometry, an objects table, nearby lists, and the query echo, at most 12 KB; the engine downgrades to summary rather than exceed that (warning full_result_exceeded_12kb_returned_summary) and always reports requestedDetail vs returnedDetail. EVIDENCE BOUNDARY:
  • evidence ‘physics’ uses Godot’s PhysicsDirectSpaceState3D against exact collider geometry on collisionMask. Shape intersections say contact_or_overlap because the query does not establish penetration depth; touching and anything within margin are included.
  • evidence ‘visual_aabb’ uses visible world-axis-aligned bounding boxes: it catches meshes without colliders but is broad-phase only, never triangle-level contact.
  • Lights, cameras, audio, navigation, scripts, and plain Nodes are not obstacles unless they own visual or collision geometry. One representative ray per direction can miss off-center geometry.
scenePath and path are exact; editor selection is never consulted. This tool is read-only: it never moves the node or saves the scene. On an engine build that predates Starcast3D the result is a structured engine_lacks_op failure naming the fallback. Use when:
  • learning what surrounds a placed prop before and after a correction — which direction is blocked, by what, and at what distance
  • diagnosing an overlap or a floating object when summer_test_placement reports fits false or grounded false and you need to know which side to move
  • checking wall gaps, shelf support, or alcove clearance for a rotated subject (directionSpace local)
Do not use when:
  • you want the engine to move the prop for you — summer_snap_to_surface or summer_align_distribute_3d
  • you only need a yes/no on one candidate pose — summer_test_placement is cheaper
  • the subject is 2D or has neither visual nor collision geometry
  • requires an engine build with Starcast3D (Summer Engine 0.5.66 or newer); older engines return engine_lacks_op
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_start_game_task

On the local MCP (summer-engine npm). Start here for any substantial AI game-building task. Takes the user’s goal and returns the recommended Summer workflow: skill routes, MCP tool groups, host-file boundaries, asset policy, user confirmation gates, and verification steps. This is the router before deep skills and before mutating the project. Use when:
  • starting any substantial AI game-building task, before mutating the project
  • the user asks for a whole feature (inventory, boss fight, day-night cycle) and the path is not obvious
  • choosing which skills and confirmation gates apply before touching the project
Do not use when:
  • a one-step edit (one property, one node) — call the tool directly
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_studio_map

On the hosted MCP. The map of Summer Studio: every page (destination id, title, what it is for, path) and the product guide the Studio assistant answers from. No open tab needed. Use a destination id with summer_studio_open. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_studio_open

On the hosted MCP. Move the person’s open Summer Studio tab to a Studio page (a destination id from summer_studio_map, or a /studio or /create path). Returns the page’s fields and buttons once it has loaded. The person sees a notice that their agent opened it. Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns the page’s fields and buttons once it has loaded.
Example call

summer_studio_page

On the hosted MCP. Read the person’s open Summer Studio tab: its path, the fields an agent may fill (id, label, kind, value, limits, choices) and the buttons it may press (confirm buttons are the person’s to press). Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_studio_use_page

On the hosted MCP. Fill fields and press one button on the person’s open Summer Studio tab, exactly like the Studio assistant’s use_page: ids and values are checked against the page (text is trimmed to its limit, choices take their value or label, picture fields take the person’s own asset ids). A button that publishes, uploads, pays or deletes is never pressed: it is shown to the person to click. Read the page first with summer_studio_page. Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_test_placement

On the local MCP (summer-engine npm). Ghost-test one 3D node at an explicit candidate global pose without moving it or saving the scene. Use this before placing a prop in a shelf, cubby, doorway, platform, or dense set. The compact result reports known overlap evidence, grounded state, signed floor gap, and at most eight overlapping object paths. Physics evidence uses enabled collider shapes; because Godot exposes no query-completeness bit, its overlap count is labeled a lower bound and an otherwise-clear physics result reports fits:null rather than claiming proof. visual_aabb evidence is a broad-phase fallback that also catches visible mesh-only obstacles. The pose is always global/world-space: position and Euler rotation in degrees are both required, while the subject’s current global scale is preserved. scenePath and subjectPath are exact; this tool never falls back to editor selection. The normal result is below 5 KB and the scene is never mutated. On an engine build that predates TestPlacement3D the result is a structured engine_lacks_op failure naming the fallback. Use when:
  • deciding whether a prop fits in a shelf, cubby, doorway, platform, or dense set before committing the transform
  • re-checking a saved pose after snap or align to confirm it still clears its neighbours
Do not use when:
  • you want the engine to move the prop for you — summer_snap_to_surface
  • the prop is 2D or has no visual/collider geometry to test
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_ui_actions

On the local MCP (summer-engine npm). List the editor’s named actions, or invoke ONE by name exactly as its menu item / shortcut would — the primary way to drive the editor UI. (preview — needs an engine build with UiListActions/UiInvoke) SCENE WORK IS NOT UI WORK: to add, move, retune, or read nodes use summer_run_script, the scene tools, summer_world_snapshot and summer_screenshot — never by clicking through the editor. UI ops are for editor-workflow steps a human would do with the mouse: open Project Settings or the Import dock, switch the 2D/3D/Script main screen, clear a dialog that is blocking input, read what a dock currently shows. mode:‘list’ -> {actions:[{name, label, shortcut_text, category, source:‘shortcut’|‘command’, denied?}], total, truncated, filter}. name is the stable shortcut path (‘editor/save_scene’, ‘editor/project_settings’, ‘spatial_editor/focus_selection’, ‘summer/design_mode’); filter is a case-insensitive substring over name and label. denied:true marks names mode:‘invoke’ will refuse — read it and do not try them. mode:‘invoke’ action_name:‘<name>’ -> {action, label, invoked:true, handled, via:‘shortcut_event’|‘command_palette’, opened_dialog?, mutates:true}. The event runs through the same MenuBar/PopupMenu/EditorNode handlers the key would. opened_dialog is a window that appeared synchronously; a dialog shown deferred appears on the next summer_ui_tree root:‘dialogs’. Order of preference: a dedicated tool -> summer_ui_actions mode:‘invoke’ by name -> summer_ui_tree + summer_ui_activate by control path -> summer_ui_screenshot (pixels, last, and only to LOOK — never to pick coordinates). Read back, never assume: after an invoke, confirm the effect with summer_ui_tree root:‘dialogs’ (a dialog opened), summer_ui_tree root:‘dock:<name>’ (a dock changed), or the scene/perception tools (the scene changed). Failures carry failure_reason: unknown_action (+close_matches — pick the exact name) | denied_action (+reason — stop; do not route around it) | modal_open (+blocking_dialog — an exclusive dialog is eating input: summer_ui_tree root:‘dialogs’, then summer_ui_activate action:‘dismiss_dialog’, then retry) | not_handled (invoked but no live receiver — switch context first, e.g. summer_ui_activate path:‘main_screen’ action:‘select_tab’ value:‘3D’) | editor_unavailable. Never try to quit the editor, quit to the project list, reload the project, or delete without confirmation (editor/file_quit, editor/quit_to_project_list, editor/reload_current_project, scene_tree/delete_no_confirm, project_manager/*): the engine refuses them with denied_action, and buttons/menu items with those labels are denied the same way. They end the session you are talking over. On an engine build without these ops the result is a structured engine_lacks_op failure (nothing is sent) naming the dedicated tools to use instead. Use when:
  • “open project settings in the editor” / “open the Import dock” / “toggle the animation bottom panel” — an editor-workflow step a human would do with the mouse, driven by its stable action name
  • finding the exact action name (mode list, filter) before invoking it, and reading which names are denied
  • a step has no dedicated tool (summer_open_scene, summer_select_node, summer_save_scene) but the editor has a menu item or shortcut for it
Do not use when:
  • scene work — adding, moving, retuning, or reading nodes goes through summer_run_script, the scene tools, summer_world_snapshot and summer_screenshot, never through editor clicks
  • quitting the editor, quitting to the project list, reloading the project, or deleting without confirmation — denied by the engine (denied_action); they end the session
  • a control has no named action — read summer_ui_tree and activate it by path with summer_ui_activate
  • requires an engine build with UiListActions / UiInvoke (Summer Engine 0.5.66 or newer); older engines return engine_lacks_op
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call

summer_ui_activate

On the local MCP (summer-engine npm). Activate ONE editor control by its summer_ui_tree path through the control’s own input path — a synthetic click for buttons, the public setter + signal for tabs, text fields and ranges — or dismiss a visible dialog (action:‘dismiss_dialog’). Mutates editor state; the result’s state is READ BACK from the control after the action, not echoed. (preview — needs an engine build with UiActivate/UiDismissDialog) SCENE WORK IS NOT UI WORK: to add, move, retune, or read nodes use summer_run_script, the scene tools, summer_world_snapshot and summer_screenshot — never by clicking through the editor. UI ops are for editor-workflow steps a human would do with the mouse: open Project Settings or the Import dock, switch the 2D/3D/Script main screen, clear a dialog that is blocking input, read what a dock currently shows. Reach for this only when no named action covers the step (summer_ui_actions mode:‘list’ first). There is no coordinate click: if a thing is visible it is in the tree and this reaches it by path. actions: press (BaseButton: hover+press+release at the rect centre — pressed_emitted is observed, not assumed; ItemList/PopupMenu item by index; MenuBar -> unsupported_control, use summer_ui_actions) | toggle (toggle-mode button) | focus (any control/window) | select_tab (TabContainer/TabBar by value title or index; path:‘main_screen’ switches the 2D/3D/Script/Game/AssetLib editor by value or index and reads back current_tab + text) | set_text (LineEdit/TextEdit; submit:true also presses Enter; value ” clears) | set_value (Range number) | dismiss_dialog (path or title from summer_ui_tree root:‘dialogs’; button ‘cancel’ default = the safe close, ‘ok’ or a button text to confirm — only when the user asked for that). Returns {path, class, action, via, state:{…the node’s tree fields…}, mutates:true} plus clicked_at/hover_established/pressed_emitted for press, item_text for menus, submitted for set_text; dismiss_dialog returns {title, class, button, via, visible_after} — visible_after:true means the dialog re-validated and stayed up (read it: summer_ui_tree root:‘dialog:<title>’). Verify with the read-back (state.checked, state.current_tab, state.text, visible_after), never by assumption. Failures: not_found | not_visible (hidden — reveal the dock/tab first) | disabled | unsupported_control (+supported_actions) | obscured (+hit_control — something on top, usually a dialog) | modal_open (+blocking_dialog — dismiss it first) | no_activation_path (use the named action instead) | denied_action / denied_path (safety: quit/reload labels, file-dialog paths outside the project) | tab_not_found (+tabs) | index_out_of_range | missing_value | not_selected | button_not_found (+buttons) | ambiguous_dialog (+candidates). Never try to quit the editor, quit to the project list, reload the project, or delete without confirmation (editor/file_quit, editor/quit_to_project_list, editor/reload_current_project, scene_tree/delete_no_confirm, project_manager/*): the engine refuses them with denied_action, and buttons/menu items with those labels are denied the same way. They end the session you are talking over. Engine builds without these ops return a structured engine_lacks_op failure (nothing is sent). Use when:
  • “dismiss the dialog that is blocking the editor” / “close that popup” — action dismiss_dialog with the path or title from summer_ui_tree root dialogs
  • “switch the editor to the 3D view” / “go to the Script screen” — path main_screen, action select_tab, value 3D
  • pressing a button, selecting a tab, typing into a search field, or dialling a slider that no named action covers, using a path from summer_ui_tree
Do not use when:
  • a named action exists — summer_ui_actions mode invoke is the first choice; the tree walk is for the long tail
  • scene work — nodes, properties, and placement go through summer_run_script and the scene tools, never through editor clicks
  • confirming a quit, reload, or delete-without-confirmation button — denied by the engine (denied_action) because it ends the session or bypasses the human’s confirmation
  • requires an engine build with UiActivate / UiDismissDialog (Summer Engine 0.5.66 or newer); older engines return engine_lacks_op
Inputs:
Output: MCP text content holding JSON; errors set isError. From the tool’s own description: Returns {path, class, action, via, state:{…the node’s tree fields…}, mutates:true} plus clicked_at/hover_established/pressed_emitted for press, item_text for menus, submitted for set_text; dismiss_dialog returns {title, class, button, via, visible_after} — visible_after:true means the dialog re-validated and stayed up (read it: summer_ui_tree root:‘dialog:<title>‘).
Example call

summer_write_file

On the local MCP (summer-engine npm). Create or safely overwrite a complete text file through the identity-bound engine. For a new file, set create_only:true. For an existing file, first call summer_read_file and pass its sha256 as expected_sha256. Exactly one guard is required; unguarded writes fail closed. Supports scripts, .tscn scenes, .tres resources, JSON, docs, and project config. Use when:
  • creating a new project file with the create-only guard
  • overwriting an existing file with its sha256 receipt
Inputs:
Output: MCP text content holding JSON; errors set isError.
Example call