You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MCP: Audit and harden native MCP server implementation (#1290)
* MCP: Audit and harden native MCP server implementation
Fixes several bugs, improves spec compliance, and fills in missing
functionality across the MCP module.
Bugfixes:
- Fix null-deref crash in capture action when viewport returns no image
or PNG encoding fails (mcp_bridge.cpp)
- Fix double-wrapped JSON-RPC error responses: pre-init tools/* requests
now return a proper top-level error via process_string override instead
of being nested inside a result envelope (mcp_protocol.{h,cpp})
- Fix double-wrapping on INVALID_PARAMS paths in tools/call handler
Protocol compliance:
- Update protocol version from 2024-11-05 to 2025-06-18
- Add version negotiation: echo client version if supported, else return
latest (mcp_protocol.cpp)
- Move initialized flag from initialize response to notifications/initialized
per spec lifecycle requirements
- Declare tools.listChanged capability explicitly
Security and robustness:
- Harden validate_path: segment-based .. check instead of substring match,
applied consistently to all path-accepting actions (instance_path,
resource paths, code_intel paths were previously unvalidated)
- Fix bridge concurrency: update() no longer drops an active connection
mid-command when a new peer connects
- Improve send_command: chunked reads via CharString accumulation with
single-pass UTF-8 decode to handle multi-byte chars across TCP boundaries
New functionality:
- Implement code_intel search action (recursive .gd file content search)
- Implement project_config add_input action (writes InputEventKey to
project.godot with runtime InputMap registration)
- Implement project_config add_autoload action (writes autoload entry
to project.godot)
Quality improvements:
- Add MCP tool annotations (readOnlyHint, destructiveHint, etc.) to all
5 tools per 2025-06-18 spec
- Clarify project_config schema descriptions (which params each action
uses) to prevent agent confusion
- Improve _ensure_callback_exists: word-boundary detection handles
static func and annotation prefixes
- Add signal-exists validation before connect() in scene_action
- Remove dead code (_make_text_content)
- Fill in class reference documentation for MCPServer, MCPBridge,
MCPProtocol
AI tools were used in the development of this contribution, in
accordance with the project AI Policy. All changes have been manually
tested end-to-end with a live MCP handshake across all 5 tools.
* MCP: Validate autoload files and refresh input actions
Reject nonexistent autoload paths before modifying project settings. When an input action already exists, replace its live deadzone and event bindings so its runtime state matches the persisted project configuration.
TCP bridge relaying commands between the MCP server and a running game process.
4
5
</brief_description>
5
6
<description>
7
+
[MCPBridge] is a bidirectional TCP relay. On the server (headless) side it listens on an ephemeral loopback port and sends commands produced by MCP tools. On the game side (started with the [code]--mcp-bridge-port[/code] flag) it connects back to that port, receives commands, executes them against the live scene tree/viewport, and returns results. The bridge is single-connection and automatically replaces a stale peer when a new game process connects.
6
8
</description>
7
9
<tutorials>
8
10
</tutorials>
9
11
<methods>
10
12
<methodname="update">
11
13
<returntype="void" />
12
14
<description>
15
+
Pumps the bridge: on the host side it accepts pending connections; on the game side it reads incoming commands, dispatches them, and writes responses. Called each frame from the main loop (game side) or the server's bridge thread (host side).
MCP JSON-RPC protocol handler: capability negotiation, tool listing, and dispatch.
4
5
</brief_description>
5
6
<description>
7
+
Implements the Model Context Protocol request layer on top of the JSONRPC class. Handles the [code]initialize[/code] handshake with version negotiation, the [code]notifications/initialized[/code] lifecycle event, [code]ping[/code], [code]tools/list[/code], and [code]tools/call[/code]. Tool execution is delegated to the internal MCPTools class. The operation phase is gated until the [code]initialized[/code] notification is received, per spec.
6
8
</description>
7
9
<tutorials>
8
10
</tutorials>
9
11
<methods>
10
12
<methodname="is_initialized"qualifiers="const">
11
13
<returntype="bool" />
12
14
<description>
15
+
Returns [code]true[/code] after the client has sent the [code]notifications/initialized[/code] handshake message, marking the start of the operation phase.
Stdio-based MCP (Model Context Protocol) server for AI agent integration.
4
5
</brief_description>
5
6
<description>
7
+
The MCP server exposes the running Redot project to AI coding assistants over a JSON-RPC stdio transport. It is started with the [code]--mcp-server[/code] command-line flag, which implies headless mode. The server reads newline-delimited JSON-RPC requests on stdin and writes responses to stdout. A TCP bridge ([MCPBridge]) is used to forward tool calls (screenshots, input, tree inspection) to a separately launched game process. See [url=https://modelcontextprotocol.io/]the MCP specification[/url] for protocol details.
6
8
</description>
7
9
<tutorials>
8
10
</tutorials>
9
11
<methods>
10
12
<methodname="is_running"qualifiers="const">
11
13
<returntype="bool" />
12
14
<description>
15
+
Returns [code]true[/code] while the server loop is processing requests.
13
16
</description>
14
17
</method>
15
18
<methodname="start">
16
19
<returntype="void" />
17
20
<description>
21
+
Starts the blocking server loop. Reads requests from stdin and dispatches them to the registered protocol handlers. Returns when the input stream is closed or [method stop] is requested.
18
22
</description>
19
23
</method>
20
24
<methodname="stop">
21
25
<returntype="void" />
22
26
<description>
27
+
Signals the server loop to stop and wakes the stdin poll.
0 commit comments