Skip to main content
Glama
RenderDoc MCP
by LifeSugar

RenderDoc MCP

Let AI clients that support the Model Context Protocol (MCP) analyze RenderDoc capture files directly: browse Draw/Dispatch events, inspect pipeline and shaders, and page through vertex and constant buffer data.

The repository contains a runnable MCP stdio service, session and path safety boundaries, a Mock backend for development testing, and a real Replay bridge backend that connects to qrenderdoc 1.44.

[!IMPORTANT] The qrenderdoc backend is currently recommended for connecting real captures; the renderdoc / native backend remains a reserved implementation.

The real bridge consists of two processes: a modern Python 3.11 MCP Gateway, and a UI extension running inside qrenderdoc's embedded Python 3.6. The two communicate over a native file-queue JSON protocol with a random token; this avoids depending on the _socket module, which is missing from RenderDoc's slim Python.

MCP Client  <-- stdio -->  Python 3.11 Gateway
                                  |
                         authenticated JSON spool
                                  |
                           qrenderdoc extension
                                  |
                         RenderDoc ReplayController

Existing capabilities

  • MCP stdio service with structured tool responses.

  • .rdc path whitelist, file type, size, and session count limits.

  • Launch standalone whitelisted .exe files via RenderDoc injection, with arguments passed as an array and no shell execution.

  • Stable capture_id, explicit event_id, no reliance on hidden current-event selection.

  • Serial per-capture backend access, leaving headroom for RenderDoc ReplayController's threading model.

  • Action filtering and cursor-based pagination.

  • inspect_event composite call, avoiding a large number of fine-grained MCP round trips for a single inspection.

  • Read topology, viewport/scissor, shaders, resource bindings, render targets, and validation messages for the current event.

  • Unified error structure and a passive capture summary Resource.

First batch of tools:

  • health

  • launch_program

  • open_capture

  • close_capture

  • get_capture_summary

  • list_actions

  • get_event

  • inspect_event

  • get_pipeline_state

  • get_shader

  • get_vertex_data

  • list_constant_buffers

  • get_constant_buffer

Pipeline, shader, and buffer data

  • get_pipeline_state without a section argument returns a cross-API common snapshot and api_specific_sections; passing any of those names as section in a follow-up call reads the full top-level state group for D3D11, D3D12, Vulkan, or OpenGL.

  • get_shader reads reflection, disassembly, source, or raw per stage. The latter three large content types are paged with cursor / next_cursor; source_file_index can traverse every embedded source file.

  • get_vertex_data expands instances and draw vertices into stable records, returning decoded values for all attributes, exact raw_hex, actual buffer offsets, and format metadata; uv_attributes explicitly marks UV / TEXCOORD. Keep following next_cursor to cover all instances and vertices.

  • list_constant_buffers enumerates every shader stage, reflection block, and array element; then use get_constant_buffer to read all decoded variables in that group. The underlying raw bytes are paged with raw_offset / next_offset, so no data is lost even beyond the single-read limit.

Related MCP server: RenderDoc MCP Server

Environment

  • Python 3.11+

  • MCP Python SDK stable line >=1.27,<2

  • RenderDoc/qrenderdoc 1.44 (real bridge backend)

SDK v2 is still in pre-release, so this project is pinned to v1.x for now, avoiding framework code changing with pre-release interfaces.

Quick start (Mock backend)

In PowerShell:

python -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
$env:RENDERDOC_MCP_BACKEND = "mock"
$env:RENDERDOC_MCP_ALLOWED_ROOTS = (Get-Location).Path
.venv\Scripts\python -m renderdoc_mcp

stdio is the protocol channel; do not write normal logs to stdout.

Using MCP Inspector:

.venv\Scripts\mcp dev src\renderdoc_mcp\server.py

The Mock backend still requires a real, whitelisted .rdc path to be passed in, but it does not parse the file contents.

Installing the qrenderdoc bridge

Assuming RenderDoc is installed at C:\Tools\RenderDoc, run the following in the project directory:

