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.Input JSON schema
Input JSON schema
isError.
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
- 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
- placing an existing .tscn prefab or imported model —
summer_instantiate_scene - 3+ related nodes or any computed placement —
summer_run_script
Input JSON schema
Input JSON schema
isError.
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.
- lining up props, stalls, pillars, or lights along one axis
- spacing a row of objects evenly by center or by visible edge gap
- 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)
Input JSON schema
Input JSON schema
isError.
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.
- checking an exact property/method/signal/constant name or default before
summer_run_scriptor a .gd edit - “does Node3D have look_at?” / “what is the CharacterBody3D velocity property called?”
- “which signal fires when a body enters an Area3D?”
- the bundled reference is missing from this install (the tool says api_docs_not_installed) — verify against the engine with
summer_inspect_nodeinstead - you need the live value of a property on a node in the scene —
summer_inspect_node
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns for a class: inherits, brief description, properties (name/type/default), method signatures, signals, constants.
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.
- 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
- seating a prop on a floor without turning it —
summer_snap_to_surface - joining a pipe to another pipe’s end —
summer_connect_ports
Input JSON schema
Input JSON schema
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}.
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)”}
- 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_playfirst): {“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.
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.
- 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
- 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
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns {ok, results, frames, out_dir}.
summer_board_agent_cancel
On the hosted MCP. Stop a queued or running board agent task. Work it already saved stays on the board.Input JSON schema
Input JSON schema
isError.
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 fromsummer_board_read. Returns a task; poll summer_board_agent_task.
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns a task; poll summer_board_agent_task.
summer_board_agent_task
On the hosted MCP. One board agent task: its status, reply and what it changed.Input JSON schema
Input JSON schema
isError.
summer_board_agent_tasks
On the hosted MCP. The board agent’s tasks on this board, with their replies.Input JSON schema
Input JSON schema
isError.
summer_board_build
On the hosted MCP. Build a playable game from a saved Game Soul version (soulVersionId fromsummer_board_game_soul), as Build in Studio does. Paid: spends the board sponsor’s Summer credits. Returns a build; poll summer_board_build_status.
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns a build; poll summer_board_build_status.
summer_board_build_cancel
On the hosted MCP. Stop a board build that has not finished.Input JSON schema
Input JSON schema
isError.
summer_board_build_status
On the hosted MCP. One board build: status, progress and, when done, what it made.Input JSON schema
Input JSON schema
isError.
summer_board_builds
On the hosted MCP. Recent game builds from this board and whether cloud builds are available now.Input JSON schema
Input JSON schema
isError.
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.Input JSON schema
Input JSON schema
isError.
summer_board_create
On the hosted MCP. Create a new board, optionally for one of the user’s projects (projectId fromsummer_list_projects). Free.
Input JSON schema
Input JSON schema
isError.
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 fromsummer_board_read; unrelated changes merge. Reuse requestId only for the identical retry.
Input JSON schema
Input JSON schema
isError.
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.Input JSON schema
Input JSON schema
isError.
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.Input JSON schema
Input JSON schema
isError.
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.Input JSON schema
Input JSON schema
isError.
summer_board_link_project
On the hosted MCP. Link a board to one of the user’s projects (projectId fromsummer_list_projects), so the game built from it opens that project.
Input JSON schema
Input JSON schema
isError.
summer_board_list
On the hosted MCP. List boards this authenticated Summer user can access.Input JSON schema
Input JSON schema
isError.
summer_board_presence
On the hosted MCP. Who is on the board right now, with their selection and topic.Input JSON schema
Input JSON schema
isError.
summer_board_project_links
On the hosted MCP. Which of the user’s boards belong to which projects.Input JSON schema
Input JSON schema
isError.
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.Input JSON schema
Input JSON schema
isError.
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.Input JSON schema
Input JSON schema
isError.
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.
- 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
- mounting a piece on a wall —
summer_attach_to_surface - putting bounds faces together without ports —
summer_place_adjacent
Input JSON schema
Input JSON schema
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}.
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
- 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
- the receiver script does not define the target method yet — write it first with
summer_write_file/summer_replace_text - the scene is a binary .scn — connect from
summer_run_scriptwith CONNECT_PERSIST, thensummer_save_scene
Input JSON schema
Input JSON schema
isError.
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:
- Call
summer_get_project_context - Call
summer_create_scenewith a new res:// path - Call
summer_open_scenewith that path
- 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
- adding nodes into the currently open scene —
summer_add_node - the file already exists — the create-only guard refuses;
summer_open_sceneit instead
Input JSON schema
Input JSON schema
isError.
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.
- 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
- mid-task lookups of a specific tool’s arguments — read that tool’s description instead
Input JSON schema
Input JSON schema
isError.
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
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’.
- 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)
Input JSON schema
Input JSON schema
isError.
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.
- 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
- the RUNNING game’s tree —
summer_get_runtime_tree - transforms and bounds, not just names —
summer_world_snapshot
Input JSON schema
Input JSON schema
isError.
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.
- 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?”
- you already know the file and want its content —
summer_read_file(offset/limit, json_path) - searching the Summer library —
summer_search_library
Input JSON schema
Input JSON schema
isError.
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”
- 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
- reading which keys are already bound —
summer_get_project_context/ project.godot
Input JSON schema
Input JSON schema
isError.
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_portsaccepts 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
- 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
- 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
Input JSON schema
Input JSON schema
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.
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.
- 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]
- sub-properties of the material, mesh, or shape itself —
summer_inspect_resource - live values while the game runs —
summer_inspect_runtime_node
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns every property the Godot inspector would show.
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_assetmeasures 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_nodetells you a MeshInstance3D has a “StandardMaterial3D” material_override — this form returns its albedo_color, metallic, roughness, etc.
- 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?”
- top-level node properties —
summer_inspect_node
Input JSON schema
Input JSON schema
isError.
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)
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.
- 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
- a bare built-in node type like Camera3D or Timer —
summer_add_node
Input JSON schema
Input JSON schema
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}.
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}.
- 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
- reporting outcome worked without in-engine verification
- the note would describe the user’s project, files, or code instead of the entry
Input JSON schema
Input JSON schema
isError.
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.
- 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
- you want clearance around one node in every direction —
summer_starcast - you want to test a pose before moving anything —
summer_test_placement
Input JSON schema
Input JSON schema
isError.
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.
- 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
- the scene has no NavigationRegion3D (ready is false; there is nothing to probe)
- you need live agent behaviour — playtest with
summer_playand readsummer_get_runtime_tree
Input JSON schema
Input JSON schema
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.
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.
- 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
- 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
Input JSON schema
Input JSON schema
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 }.
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”.
- 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
- a specific non-main scene —
summer_open_scenewith its path
Input JSON schema
Input JSON schema
isError.
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:
summer_get_project_context(read mainScene)summer_open_main_scene(open known main scene)summer_open_sceneonly when user gave an explicit path.
- 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
- guessing scene filenames (resolve them from project context first)
- the project’s main scene —
summer_open_main_scene
Input JSON schema
Input JSON schema
isError.
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).
- 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
- aligning or spacing a whole group along one axis —
summer_align_distribute_3d - seating a piece on a floor or a wall surface —
summer_snap_to_surfaceorsummer_attach_to_surface
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns {moved_by, position, verify:{gap, residuals}}.
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)
- configuring project-level behavior
- “make the game start on Level1” — changing the main scene
- “set the resolution / fullscreen / gravity / physics tick rate”
- per-node properties —
summer_set_prop - key bindings —
summer_input_map_bind
Input JSON schema
Input JSON schema
isError.
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.
- 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
- you want clearance around an existing node in every direction —
summer_starcast - you want to mount the piece in the same call —
summer_attach_to_surfacecasts its own ray
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns {hit, evidence, path, point, normal, distance, origin, direction, physics_available, warnings}.
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.
- 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
Input JSON schema
Input JSON schema
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.
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.
summer_search_libraryreturned 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
- you do not know the id yet —
summer_search_libraryfirst - the skill is installed in your host — invoking it there (Claude Code /<slug>) loads the same body
Input JSON schema
Input JSON schema
isError.
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.
- 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
- bulk-deleting top-level nodes without an explicit user request
Input JSON schema
Input JSON schema
isError.
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.
- 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
- scattering copies over an area or a grid —
summer_run_scriptwith ctx.scatter / ctx.grid - spacing nodes that already exist —
summer_align_distribute_3d
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns a compact receipt: {count, spacing, first, last, created [node paths], renamed, failures [{index, error}], saved}.
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.
- 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
- adding alongside instead of replacing —
summer_add_node/summer_instantiate_scene
Input JSON schema
Input JSON schema
isError.
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.
- 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
- 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
Input JSON schema
Input JSON schema
isError.
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).
- 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”
- 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
Input JSON schema
Input JSON schema
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, …).
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.
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.
- 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
- a single property tweak —
summer_set_propis 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
Input JSON schema
Input JSON schema
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).
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.
- a standalone save or save-as is needed
- “save a copy of this scene as level1_backup.tscn”
- the user explicitly asks to save
- after ordinary mutation tools, which already append one save
Input JSON schema
Input JSON schema
isError.
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.
- 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
- you already hold an exact id — load it with
summer_read_library - looking for assets (models, textures, sounds) —
summer_search_assetssearches the asset library, not the knowledge library - looking up an engine class, property, or method name —
summer_api_docs
Input JSON schema
Input JSON schema
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}.
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.
- 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
- reading properties —
summer_inspect_node; selection changes nothing
Input JSON schema
Input JSON schema
isError.
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
- 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
- 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
- a property that lives on a mesh, material, or shape resource —
summer_set_resource_property - project-wide settings —
summer_project_setting - many nodes or computed values —
summer_run_script
Input JSON schema
Input JSON schema
isError.
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)“
- 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
- the property is on the node itself (position, visible, scale) —
summer_set_prop
Input JSON schema
Input JSON schema
isError.
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.
- 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
- you only want to know whether a pose fits —
summer_test_placementis read-only - arranging several objects relative to each other —
summer_align_distribute_3d
Input JSON schema
Input JSON schema
isError.
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.
- 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_placementreports 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)
- you want the engine to move the prop for you —
summer_snap_to_surfaceorsummer_align_distribute_3d - you only need a yes/no on one candidate pose —
summer_test_placementis 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
Input JSON schema
Input JSON schema
isError.
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.
- 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
- a one-step edit (one property, one node) — call the tool directly
Input JSON schema
Input JSON schema
isError.
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 withsummer_studio_open.
Input JSON schema
Input JSON schema
isError.
summer_studio_open
On the hosted MCP. Move the person’s open Summer Studio tab to a Studio page (a destination id fromsummer_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.
Input JSON schema
Input JSON schema
isError. From the tool’s own description: Returns the page’s fields and buttons once it has loaded.
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).Input JSON schema
Input JSON schema
isError.
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 withsummer_studio_page.
Input JSON schema
Input JSON schema
isError.
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.
- 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
- 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
Input JSON schema
Input JSON schema
isError.
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.
- “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
- scene work — adding, moving, retuning, or reading nodes goes through
summer_run_script, the scene tools,summer_world_snapshotandsummer_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_treeand activate it by path withsummer_ui_activate - requires an engine build with UiListActions / UiInvoke (Summer Engine 0.5.66 or newer); older engines return engine_lacks_op
Input JSON schema
Input JSON schema
isError.
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).
- “dismiss the dialog that is blocking the editor” / “close that popup” — action dismiss_dialog with the path or title from
summer_ui_treeroot 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
- a named action exists —
summer_ui_actionsmode invoke is the first choice; the tree walk is for the long tail - scene work — nodes, properties, and placement go through
summer_run_scriptand 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
Input JSON schema
Input JSON schema
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>‘).
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.
- creating a new project file with the create-only guard
- overwriting an existing file with its sha256 receipt
Input JSON schema
Input JSON schema
isError.

