- name
- godot-mcp-pro-integration
- description
- AI-powered Godot 4 development with 175 MCP tools for scene manipulation, animation, 3D, physics, shaders, and runtime testing via WebSocket connection
- triggers
- ["help me build a Godot game with AI","connect Claude to Godot editor","create Godot scenes with AI assistance","automate Godot development tasks","set up MCP for Godot 4","add nodes to Godot scene programmatically","test Godot game with AI tools","simulate input in Godot game"]
# Godot MCP Pro Integration
> Skill by [ara.so](https://ara.so) — MCP Skills collection.
Godot MCP Pro connects AI assistants (Claude, Cursor, Copilot) to your Godot 4 editor through WebSocket, providing 175 tools for real-time scene manipulation, script editing, input simulation, runtime analysis, and more.
## Architecture
```
AI Assistant ←—MCP/stdio—→ Node.js Server ←—WebSocket:6505—→ Godot Editor Plugin
```
- **Real-time**: WebSocket connection for instant feedback
- **Editor Integration**: Full access to Godot's editor API and UndoRedo system
- **JSON-RPC 2.0**: Standard protocol with error codes and suggestions
- **Four Modes**: Full (175), 3D (103), Lite (84), Minimal (35) tools to fit client limits
## Installation
### 1. Install Godot Plugin (Free)
```bash
# Clone or download the free addon
git clone https://github.com/youichi-uda/godot-mcp-pro.git
```
Copy `addons/godot_mcp/` into your Godot project's `addons/` directory.
Enable in Godot: **Project → Project Settings → Plugins → Godot MCP Pro → Enable**
### 2. Install MCP Server (Paid)
The Node.js server is distributed separately as a paid package ($15 one-time):
- Buy Me a Coffee: https://buymeacoffee.com/y1uda/extras
- itch.io: https://y1uda.itch.io/godot-mcp-pro
After purchasing and extracting:
```bash
cd server
npm install
npm run build
```
### 3. Configure Your AI Client
#### Claude Code (.mcp.json)
```json
{
"mcpServers": {
"godot-mcp-pro": {
"command": "node",
"args": ["/absolute/path/to/server/build/index.js"],
"env": {
"GODOT_MCP_PORT": "6505"
}
}
}
}
```
#### Cursor / VS Code Copilot
Full mode (175 tools) recommended — both support large tool counts.
#### Windsurf / JetBrains Junie (100 tool limit)
```json
{
"mcpServers": {
"godot-mcp-pro": {
"command": "node",
"args": ["/absolute/path/to/server/build/index.js", "--lite"]
}
}
}
```
#### OpenCode / Local LLMs
```json
{
"mcpServers": {
"godot-mcp-pro": {
"command": "node",
"args": ["/absolute/path/to/server/build/index.js", "--minimal"]
}
}
}
```
### 4. Start Development
1. Launch Godot editor with your project and plugin enabled
2. Start your AI assistant (e.g., Claude Code)
3. The MCP server auto-connects to Godot via WebSocket
## Tool Categories & Key Commands
### Project Management (7 tools)
```gdscript
# Get project info
get_project_info()
# Returns: {name, version, viewport_size, autoloads, main_scene}
# Search files
search_files(pattern: "*.gd", use_glob: true)
# Get filesystem tree
get_filesystem_tree(path: "res://", max_depth: 3, include_extensions: [".gd", ".tscn"])
# UID conversion
uid_to_project_path(uid: "uid://abc123")
project_path_to_uid(path: "res://scenes/player.tscn")
```
### Scene Manipulation (9 tools)
```gdscript
# Get scene tree
get_scene_tree()
# Returns hierarchical node structure with properties
# Create new scene
create_scene(
path: "res://scenes/enemy.tscn",
root_type: "CharacterBody3D"
)
# Open scene
open_scene(scene_path: "res://scenes/level_01.tscn")
# Save current scene
save_scene()
# Add scene instance
add_scene_instance(
scene_path: "res://actors/player.tscn",
parent_path: "Level/Entities",
instance_name: "Player"
)
# Play/stop scene
play_scene(mode: "current") # "main", "current", or custom path
stop_scene()
```
### Node Operations (17 tools)
```gdscript
# Add node
add_node(
parent_path: "Player",
node_type: "CollisionShape3D",
node_name: "BodyCollision",
properties: {
"position": {"x": 0, "y": 1, "z": 0}
}
)
# Update property (auto type parsing)
update_property(
node_path: "Player",
property: "speed",
value: "10.0" # Auto-converts to float
)
update_property(
node_path: "Player/Sprite",
property: "modulate",
value: "#ff0000" # Auto-converts to Color
)
# Get node properties
get_node_properties(
node_path: "Player",
include_readonly: false
)
# Move/reparent node
move_node(
node_path: "Enemy",
new_parent_path: "Level/Enemies",
new_index: 0
)
# Duplicate node
duplicate_node(
node_path: "Enemy",
new_name: "Enemy2"
)
# Delete node
delete_node(node_path: "OldNode")
# Connect signal
connect_signal(
source_path: "Button",
signal_name: "pressed",
target_path: "Game",
method_name: "_on_button_pressed"
)
# Groups
set_node_groups(node_path: "Enemy", groups: ["enemies", "ai"])
find_nodes_in_group(group_name: "enemies")
# Selection
select_nodes(node_paths: ["Player", "Player/Camera3D"], focus_first: true)
get_editor_selection()
clear_editor_selection()
```
### Script Management (8 tools)
```gdscript
# List all scripts
list_scripts()
# Returns: [{path, class_name, extends, methods, signals}]
# Read script
read_script(script_path: "res://scripts/player.gd")
# Create script
create_script(
path: "res://scripts/enemy.gd",
template: "CharacterBody3D",
class_name: "Enemy"
)
# Edit script (search/replace)
edit_script(
script_path: "res://scripts/player.gd",
mode: "search_replace",
search: "var speed = 5.0",
replace: "var speed = 10.0"
)
# Full replacement
edit_script(
script_path: "res://scripts/player.gd",
mode: "replace",
content: "extends CharacterBody3D\n\nfunc _ready():\n\tpass"
)
# Attach script to node
attach_script(
node_path: "Enemy",
script_path: "res://scripts/enemy.gd"
)
# Validate syntax
validate_script(script_path: "res://scripts/player.gd")
# Search in files
search_in_files(
pattern: "func _process",
extensions: [".gd"],
case_sensitive: false
)
```
### Runtime Testing (19 tools)
```gdscript
# Get running game scene tree
get_game_scene_tree()
# Get node properties in running game
get_game_node_properties(node_path: "/root/Level/Player")
# Set property in running game
set_game_node_property(
node_path: "/root/Level/Player",
property: "position",
value: {"x": 100, "y": 200, "z": 0}
)
# Execute code in game context
execute_game_script(code: """
var player = get_node('/root/Level/Player')
player.health = 100
print('Player health reset')
""")
# Input simulation
simulate_key(key: "Space", pressed: true)
simulate_key(key: "Space", pressed: false)
simulate_mouse_click(
position: {"x": 512, "y": 300},
button: "left"
)
simulate_action(action: "jump", strength: 1.0)
simulate_sequence(events: [
{"type": "key", "key": "Right", "pressed": true},
{"type": "wait", "frames": 30},
{"type": "key", "key": "Space", "pressed": true},
{"type": "wait", "frames": 5},
{"type": "key", "key": "Space", "pressed": false},
{"type": "key", "key": "Right", "pressed": false}
])
# Capture frames
capture_frames(
duration_frames: 60,
interval_frames: 10,
output_dir: "res://test_captures"
)
# Monitor properties
monitor_properties(
node_path: "/root/Level/Player",
properties: ["position", "velocity"],
duration_frames: 120,
interval_frames: 5
)
# Recording/replay
start_recording()
stop_recording() # Returns recording data
replay_recording(recording_data: {...})
# Find nodes
find_nodes_by_script(script_path: "res://scripts/enemy.gd")
find_ui_elements(node_type: "Button")
find_nearby_nodes(
position: {"x": 100, "y": 200, "z": 0},
radius: 50.0,
node_type: "Area3D"
)
# UI interaction
click_button_by_text(text: "Start Game")
# Wait for condition
wait_for_node(
node_path: "/root/Level/Boss",
timeout_seconds: 5.0
)
```
### Animation (6 tools)
```gdscript
# List animations
list_animations(player_path: "Player/AnimationPlayer")
# Create animation
create_animation(
player_path: "Player/AnimationPlayer",
animation_name: "run",
length: 1.0,
loop: true
)
# Add track
add_animation_track(
player_path: "Player/AnimationPlayer",
animation_name: "run",
track_type: "value", # "value", "position", "rotation", "method", "bezier"
node_path: "Player/Sprite",
property: "frame"
)
# Set keyframe
set_animation_keyframe(
player_path: "Player/AnimationPlayer",
animation_name: "run",
track_index: 0,
time: 0.0,
value: 0
)
set_animation_keyframe(
player_path: "Player/AnimationPlayer",
animation_name: "run",
track_index: 0,
time: 1.0,
value: 8
)
# Get animation info
get_animation_info(
player_path: "Player/AnimationPlayer",
animation_name: "run"
)
# Remove animation
remove_animation(
player_path: "Player/AnimationPlayer",
animation_name: "old_anim"
)
```
### 3D & Physics
```gdscript
# Add collision shape resource
add_resource(
node_path: "Player/CollisionShape3D",
resource_type: "BoxShape3D",
properties: {
"size": {"x": 1, "y": 2, "z": 1}
}
)
# Add mesh resource
add_resource(
node_path: "Enemy/MeshInstance3D",
resource_type: "SphereMesh",
properties: {
"radius": 0.5,
"height": 1.0
}
)
# Set 3D node properties
update_property(
node_path: "Player",
property: "position",
value: {"x": 0, "y": 0, "z": 0}
)
update_property(
node_path: "Player",
property: "rotation_degrees",
value: {"x": 0, "y": 90, "z": 0}
View on GitHub