powershell -ExecutionPolicy Bypass -File .\scripts\install_qrenderdoc_bridge.ps1 `
  -RenderDocRoot C:\Tools\RenderDoc

The script will:

  • Install the extension to %APPDATA%\qrenderdoc\extensions\renderdoc_mcp_bridge;

  • Generate a random token and write it to bridge_config.json on the extension side;

  • Generate .renderdoc-mcp-bridge.json in the project root for the Gateway to use.

Then open C:\Tools\RenderDoc\qrenderdoc.exe, go to Tools → Manage Extensions, select RenderDoc MCP Bridge, click Load first, and after it succeeds check Always Load. When using the real backend, qrenderdoc must stay running; the spool directory defaults to .renderdoc-mcp-spool inside the project, which is Git-ignored.

During development you can also have qrenderdoc run a load script automatically once the UI opens:

C:\Tools\RenderDoc\qrenderdoc.exe --ui-python .\scripts\load_qrenderdoc_bridge.py

This command only handles loading for that session; for daily use it is still recommended to check Always Load in the extension manager.

MCP client configuration example

Replace the paths with your actual locations:

{
  "mcpServers": {
    "renderdoc": {
      "command": "C:\\path\\to\\RenderDoc_MCP\\.venv\\Scripts\\python.exe",
      "args": ["-m", "renderdoc_mcp"],
      "env": {
        "RENDERDOC_MCP_BACKEND": "qrenderdoc",
        "RENDERDOC_MCP_ALLOWED_ROOTS": "C:\\captures",
        "RENDERDOC_MCP_ALLOWED_EXECUTABLE_ROOTS": "C:\\projects\\my-renderer",
        "RENDERDOC_MCP_ARTIFACT_ROOT": "C:\\path\\to\\RenderDoc_MCP\\artifacts",
        "RENDERDOC_MCP_RENDERDOC_ROOT": "C:\\Tools\\RenderDoc"
      },
      "cwd": "C:\\path\\to\\RenderDoc_MCP"
    }
  }
}

In Codex's graphical configuration page, the arguments must be split into two lines: -m and renderdoc_mcp. Leave environment variable passthrough blank; set Working directory to the project root. Since .renderdoc-mcp-bridge.json already exists in the working directory, there is no need to paste the token manually into the MCP configuration.

Configuration options

Environment variable

Default

Description

RENDERDOC_MCP_BACKEND

mock

mock, qrenderdoc (real UI bridge), or renderdoc (reserved native backend)

RENDERDOC_MCP_ALLOWED_ROOTS

current directory

Directories where captures may be opened; multiple directories separated by the system path separator

RENDERDOC_MCP_ALLOWED_EXECUTABLE_ROOTS

empty (launch disabled)

Root paths for .exe files and working directories that launch_program may start; multiple directories separated by the system path separator

RENDERDOC_MCP_ARTIFACT_ROOT

./artifacts

Directory for artifacts such as PNG, shader, and JSON files generated later

RENDERDOC_MCP_MAX_SESSIONS

2

Maximum concurrent capture sessions; the qrenderdoc backend is tightened to 1

RENDERDOC_MCP_MAX_CAPTURE_BYTES

8589934592

Maximum size limit for a single capture

RENDERDOC_MCP_MAX_PAGE_SIZE

100

Hard upper limit for a single Action page

RENDERDOC_MCP_MAX_BUFFER_READ_BYTES

65536

Hard upper limit for a single page of vertex, constant buffer, and shader content reads; cursors allow continued reading

RENDERDOC_MCP_RENDERDOC_ROOT

config file value

RenderDoc installation directory, e.g. E:\RenderDoc

RENDERDOC_MCP_BRIDGE_CONFIG

./.renderdoc-mcp-bridge.json

Gateway bridge configuration file

RENDERDOC_MCP_BRIDGE_SPOOL_DIR

config file value

Local bridge request/response queue directory

RENDERDOC_MCP_BRIDGE_TOKEN

config file value

Optional environment variable override; normally no manual configuration needed

RENDERDOC_MCP_BRIDGE_TIMEOUT_SECONDS

120

Timeout for a single bridge request

Launching a program from RenderDoc

First add your program's project root to RENDERDOC_MCP_ALLOWED_EXECUTABLE_ROOTS, restart the MCP service, then call:

{
  "executable": "C:\\projects\\my-renderer\\bin\\renderer.exe",
  "arguments": ["--scene", "C:\\projects\\my-renderer\\scenes\\demo.json"],
  "working_directory": "C:\\projects\\my-renderer",
  "hook_into_children": false,
  "api_validation": false
}

A successful result includes the RenderDoc target-control ident and the capture file template. The program has been injected by RenderDoc, so you can press the default capture hotkey F12 in the program window. This tool does not accept shell commands or environment variable modifications; enable hook_into_children only if child processes also need to be injected, and api_validation only if the API validation layer is needed.

Testing

After installing development dependencies:

.venv\Scripts\python -m pytest
.venv\Scripts\ruff check .

Core service tests can also run without third-party test dependencies:

$env:PYTHONPATH = "src"
python -m unittest discover -s tests -v

Safety boundaries

  • Only .rdc files under RENDERDOC_MCP_ALLOWED_ROOTS can be opened.

  • launch_program is disabled by default and can only launch .exe files under RENDERDOC_MCP_ALLOWED_EXECUTABLE_ROOTS.

  • Launch arguments are passed as an array, not through a shell; the Gateway does not allow modifying the target program's environment variables through tools.

  • Native messages between the Gateway and the qrenderdoc extension are authenticated with a random token generated at install time.

  • Action, shader, vertex, and buffer data are all subject to pagination or single-read limits.

Project status and next steps

The bridge main path, pipeline state, shaders, vertex input, and constant buffer reads are implemented. Future tasks can continue with Texture export, generic buffer readback, Pixel History, and artifact management.

See the architecture notes for detailed boundaries.

License

MIT

Available Tools

13 tools
close_captureB

Close a capture session and release its replay resources.

Inputs: capture_id (required). Returns: object

get_capture_summaryB

Return metadata and warnings for an open capture session.

Inputs: capture_id (required). Returns: object

get_constant_bufferC

Read decoded variables and a bounded raw-byte page for one constant-buffer group.

Inputs: stage (required), event_id (required), capture_id (required), block_index (required), +3 more. Returns: object

get_eventC

Get draw, dispatch, copy, marker, or present details for one event ID.

Inputs: event_id (required), capture_id (required). Returns: object

get_pipeline_stateC

Read common pipeline state or one API-specific top-level state section.

Inputs: event_id (required), capture_id (required), section. Returns: object

get_shaderC

Read a bound shader's reflection, disassembly, source, or raw bytes in pages.

Inputs: stage (required), event_id (required), capture_id (required), cursor, +4 more. Returns: object

get_vertex_dataC

Page through every vertex/instance input and decoded attribute, including UVs.

Inputs: event_id (required), capture_id (required), limit, cursor. Returns: object

healthA

Check gateway limits and whether the configured replay backend is available.

Inputs: no named parameters. Returns: object

inspect_eventC

Inspect selected pipeline sections for an event in one serialized replay call.

Inputs: event_id (required), capture_id (required), include. Returns: object

launch_programC

Launch and inject an allow-listed .exe through qrenderdoc/RenderDoc.

Inputs: executable (required), arguments, api_validation, working_directory, +1 more. Returns: object

list_actionsC

List capture actions with filtering and bounded cursor pagination.

Inputs: capture_id (required), kind, limit, query, +3 more. Returns: object

list_constant_buffersC

List every shader-stage/block/array constant-buffer group with pagination.

Inputs: event_id (required), capture_id (required), limit, cursor. Returns: object

open_captureB

Open one allow-listed .rdc file and return a stable capture_id.

Inputs: path (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 13 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes across lifecycle, metadata, and inspection. However, get_event, inspect_event, and get_pipeline_state all operate on event IDs and pipeline data, creating some boundary overlap that could cause misselection in an agent.

    Naming Consistency4/5

    Nearly all tools follow a clean snake_case verb_noun pattern (open_capture, get_event, list_actions, get_constant_buffer). The lone 'health' deviates as a bare noun, but it is a widely recognized convention so the impact is minor.

    Tool Count5/5

    13 tools is well-scoped for a graphics debugging/replay server, with each tool earning its place across session lifecycle, event inspection, and pipeline/shader data retrieval. No redundancy or bloat.

    Completeness4/5

    Covers the core lifecycle (launch, open, close) plus rich inspection of actions, events, pipeline state, shaders, vertex data, and constant buffers. Minor gaps exist for resource/texture inspection or capture export, but core workflows are well covered.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers