Skip to main content
Glama
beckettlab

Beckett — MCP for Godot

by beckettlab

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
BECKETT_PORTNoPort for the MCP server (default 8770)8770
BECKETT_TOKENNoOptional bearer token for authentication
BECKETT_READONLYNoSet to 1 to enable read-only mode
BECKETT_ALLOWLISTNoComma-separated list of allowed paths or patterns
BECKETT_CONFIRM_DESTRUCTIVENoSet to 1 to require confirmation for destructive actions

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
apply_templateA

Instantiate a bundled (or project) template into res:// in one call — copies its files and, if the template declares a main_scene, sets and opens it. Generic: a template can be a game starter, a UI screen, a settings menu, a test harness. Project templates under res://.beckett/templates/ override bundled ones. Call with no 'template' to list what's available.

attach_scriptA

Attach a script (res:// path) to a node in the open scene (undoable).

batch_executeA

Run several tool calls in one request, in order. steps = [{tool, args}]. Stops at the first failure (stop_on_error, default true). When a step fails, scene edits made by the batch are rolled back via the editor undo history (rollback, default true) — file/resource writes are not. Use to collapse multi-step authoring (create node → set props → attach script) into one atomic call. ok per step means the handler completed - verify EFFECTS with a trailing read-back step (assert_scene / assert_node_state / a get_*) before trusting a mutation batch.

build_csharpA

Compile-check a C#/.NET Godot project with dotnet build, returning structured diagnostics (errors/warnings with file:line:col + CS-code). Isolated build (scratch output) — never touches the editor's loaded assembly, so it's safe while the editor is open. Auto-detects the .csproj if omitted. Needs the .NET SDK (already installed for any C# Godot project). First build restores packages (slower); incremental ~1-3s. Use after editing .cs — the GDScript compile-gate (write_script) does NOT cover C#.

call_methodA

Invoke a method on a resolved object. args = a positional array, coerced to the declared param types: vectors accept [x,y,z] / {"x":..} / "x y z", colors hex or [r,g,b,a], object params a node name/path or res:// path. Wrong types or counts return an ERROR (never a silent no-op). Returns the result as JSON.

connect_signalA

Connect a node's signal to a method on another node, persisted into the scene (undoable). from/to = node path/name in the open scene.

create_nodeA

Create a node of the given class and add it to the open scene (undoable). parent = a node path/name (default: scene root).

create_resourceA

Create a Resource of the given class and save it to a res:// path (.tres). Optional 'properties' dict sets initial values.

delete_nodeB

Remove a node from the open scene (undoable).

describe_classA

List a class's properties and methods (with signatures) so you know exactly what to set_property / call_method. The discovery key for full domain coverage.

describe_objectA

Dump a live object's properties as JSON. target = a res:// path, a node name/path in the OPEN scene, or a class name (falls back to describe_class). While a game is running it also resolves live nodes (/root/Main/Player), the same paths runtime_get_property takes; the answer says which scope it came from, since the edited scene and the running game share one path syntax but are different worlds.

disconnect_signalA

Disconnect a previously connected signal (undoable).

doctorA

Beckett self-diagnosis — one call answers 'why can't the agent see or do X?'. Reports: edition (Lite/Full), the effort dial vs its ceiling AND where the cap comes from (a beckett/effort= line committed in project.godot silently trims every clone's tool list), advertised-vs-ceiling tool counts, dock-disabled tools, server/port/auth state, per-client config freshness (does each written config still carry the CURRENT endpoint URL?), and runtime-bridge liveness. Run this FIRST when tools seem missing, counts look wrong, or calls fail unexpectedly.

duplicate_nodeA

Duplicate a node (with its children) under the same parent (undoable). Optional 'name' for the copy.

find_classesA

Search classes by name substring — engine classes AND your project's own types (GDScript class_name + C# [GlobalClass]). Optional 'base' restricts to subclasses (e.g. base=Node2D). The discovery entry point — pair with describe_class.

find_methodsA

Search methods by name substring, optionally restricted to a class (incl. inherited). Any result is invokable via call_method.

find_nodesA

Find LIVE nodes in the RUNNING game by type and/or name; returns their paths to feed into runtime_call/runtime_get_property/runtime_set_property. 'class' matches native classes AND custom class_name scripts (is_class alone misses custom nodes — they read as @Node@NN). name=substring on the node name. path=scope root (default scene root). recursive=true. max=cap (default 100).

game_logsA

