Skip to content

MCP: Audit and harden native MCP server implementation#1290

Merged
Arctis-Fireblight merged 4 commits into
Redot-Engine:masterfrom
MichaelFisher1997:mcp-audit
Jul 11, 2026
Merged

MCP: Audit and harden native MCP server implementation#1290
Arctis-Fireblight merged 4 commits into
Redot-Engine:masterfrom
MichaelFisher1997:mcp-audit

Conversation

@MichaelFisher1997

@MichaelFisher1997 MichaelFisher1997 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

A comprehensive audit and hardening of the native MCP (Model Context Protocol) server module (modules/mcp/). The module was functional but had several bugs, spec compliance gaps, and unimplemented actions advertised in the tool schemas.

Bugfixes

  • Capture crash: Null-deref in capture action when viewport returns no image (headless/first-frame) or PNG encoding fails
  • Double-wrapped errors: Pre-init tools/* requests returned a JSON-RPC error nested inside a result envelope instead of a top-level error. Fixed via a process_string override that gates pre-init requests and notifications

Protocol compliance

  • Updated protocol version from 2024-11-05 to 2025-06-18 with proper version negotiation (echoes client version if supported)
  • Moved initialized flag from initialize response to notifications/initialized per spec lifecycle
  • Declared tools.listChanged capability explicitly

Security & robustness

  • Hardened validate_path: segment-based .. traversal check, applied consistently to all path-accepting actions (previously instance_path, resource paths, and code_intel paths were unvalidated)
  • Fixed bridge concurrency: update() no longer drops an active connection mid-command
  • Improved send_command: chunked reads via CharString accumulation with single-pass UTF-8 decode

New functionality

  • code_intel search action: recursive .gd file content search
  • project_config add_input action: writes InputEventKey to project.godot with runtime InputMap registration
  • project_config add_autoload action: writes autoload entry to project.godot

Quality

  • MCP tool annotations (readOnlyHint, destructiveHint, etc.) on all 5 tools per 2025-06-18 spec
  • Clarified project_config schema descriptions (which params each action uses)
  • Improved _ensure_callback_exists word-boundary detection (handles static func, annotation prefixes)
  • Added signal-exists validation before connect() in scene_action
  • Filled in class reference docs for MCPServer, MCPBridge, MCPProtocol
  • Removed dead code (_make_text_content)

Testing

All changes manually tested end-to-end with a live MCP handshake (--mcp-server --headless) across all 5 tools:

Tool Actions verified
code_intel get_symbols, get_docs, validate, search
game_control wait, capture, inspect_live, click, trigger_action, type
project_config get_info, list_files, run, stop, output, read_file_res, create_file_res, set_setting, add_input, add_autoload
resource_action inspect, inspect_asset, create, modify, duplicate
scene_action get_node, create, add, set_prop, instance, reparent, remove, connect

Pre-init gating verified: single requests return JSON-RPC error, notifications are silently dropped.

Notes

  • AI tools were used during development, in accordance with the project AI Policy. All changes have been manually tested and reviewed.
  • Built and tested on Linux (linuxbsd platform, editor target).

Checklist

  • Code compiles (scons platform=linuxbsd target=editor)
  • Manually tested all advertised tool actions
  • Class reference documentation updated
  • Pre-commit hooks passed (clang-format, codespell, copyright-headers, header-guards, file-format)
  • CodeRabbit review addressed

Summary by CodeRabbit

  • New Features
    • Added code search across GDScript files with contextual results and truncation notice.
    • Added project configuration actions for input mappings and autoloads.
    • Added richer tool metadata (annotations) and enhanced tool discovery/execution support.
  • Bug Fixes
    • Improved protocol version negotiation and deferred initialization until the initialized notification is received.
    • Hardened tool request handling before initialization and improved invalid-request errors.
    • Improved TCP response decoding and connection handling; strengthened capture error reporting.
  • Documentation
    • Expanded MCP bridge, protocol, and server lifecycle documentation.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 24eb4c2c-2d29-4433-95b2-8b2d87217b1b

📥 Commits

Reviewing files that changed from the base of the PR and between e64e6b5 and 1a97674.

📒 Files selected for processing (1)
  • modules/mcp/mcp_tools.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • modules/mcp/mcp_tools.cpp

Walkthrough

The PR updates MCP documentation and runtime behavior, including protocol version negotiation, initialization gating, TCP bridge handling, tool validation and annotations, GDScript search, project input/autoload configuration, and capture error reporting.

Changes

MCP runtime and tools

Layer / File(s) Summary
Protocol negotiation and initialization
modules/mcp/mcp_types.h, modules/mcp/mcp_protocol.*, modules/mcp/doc_classes/MCPProtocol.xml
MCP versions are negotiated, initialization completes through notifications/initialized, pre-initialization tool requests are gated, and tool capabilities expose listChanged.
TCP bridge transport and capture errors
modules/mcp/mcp_bridge.cpp, modules/mcp/doc_classes/MCPBridge.xml
Bridge responses are buffered before UTF-8 decoding, active connections are preserved, capture failures return errors, and bridge behavior is documented.
Tool metadata and validation
modules/mcp/mcp_types.h, modules/mcp/mcp_tools.cpp
Tool annotations are added, path and callback checks are strengthened, and scene and resource actions validate inputs more thoroughly.
Code search and project configuration actions
modules/mcp/mcp_tools.cpp
Code intelligence supports bounded recursive GDScript search, while project configuration can add input actions and autoload entries.
MCP server lifecycle documentation
modules/mcp/doc_classes/MCPServer.xml
MCP server stdio behavior and the is_running, start, and stop methods are documented.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MCPProtocol
  participant JSONRPC
  participant MCPTools
  Client->>MCPProtocol: initialize with protocolVersion
  MCPProtocol->>Client: negotiated version and capabilities
  Client->>MCPProtocol: notifications/initialized
  MCPProtocol->>MCPProtocol: enable tool requests
  Client->>MCPProtocol: tools/list or tools/call
  MCPProtocol->>JSONRPC: process request
  JSONRPC->>MCPTools: list or execute tool
Loading

Possibly related PRs

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the PR’s main theme: auditing and hardening the native MCP server implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.
@MichaelFisher1997
MichaelFisher1997 marked this pull request as ready for review July 11, 2026 01:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modules/mcp/mcp_tools.cpp`:
- Around line 1000-1015: Before persisting the autoload in the add_autoload
action, verify that the normalized path exists using FileAccess::exists; if it
does not, return an appropriate error through result.set_error and avoid
modifying ProjectSettings. Keep the existing validate_path check and place the
existence guard before set_setting.
- Around line 986-998: Update the runtime registration logic in the add_input
implementation: when InputMap already contains action_name, clear its existing
events and set its deadzone to the new value before adding events; only
add_action for new actions, ensuring runtime state matches the overwritten
ProjectSettings entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 62d6e11e-315f-4485-922f-db25499426c0

📥 Commits

Reviewing files that changed from the base of the PR and between d93bf62 and e64e6b5.

📒 Files selected for processing (8)
  • modules/mcp/doc_classes/MCPBridge.xml
  • modules/mcp/doc_classes/MCPProtocol.xml
  • modules/mcp/doc_classes/MCPServer.xml
  • modules/mcp/mcp_bridge.cpp
  • modules/mcp/mcp_protocol.cpp
  • modules/mcp/mcp_protocol.h
  • modules/mcp/mcp_tools.cpp
  • modules/mcp/mcp_types.h

Comment thread modules/mcp/mcp_tools.cpp
Comment thread modules/mcp/mcp_tools.cpp
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.
@Arctis-Fireblight Arctis-Fireblight self-assigned this Jul 11, 2026
@Arctis-Fireblight
Arctis-Fireblight merged commit efd15f0 into Redot-Engine:master Jul 11, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants