toasted-iron-studios/godot-agent-mcp
If you are the rightful owner of godot-agent-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
A Godot MCP server that allows AI assistants to interact with Godot Engine through standardized tools and commands.
create_node
Creates a new node in the currently edited scene.
Godot Agent MCP
A Godot MCP (Model Context Protocol) server that enables AI assistants like Claude, Cursor, and Zed to interact with Godot Engine through standardized tools and commands.
Overview
This plugin transforms your Godot editor into an MCP server, allowing AI coding assistants to:
- Create and manipulate scene nodes
- Inspect and modify project structure
- Execute Godot-specific operations remotely
The server implements the MCP specification and provides a robust foundation for building AI-assisted Godot development workflows.
Notably, the MCP runs in Godot, which reduces installation complexity and improves maintainability.
Features
- MCP-compliant HTTP server - Runs on localhost:8080
- Schema validation - Uses Zodot for type-safe parameter validation
- Extensible tool system - Easy to add new tools and capabilities
- JSON-RPC 2.0 support - Standard protocol implementation
- CORS protection - Restricted to localhost connections
Installation
Prerequisites
- Godot 4.x
- Git (for cloning the repository)
Setup
-
Clone the repository into your Godot project:
cd your-godot-project git clone https://github.com/toasted-iron-studios/godot-agent-mcp.git # Or add as submodule git submodule add https://github.com/toasted-iron-studios/godot-agent-mcp.git addons/godot_agent_mcp
-
Enable the plugin:
- Open your project in Godot
- Go to
Project → Project Settings → Plugins
- Find "Godot Agent MCP" and enable it
- The server will automatically start on port 8080
-
Verify installation:
- Check the Output panel for "Godot Agent MCP plugin started"
- The server should be accessible at
http://127.0.0.1:8080
Usage
With AI Assistants
Configure your AI assistant to use the MCP server:
For Cursor/VSCode:
Copy-pasta the sample MCP config in the repo: mcp.json.sample
Available Tools
create_node
Creates a new node in the currently edited scene.
Parameters:
parent_path
(string): Path to the parent node (use "/root" for scene root)node_type
(string): Godot node class name (e.g., "Node2D", "RigidBody3D")node_name
(string): Name for the new node
Example:
{
"parent_path": "/root",
"node_type": "Node2D",
"node_name": "Player"
}
Direct HTTP Usage
You can also interact with the server directly via HTTP:
curl -X POST http://127.0.0.1:8080 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_node",
"arguments": {
"parent_path": "/root",
"node_type": "Node2D",
"node_name": "MyNode"
}
},
"id": 1
}'
Architecture
Core Components
plugin.gd
- Main plugin entry point, manages server lifecycleHttpServer
- HTTP server handling MCP requestsMCPRouter
- Routes MCP method calls to appropriate handlersMCPTool
- Abstract base class for all toolsZodot
- Schema validation library for type safety
Request Flow
AI Assistant → HTTP Request → HttpServer → MCPRouter → MCPTool → Godot API
- AI assistant sends JSON-RPC 2.0 request
- HttpServer validates and parses the request
- MCPRouter routes to the appropriate tool
- Tool validates parameters using Zodot schemas
- Tool executes Godot operations and returns results
Tool Architecture
Tools inherit from MCPTool
and implement:
get_name()
- Unique tool identifierget_description()
- Human-readable descriptionget_input_schema()
- Zodot schema for parameter validationrun(params)
- Tool execution logic
Contributing
Code Quality Standards
We maintain strict code quality standards to ensure a professional, maintainable codebase:
NO INLINE COMMENTS
- NEVER use inline comments (single
#
comments within function bodies) - Inline comments indicate poor code quality and lack of experience
- If code needs explanation, refactor it into a well-named function with a docblock
- Code should be self-documenting through clear variable and function names
MANDATORY DOCBLOCKS
- ALL public functions MUST have descriptive docblocks (
##
comments) - Docblocks must explain the function's purpose, parameters, return values, and side effects
- Include parameter types and return types in the description when helpful
- Document any exceptions or error conditions the function might encounter
Function Naming
- Use descriptive verb phrases:
validate_input()
,parse_json_request()
,handle_authentication()
- Use descriptive nouns for variables:
user_credentials
,parsed_data
,validation_result
- Avoid abbreviations and single-letter variables (except for short loop counters)
Refactoring Guidelines
- If you find yourself wanting to add an inline comment, stop and refactor instead
- Extract the code block into a function with a descriptive name
- The function name should explain what the inline comment would have said
Examples
❌ BAD - Inline comments:
# Parse the request data
var data = parse_request(request)
# Check if user is valid
if user.is_valid():
# Process the user
process_user(user)
✅ GOOD - Self-documenting code with docblocks:
## Validates user credentials and processes authentication request
## Returns true if authentication succeeds, false otherwise
func authenticate_user(credentials: Dictionary) -> bool:
var user = find_user_by_credentials(credentials)
if not user or not user.is_valid():
return false
return process_authentication(user)
## Converts raw HTTP request data into a structured request object
## Parameters:
## - raw_data: The complete HTTP request as a string
## Returns: Dictionary containing parsed headers, body, and method
## Throws: Returns error dictionary if request format is invalid
func parse_http_request(raw_data: String) -> Dictionary:
# Implementation here
Adding New Tools
-
Create your tool class:
@tool extends MCPTool class_name YourTool ## Returns the unique identifier for this tool func get_name() -> String: return "your_tool_name" ## Returns a description of what this tool does func get_description() -> String: return "Clear description of tool functionality" ## Returns the input schema defining required parameters func get_input_schema() -> z_schema: return Z.schema({ "param1": Z.string().describe("Parameter description"), "param2": Z.integer().nullable().describe("Optional parameter") }) ## Executes the tool with validated parameters ## Parameters: ## - params: Dictionary containing validated tool input ## Returns: Dictionary with success data or error message func run(params: Dictionary) -> Dictionary: # Tool implementation return ok("Success message")
-
Register your tool:
# In plugin.gd http_server.start(MCPRouter.new([ CreateNodeTool.new(), YourTool.new() # Add your tool here ]), 8080)
-
Add tests:
# In tests/test_your_tool.gd extends RefCounted class_name TestYourTool func test_your_tool_functionality() -> void: var tool = YourTool.new() var result = tool.run({"param1": "test_value"}) assert(result.has("content"), "Tool should return content")
Schema Validation with Zodot
Use Zodot for robust parameter validation:
# Basic types
Z.string() # String parameter
Z.integer() # Integer parameter
Z.boolean() # Boolean parameter
Z.dictionary() # Dictionary parameter
# Modifiers
Z.string().nullable() # Optional string
Z.integer().describe("desc") # With description
# Complex schemas
Z.schema({
"user": Z.schema({
"name": Z.string(),
"age": Z.integer()
}),
"tags": Z.array().items(Z.string())
})
Development Workflow
- Fork and clone the repository
- Create a feature branch:
git checkout -b feature/new-tool
- Follow code standards outlined above
- Add comprehensive tests for your changes
- Submit a pull request with clear description
Testing
WIP: it don't work.
GDScript Specific Guidelines
- Follow GDScript naming conventions (snake_case for variables/functions, PascalCase for classes)
- Use type hints wherever possible
- Prefer
match
statements over longif/elif
chains - Use
const
for compile-time constants,var
for variables - Favor composition over inheritance
- Use dependency injection for better testability
- Keep classes focused on a single responsibility
Troubleshooting
Common Issues
Server won't start:
- Check if port 8080 is already in use
- Ensure the plugin is properly enabled
- Check Godot's Output panel for error messages
Tools not found:
- Verify tools are properly registered in
plugin.gd
- Check tool names match exactly (case-sensitive)
- Ensure tools inherit from
MCPTool
Schema validation errors:
- Verify parameter types match schema definitions
- Check for missing required parameters
- Ensure Zodot schemas are properly defined
License
This project is licensed under the MIT License - see the file for details.
Contributing
We welcome contributions! Please read our contributing guidelines above and ensure your code follows our quality standards.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: MCP Specification