Read the RUNNING game's captured output off the runtime channel (real-time, no file logging): runtime SCRIPT errors WITH stack traces, push_error/push_warning, and print(). This is the play->see-error->fix signal — the blind spot logs_read (file-based) can't reliably cover. level=error (default: errors+script+shader) | warning (adds warnings) | all (adds print/stderr). limit=newest N (default 100), filter=substring, clear=true empties the buffer after reading.

get_godot_versionA

Return the running Godot engine version info.

get_performance_monitorsA

Profiling: read Performance monitors (fps, frame time, memory, object/node counts, draw calls, video mem, physics) — measured engine counters, never estimates. target=game (default when a play session is connected) reads the RUNNING game; target=editor reads the editor. duration_s>0 (game only, max 30) SAMPLES OVER TIME: polls every interval_ms (default 100, min 30) while the game keeps running, then returns per-monitor stats {min,avg,p95,max} — e.g. fps.p95 or process_time.max over a stress window; series=true also returns the raw per-sample series (token-heavy). Editor-target sampling is refused honestly: a tool call blocks the editor's own loop, so an over-time editor read would only measure a stalled editor.

get_play_stateA

Report whether a scene is playing and whether the runtime channel to the game is connected.

get_project_settingA

Read a ProjectSettings value by its property path (e.g. application/run/main_scene). Pass it as 'setting' ('name' is also accepted).

get_project_statisticsA

Project overview: file/script/scene/resource counts, total GDScript lines, autoloads, main scene, input-action count, Godot version. Read-only static scan.

get_remote_treeA

Dump the live scene tree of the RUNNING game (runtime counterpart of get_scene_tree). SCOPE IT to stay under token limits — a full game tree blows the budget. path=subtree root (name, relative, or absolute /root/...); depth=levels (-1=all); max_nodes (default 250); max_children per node (default 50); collapse=true groups runs of identical leaf siblings (e.g. '8x CPUParticles2D'). Returns {tree, node_count, truncated?}.

get_scene_treeA

Return the node tree of the scene currently open in the editor (name/class/script, nested).

instance_sceneA

Instantiate a packed scene (res://*.tscn) as a child in the open scene (undoable).

list_dirA

List entries (dirs + files) of a res:// directory.

list_signalsA

List a node's signals and their current connections (target node + method).

logs_readA

Tail Godot's log FILE (the editor session and any played game log here). For the RUNNING game's errors/stack traces/prints in REAL TIME, prefer game_logs (runtime channel, no file needed) — this file reader is a fallback and needs file logging enabled (off by default; the result tells you how). Optional: level='error'|'warning', 'filter' substring, 'lines' (default 200), 'path' to override.

monitor_propertiesA

Sample a node's property in the running game over several frames (detect movement/changes). Returns the sample series.

move_nodeA

Reorder a node within its parent to a new child index (undoable).

open_sceneA

Open a scene by res:// path in the editor (makes it the edited scene).

play_sceneA

Play a scene in the editor. 'scene' (res://) plays a specific scene; current=true plays the open scene; otherwise the project's main scene. Then wait_until condition=play_started, and logs_read for errors. on_ready=[{path|class|name, property, value}, ...] queues runtime writes that are applied automatically the moment the new game connects — the restart boundary batch_execute cannot cross. Use it to restore camera pose, debug flags or spawn state in ONE call instead of re-issuing them after every restart; wait_until condition=game_connected then reports whether each one landed. Writes whose target is still spawning are retried for a few seconds, then reported as failures rather than dropped.

read_fileA

Read a text file by res:// (or user://) path.

read_scriptA

Read a script/text file from res://.

rename_nodeA

Rename a node in the open scene (undoable).

render_probeA

Ask WHY a 3D node is or is not on screen, as data instead of pixels. Answers the 'the node exists, visible is true, the log is clean, and I still see nothing' case: visibility chain, world AABB, frustum test, distance vs far plane and visibility range, layers vs the camera cull_mask, per-surface material + cull mode, and the triangle winding the camera actually sees (facing_camera=0 with back-face culling means a reversed index buffer — Godot treats CLOCKWISE winding as the FRONT face). Returns a 'warnings' list naming the stage that broke, or a verdict saying the geometry does reach the camera. USE THIS BEFORE tuning lighting, fog, exposure or palette on anything you cannot clearly see — those are invisible-mesh symptoms far more often than they are art problems.

reparent_nodeA

Move a node under a new parent in the open scene (undoable).

runtime_get_propertyA

Read a property of a node in the RUNNING game. Address by path (node path/name) OR a live selector: class (native or custom class_name) / name / text [+ nth, default 0]. The selector resolves fresh each call — no need to re-fetch volatile @Node@NN paths. Returns the value plus the 'resolved' path that matched.

save_sceneA

Save the scene currently open in the editor. Pass 'path' (res://) to save-as.

screenshotA

Capture an image the agent can see. target=game (default) screenshots the RUNNING game via the runtime channel; target=editor captures the 2D editor viewport (PNG only). Token-cost dials (game target, 1.10+): scale=0.5 quarters the pixels; format=jpeg|webp with quality (default 0.8) compresses far below PNG for game frames; region=[x,y,w,h] crops (clamped). annotate=ui draws numbered Set-of-Mark boxes over every visible interactive control and ALSO returns the legend as structured {marks:[{i, path, rect, text?}]} — one glance answers both 'does it look right' and 'what can I click where'; follow up with click_control path=. For pure functional state, ui_snapshot is cheaper than any image.

script_patchA

Surgically edit an existing res:// file without rewriting it whole. edits = an ordered array; each item is {find, replace[, all]} (find must match EXACTLY once unless all:true), {append: text}, or {prepend: text}. Atomic + safe: nothing is written if any anchor is missing/ambiguous or (for .gd) the result fails to compile. Prefer this over write_script for small changes.

search_filesA

Search file contents under res:// for a substring (or regex with regex=true). Returns file:line matches.

set_debug_drawA

Switch the RUNNING game's viewport debug draw mode, then screenshot to see one render stage in isolation. unshaded = albedo only (clears lighting/fog/exposure as suspects in one shot). wireframe = is the geometry even there (culled or degenerate meshes show as nothing). overdraw = transparency cost. normal_buffer = flipped or NaN normals. lighting = light contribution only. normal = back to the real image. Reach for this FIRST when the picture is wrong; render_probe then answers the same question in numbers.

set_project_settingA

Set a ProjectSettings value and persist project.godot. The property path goes in 'setting' ('name' is also accepted); e.g. set application/run/main_scene to res://main.tscn.

set_propertyA

Set a property on a resolved object (undoable). value is coerced to the property's type (vectors accept "x y z" or [x,y,z]).

set_resourceA

Assign a resource to a node's property (undoable). Use 'resource' (res:// path to load) OR 'class' (mint a new inline sub-resource of that class). e.g. set Sprite2D.texture from a path, or a fresh RectangleShape2D on CollisionShape2D.shape.

stop_sceneA

Stop the running play session.

ui_snapshotA

One-call UI snapshot of the RUNNING game: every visible Control as structured data — path, class (+custom class_name), text, rect [x,y,w,h] (gui space, ints), and the semantic state pixels can't tell you: disabled, focused, checked (toggles), value + range (sliders/spin/progress), selected (+selected_text / tabs / item_count), editable / placeholder / secret (text fields), tooltip, mouse_ignore. Interactive controls also get honesty flags: clipped (scrolled out of view) and occluded_by (another control would swallow the click — popup/modal/overlay). Top level: focus owner, open popup/dialog windows (exclusive = modal), viewport size, and a stable content 'hash' — pass it back as since_hash and an unchanged UI returns {unchanged:true} for ~free. For functional UI checks this replaces the screenshot + find_ui_elements + get_control_rect + runtime_get_property round-trips (keep screenshot for VISUAL/render bugs). Walks the whole SceneTree root (autoload HUD layers and popups included); scope with path=, slim with interactive_only=true, cap with max_nodes (default 400).

validate_scriptA

Parse/compile GDScript WITHOUT writing it. Pass 'content' (source) or 'path' (res://). Returns whether it compiles — use before write_script to catch hallucinated APIs. Scripts whose class_name is already registered validate correctly (v1.9; the old false 'hides a global class' error is fixed); when validating 'content' destined for an existing file, ALSO pass its 'path' so a real cross-file class_name duplicate is still reported as the error it is.

wait_for_nodeA

Block until a node appears in the RUNNING game (by path/name) or timeout. Use after play_scene to sync before driving.

wait_untilA

Wait for a condition. Blocks the editor at most ~1.5 s per call — longer would stall the editor's own game-launch pipeline and background jobs (they need main-thread frames). If not met yet it answers 'not yet': just call it again. condition = play_started | play_stopped | game_connected | seconds:N | file_exists:res://path.

write_fileA

Write a text file under res:// (or user://), path-traversal guarded. Refreshes the editor filesystem.

write_scriptA

Write a GDScript (or other text, e.g. .cs) file under res://. GDScript is validated first by default — refuses code that doesn't compile; non-.gd files (C#, config…) are written as-is (use build_csharp to compile-check C#). Set validate=false to force.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/beckettlab/beckett-godot-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server