MCP Server

August 8, 2026 · View on GitHub

D3D12LookDevPT includes a local MCP server for inspecting and controlling the running renderer from tools such as VS Code, Codex, or custom JSON-RPC clients. The server exposes the same validation-oriented action layer used by the ImGui UI.

Japanese documentation: MCP サーバー

MCP-Driven Workflow Example

The screenshot below shows the renderer side of a typical local workflow: an MCP-capable client issues camera, quality, or denoise requests, and D3D12LookDevPT applies them through its validated action layer.

D3D12LookDevPT running the MCP server with recent local requests

The viewport above is the renderer with the MCP server running, recent local JSON-RPC requests listed, and the bearer token area redacted. Do not commit real MCP tokens in screenshots or project files.

The client should validate settings first, apply mutation tools, then read state back to confirm that the renderer accepted the same values. Treat the live schema returned by tools/list or lookdevpt://actions/schema—and the examples below—as authoritative for the current build.

Availability And Security

  • Endpoint: http://127.0.0.1:<port>/mcp
  • Default port: 8777
  • Bind address: 127.0.0.1 only
  • Transport: Streamable HTTP JSON-RPC, plus subscription SSE, over POST /mcp
  • Protocol versions accepted: 2026-07-28, 2025-11-25, 2025-06-18
  • Authentication: Authorization: Bearer <token> is required
  • Modern era (2026-07-28): stateless requests; no initialize or MCP-Session-Id
  • Legacy eras (2025-11-25, 2025-06-18): initialize creates an MCP-Session-Id; sessions expire after 30 minutes idle
  • Server-Sent Events: subscriptions/listen uses an SSE response to POST; GET /mcp remains 405 Method Not Allowed
  • Maximum HTTP request body: 16 MiB; both Content-Length and Transfer-Encoding: chunked are supported
  • Limits: 64 simultaneous connections, 16 simultaneous subscriptions, and 64 legacy sessions

The bearer token and MCP settings are stored in:

%APPDATA%\D3D12LookDevPT\settings.json

This file is user-local. Do not copy the token into .lookdevpt.json, README files, screenshots, issue comments, or committed VS Code settings.

The server accepts an absent Origin, or an HTTP origin whose parsed host is 127.0.0.1, localhost, or [::1] (with an optional valid port). Origin: null, a non-loopback Host, and all other origins are rejected with 403.

Starting The Server

Use the dockable MCP Server panel:

  • Start Server / Stop Server
  • Port
  • Request Timeout
  • Access Mode
  • Copy Token
  • Regenerate Token
  • pending approvals and recent request log

The server is disabled by default. It can also be started from the command line:

.\Bin\x64\Debug\D3D12LookDevPT.exe --mcp-server --mcp-port 8777 --mcp-token <token> --mcp-access confirm_mutations

Access modes:

  • read_only: read tools work; mutation tools are rejected.
  • confirm_mutations: mutation tools wait for approval in the ImGui MCP Server panel.
  • allow_mutations: mutation tools execute without UI approval.

The mutation queue is processed on the main thread and has a limit of 16 queued requests. Mutations never touch D3D12 or ImGui state directly from the HTTP server thread.

capture_viewport is a read operation, but it is still queued on the renderer thread because it performs a GPU readback. capture_debug_pack temporarily changes the debug view and invalidates its related temporal history, so it requires mutation access (and approval in confirm_mutations mode). Its restoreView option defaults to true.

Snapshot Cadence And Freshness

MCP reads use mutex-protected snapshots rather than walking renderer or scene data on the HTTP thread. Snapshot work is disabled while the server is stopped. Starting the server forces an initial snapshot; while it is running:

  • state is refreshed about every 33 ms (30 Hz).
  • stats and diagnostics are refreshed about every 100 ms (10 Hz).
  • materials, project, scene/summary, material variants, and presets are rebuilt only when their scene/project/catalog revisions change.
  • Debug-view, render-mode, and action-schema resources are generated from fixed metadata on demand.

The same publication points drive subscriptions/listen. Notifications are coalesced by URI and snapshot revision, so state is published at no more than 30 Hz, stats/diagnostics at no more than 10 Hz, revision resources only when their serialized content changes, and capture index/latest when captures change.

A read immediately following a mutation can therefore normally trail the renderer by one refresh interval. If a client must verify a value, read get_state again after that interval while the renderer is advancing frames. Mutation, validation, and capture operations are serialized through the main-thread queue; ordinary snapshot reads do not block renderer state mutation.

VS Code Configuration

VS Code stores MCP server configuration in mcp.json, either in .vscode/mcp.json or in the user profile. VS Code's current MCP configuration reference uses type, url, and headers for HTTP servers, with optional inputs for secrets.

Example .vscode/mcp.json:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "lookdevpt-token",
      "description": "D3D12LookDevPT MCP bearer token",
      "password": true
    }
  ],
  "servers": {
    "d3d12LookDevPT": {
      "type": "http",
      "url": "http://127.0.0.1:8777/mcp",
      "headers": {
        "Authorization": "Bearer ${input:lookdevpt-token}"
      }
    }
  }
}

Use MCP: List Servers to start or restart the server entry after editing the file. Use MCP: Reset Cached Tools if the tool list changes after rebuilding D3D12LookDevPT.

Notes:

  • Start D3D12LookDevPT and its MCP server before starting the VS Code MCP entry.
  • If the token is regenerated in ImGui, restart the VS Code MCP server entry and enter the new token.
  • Let VS Code negotiate the protocol version and generate MCP routing headers. Do not pin MCP-Protocol-Version in mcp.json.
  • The subscription stream is a response to POST subscriptions/listen; the deprecated unsolicited GET stream is not implemented.

LocalMCPChatClient Configuration

For LocalMCPChatClient, import config/LocalMCPChatClient.mcp.json from Settings, MCP connections, JSON import.

  1. Copy the token from the MCP Server panel.
  2. Store only the token in the Windows user environment variable D3D12LOOKDEVPT_MCP_TOKEN.
  3. Fully exit and restart LocalMCPChatClient so it sees the updated environment.
  4. Import the JSON, then run connection test, save, and connect.

The example maps Authorization: Bearer ${env:D3D12LOOKDEVPT_MCP_TOKEN} to LocalMCPChatClient's bearer-token environment setting and disables standalone GET. Do not put the token or a pinned MCP-Protocol-Version in a tracked file. MCP C# SDK 2.1.0 and this server negotiate the stateless 2026-07-28 protocol automatically.

When both repositories are cloned under the same parent directory, the following script starts the D3D12LookDevPT test host and verifies tools/list plus lookdevpt.get_state through the real LocalMCPChatClient implementation:

.\Scripts\TestLocalMcpChatClientIntegration.ps1

JSON-RPC Flow

2026-07-28 is the preferred path. Every request carries its protocol version and client capabilities in params._meta, plus matching MCP-Protocol-Version and Mcp-Method headers. tools/call, resources/read, and prompts/get also carry a matching Mcp-Name. No initialization or session header is used.

Every successful modern result carries resultType: "complete" and _meta["io.modelcontextprotocol/serverInfo"]. server/discover reports the supported versions and the tools/resources/prompts capabilities. These modern-only fields are not added to legacy responses.

Discover and call a read tool from PowerShell:

$endpoint = "http://127.0.0.1:8777/mcp"
$token = "<token>"
$baseHeaders = @{
  "Authorization" = "Bearer $token"
  "Accept" = "application/json, text/event-stream"
  "MCP-Protocol-Version" = "2026-07-28"
}

$meta = @{
  "io.modelcontextprotocol/protocolVersion" = "2026-07-28"
  "io.modelcontextprotocol/clientInfo" = @{ name = "manual-client"; version = "1.0" }
  "io.modelcontextprotocol/clientCapabilities" = @{}
}

$discoverHeaders = $baseHeaders.Clone()
$discoverHeaders["Mcp-Method"] = "server/discover"
$discoverBody = @{
  jsonrpc = "2.0"
  id = 1
  method = "server/discover"
  params = @{ _meta = $meta }
} | ConvertTo-Json -Depth 10 -Compress

Invoke-RestMethod -Uri $endpoint -Method Post -Headers $discoverHeaders -ContentType "application/json" -Body $discoverBody

$callHeaders = $baseHeaders.Clone()
$callHeaders["Mcp-Method"] = "tools/call"
$callHeaders["Mcp-Name"] = "lookdevpt.get_state"
$body = @{
  jsonrpc = "2.0"
  id = 2
  method = "tools/call"
  params = @{
    _meta = $meta
    name = "lookdevpt.get_state"
    arguments = @{}
  }
} | ConvertTo-Json -Depth 10 -Compress

Invoke-RestMethod -Uri $endpoint -Method Post -Headers $callHeaders -ContentType "application/json" -Body $body

Header values that cannot be represented safely as an HTTP field value use the MCP =?base64?<payload>?= sentinel form. The server decodes this form before comparing it with the JSON body.

Legacy clients may continue to use the existing sequence: initialize, retain the returned MCP-Session-Id, send notifications/initialized, then include the session id on later calls. DELETE /mcp ends a legacy session; modern DELETE is rejected with 405.

Resource Subscriptions

server/discover advertises resources: { "subscribe": true, "listChanged": false }. Open a subscriptions/listen request and include the resource URIs of interest in notifications.resourceSubscriptions. The first SSE event is always notifications/subscriptions/acknowledged and contains only accepted URIs. Later updates use notifications/resources/updated with the same subscription id.

This PowerShell example uses curl.exe because the response stays open:

$listenBody = @{
  jsonrpc = "2.0"
  id = 30
  method = "subscriptions/listen"
  params = @{
    _meta = $meta
    notifications = @{
      resourceSubscriptions = @("lookdevpt://state", "lookdevpt://diagnostics")
    }
  }
} | ConvertTo-Json -Depth 10 -Compress

curl.exe -N $endpoint `
  -H "Authorization: Bearer $token" `
  -H "Accept: application/json, text/event-stream" `
  -H "Content-Type: application/json" `
  -H "MCP-Protocol-Version: 2026-07-28" `
  -H "Mcp-Method: subscriptions/listen" `
  --data-binary $listenBody

The server sends a comment keepalive every 15 seconds, does not emit SSE event ids, ignores Last-Event-ID, drops subscriptions on client disconnect, and sends a final complete result during graceful server shutdown.

Tools

Read tools:

  • lookdevpt.get_stats: returns adapter, DXR tier, resolution, aggregate GPU timing, scene counts, history/resource-memory status, active secondary shading rate, denoiser status, and MCP queue state.
  • lookdevpt.get_state: returns scene/project paths, quality and ray-budget settings, camera, lighting, path tracing, ReSTIR/RTXDI status, denoise, frame-history revisions, and view state.
  • lookdevpt.list_materials: returns material names, usage counts, editable PBR factors, and texture slot state.
  • lookdevpt.list_debug_views: returns debug view ids, labels, and keys.
  • lookdevpt.list_render_modes: returns render mode labels and action values.
  • lookdevpt.get_diagnostics: returns scene/project/capture/MCP diagnostics.
  • lookdevpt.capture_viewport: captures the current final/debug viewport as PNG and returns an inline image/png plus lookdevpt://captures/latest.png.

Validation and capture workflow tools:

  • lookdevpt.validate_action: accepts { "method": "...", "params": { ... } } and runs the same action path with validateOnly=true.
  • lookdevpt.run_actions: validates and applies up to 16 action-layer calls as one MCP request. Validation failure prevents all mutation. Application is ordered but not rollback-transactional if a later runtime operation fails.
  • lookdevpt.capture_debug_pack: captures up to eight debug views and returns resource links for each PNG. It is treated as a mutation because it changes debug-view/history state while capturing.

Mutation tools:

  • lookdevpt.reset_accumulation
  • lookdevpt.reset_denoise_history
  • lookdevpt.reset_reservoirs
  • lookdevpt.reset_camera_view
  • lookdevpt.set_camera_speed
  • lookdevpt.fit_camera_to_scene
  • lookdevpt.set_display_resolution
  • lookdevpt.load_project
  • lookdevpt.save_project
  • lookdevpt.save_project_as
  • lookdevpt.set_scene
  • lookdevpt.set_camera
  • lookdevpt.set_material
  • lookdevpt.set_material_texture
  • lookdevpt.reset_material
  • lookdevpt.save_material_variant
  • lookdevpt.apply_material_variant
  • lookdevpt.delete_material_variant
  • lookdevpt.set_material_view
  • lookdevpt.set_color_management
  • lookdevpt.set_lighting
  • lookdevpt.set_path_tracing
  • lookdevpt.set_quality
  • lookdevpt.set_restir
  • lookdevpt.set_denoise
  • lookdevpt.set_view

Tool results primarily use structuredContent. A text content summary is also included for compatibility.

Resources

  • lookdevpt://state: current state JSON.
  • lookdevpt://stats: current stats JSON.
  • lookdevpt://diagnostics: scene, project, capture, and MCP diagnostics.
  • lookdevpt://materials: material list JSON.
  • lookdevpt://materials/{index}: one material object.
  • lookdevpt://materials/{index}/textures: source/current/override texture slots for one material.
  • lookdevpt://material-variants: saved per-material variant snapshots.
  • lookdevpt://material-presets: built-in and user material presets.
  • lookdevpt://debug-views: debug view ids, labels, and keys.
  • lookdevpt://render-modes: render modes and set_path_tracing.mode values.
  • lookdevpt://project: current project path and dirty flag.
  • lookdevpt://scene/summary: scene counts, bounds, lights, and asset paths.
  • lookdevpt://actions/schema: action names and JSON input schemas.
  • lookdevpt://captures/index: in-memory capture history.
  • lookdevpt://captures/latest.png: most recent PNG capture.
  • lookdevpt://captures/{id}.png: PNG from capture_viewport or capture_debug_pack.

Resource templates:

  • lookdevpt://captures/{id}.png
  • lookdevpt://materials/{index}
  • lookdevpt://materials/{index}/textures

Modern discover/list/read results include cacheScope: "private" and a ttlMs hint. Catalogs and immutable capture IDs use 3,600,000 ms; state uses 33 ms; stats/diagnostics use 100 ms; materials/project/scene/variants/presets use 1,000 ms; capture index/latest use 0 ms. Lists do not issue cursors, and a supplied cursor is rejected.

Prompts:

  • lookdevpt.inspect_scene: read state/stats/materials/diagnostics and summarize the scene.
  • lookdevpt.tune_denoise: propose and apply stable denoise settings through validation.
  • lookdevpt.setup_camera_shot: fit/refine a camera shot using scene bounds and state.
  • lookdevpt.capture_debug_review: capture a debug pack and summarize visible issues.

State, Stats, And Benchmark Metrics

Important get_state fields added for the stability/performance pipeline are:

  • quality: the stored/requested qualityProfile, restirBackend, secondaryShadingRate, complete rayBudget, finalTaa, sharpenStrength, and referenceSpp policy object. Profile- and availability-dependent results are reported separately by finalTaaActive, restir.effective, and denoise.activeBackend.
  • finalTaaActive: whether the selected profile and available pipeline are actually running Final TAA.
  • pathTracing.requestedSecondaryShadingRate, activeSecondaryRate, and autoSecondaryHalfActive: requested policy versus the currently active secondary rate.
  • restir.requestedBackend, effective, and rtxdiStatus: requested RTXDI path, compiled/runtime availability, active DI/GI state, and fallback reason.
  • frameState: frame/sample counters, change mask, valid history-domain mask, camera-cut flag, and independent scene/geometry/material/light/HDRI/backend/profile revisions.

Important get_stats groups are:

  • gpuTiming: last completed aggregate pipeline, Path Trace, ReSTIR reuse, denoise, copy, and UI timings, together with validity and completion serial.
  • historyDomains: valid history mask and the last change mask.
  • resourceMemory: frame/history bytes and MiB, the 512 MiB budget, budget status, and active allocation profile.
  • secondaryShading: requested/effective rate, active ratio, automatic half-rate state, additional-sample quota, bounce penalty, and over/under-budget counters.
  • denoiser and mcp: effective backend/history status and server queue state.

The benchmark CSV/JSON artifacts contain the heavier per-phase metrics—ReSTIR candidate/temporal/spatial/shade/publish, denoise prepare/core/composite, Final TAA, quality counters, history publish, detailed CPU stages, estimated ray budgets, and history/contribution diagnostics. get_stats intentionally remains a lower-cost aggregate snapshot. In a performance benchmark, full-screen quality counters are disabled; use a quality or combined run when those counters are required.

Example resource read:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "resources/read",
  "params": {
    "uri": "lookdevpt://actions/schema"
  }
}

Common Operations

Get camera:

{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.get_state",
    "arguments": {}
  }
}

Set camera:

{
  "jsonrpc": "2.0",
  "id": 11,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_camera",
    "arguments": {
      "position": [-14.7075, 7.99065, -11.7407],
      "yaw": 0.456,
      "pitch": -0.144733,
      "historyMode": "auto"
    }
  }
}

historyMode controls only this camera mutation:

  • auto (default): preserve and reproject history for ordinary motion, but classify a large teleport/turn as a camera cut.
  • preserve: force reprojection even when the automatic cut threshold would be exceeded. Use only when the previous and new views are intentionally continuous.
  • reset: mark an explicit camera cut and reject temporal history for the new frame.

Load Bistro:

{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_scene",
    "arguments": {
      "scenePath": "C:\\Projects\\D3D12LookDevPT\\Bistro_v5_2\\BistroExterior.fbx"
    }
  }
}

Set ReSTIR GI + DI:

{
  "jsonrpc": "2.0",
  "id": 13,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_path_tracing",
    "arguments": {
      "mode": "restir_gi_di",
      "samplesPerFrame": 2,
      "maxBounces": 4,
      "radianceClamp": 8.0
    }
  }
}

Set the interactive quality profile and automatic secondary shading budget:

{
  "jsonrpc": "2.0",
  "id": 14,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_quality",
    "arguments": {
      "qualityProfile": "interactive_game",
      "restirBackend": "rtxdi",
      "secondaryShadingRate": "auto",
      "rayBudget": {
        "movingSpp": 1,
        "movingBounces": 2,
        "staticBaseSpp": 1,
        "staticMaxSpp": 2,
        "staticBounces": 4,
        "settleFrames": 8,
        "targetGpuMs": 14.5
      },
      "finalTaa": true,
      "sharpenStrength": 0.0,
      "referenceSpp": 4096
    }
  }
}

secondaryShadingRate accepts auto, full, or adaptive_half. auto spends the additional-sample quota and then reduces bounce depth before enabling half-rate secondary shading after sustained budget overruns; recovery occurs only after a sustained under-budget period. adaptive_half forces the interactive secondary path to half rate, while full disables it. Sharp Preview and Reference Still always resolve this field to full. Partial set_quality calls preserve unspecified values, but changing profiles applies that profile's renderer/denoiser defaults and resets the affected histories.

Set the interactive denoise preset:

{
  "jsonrpc": "2.0",
  "id": 14,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_denoise",
    "arguments": {
      "preset": "interactive_stable",
      "temporalStability": true,
      "jitterMode": "stable32",
      "movingJitterScale": 0.25,
      "resetHistory": true
    }
  }
}

Select NRD REBLUR. When the NRD SDK and D3D12 evaluation resources are available, this becomes the active backend; otherwise the renderer safely falls back to the internal denoiser. Inspect denoise.activeBackend and denoise.nrd.fallbackReason from lookdevpt.get_state for the effective path. More setup notes are in Optional NVIDIA NRD Backend.

{
  "jsonrpc": "2.0",
  "id": 15,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_denoise",
    "arguments": {
      "backend": "nrd_reblur",
      "resetNrd": true
    }
  }
}

Select DLSS Ray Reconstruction when available. Unsupported machines keep the selected backend but fall back to the internal denoiser; read denoise.dlss.fallbackReason from lookdevpt.get_state for details. More setup notes are in Optional DLSS Ray Reconstruction.

{
  "jsonrpc": "2.0",
  "id": 16,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_denoise",
    "arguments": {
      "backend": "dlss_rr",
      "dlssMode": "quality",
      "resetDlss": true
    }
  }
}

Set material factors:

{
  "jsonrpc": "2.0",
  "id": 17,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_material",
    "arguments": {
      "index": 0,
      "baseColor": [0.9, 0.76, 0.54, 1.0],
      "roughness": 0.42,
      "metallic": 0.0
    }
  }
}

Override or clear a material texture slot:

{
  "jsonrpc": "2.0",
  "id": 16,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.set_material_texture",
    "arguments": {
      "index": 0,
      "slot": "baseColor",
      "path": "D:\\LookDevTextures\\paint_basecolor.png"
    }
  }
}

Use "clear": true to remove the slot override, or "resetToSource": true to restore the imported source texture for that slot.

Save and apply a material variant:

{
  "jsonrpc": "2.0",
  "id": 17,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.save_material_variant",
    "arguments": {
      "index": 0,
      "variant": "warm rough"
    }
  }
}
{
  "jsonrpc": "2.0",
  "id": 18,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.apply_material_variant",
    "arguments": {
      "index": 0,
      "variant": "warm rough"
    }
  }
}

Focus one material and adjust the final view transform:

{
  "jsonrpc": "2.0",
  "id": 19,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.run_actions",
    "arguments": {
      "actions": [
        {
          "method": "set_material_view",
          "params": { "selectedMaterial": 0, "focusMode": "dim" }
        },
        {
          "method": "set_color_management",
          "params": { "toneMapper": "aces", "exposure": 0.0, "gamma": 2.2 }
        }
      ],
      "validateOnly": false,
      "stopOnError": true
    }
  }
}

Capture the viewport:

{
  "jsonrpc": "2.0",
  "id": 20,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.capture_viewport",
    "arguments": {}
  }
}

Run a validated batch:

{
  "jsonrpc": "2.0",
  "id": 21,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.run_actions",
    "arguments": {
      "actions": [
        {
          "method": "set_path_tracing",
          "params": { "mode": "restir_gi_di", "samplesPerFrame": 2 }
        },
        {
          "method": "set_denoise",
          "params": { "preset": "interactive_stable", "resetHistory": true }
        }
      ],
      "validateOnly": false,
      "stopOnError": true
    }
  }
}

Capture a debug review pack:

{
  "jsonrpc": "2.0",
  "id": 22,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.capture_debug_pack",
    "arguments": {
      "views": [
        "Final",
        "Base Color",
        "World Normal",
        "Roughness",
        "Metallic",
        "Direct Signal",
        "Indirect Signal",
        "History Confidence"
      ]
    }
  }
}

Save a project without a dialog:

{
  "jsonrpc": "2.0",
  "id": 23,
  "method": "tools/call",
  "params": {
    "name": "lookdevpt.save_project_as",
    "arguments": {
      "path": "C:\\Projects\\D3D12LookDevPT\\projects\\bistro.lookdevpt.json"
    }
  }
}

Troubleshooting

  • 401 Unauthorized: token mismatch. Copy the token from the ImGui MCP Server panel and restart the client connection.
  • 403 Forbidden: client sent a disallowed Origin header.
  • 400 / -32020: a modern routing header is missing, malformed, or differs from the JSON body. Let the MCP client generate the protocol, method, and name headers.
  • 400 / -32022: use 2026-07-28, 2025-11-25, or 2025-06-18; the error data lists the supported versions.
  • 400 MCP-Session-Id is required: this applies only to legacy traffic; call initialize first, then send the returned MCP-Session-Id.
  • 404 Unknown MCP session: the legacy session was deleted, expired after 30 minutes idle, or the app/server restarted. Initialize again.
  • 405 Method Not Allowed on GET: expected. Modern subscriptions use an SSE response to POST subscriptions/listen.
  • 405 Method Not Allowed on modern DELETE: expected because modern requests are stateless. DELETE is reserved for legacy session termination.
  • Mutation request hangs in confirm_mutations: approve or reject it in the ImGui MCP Server panel before the request timeout.
  • MCP mutation queue is full: wait for pending requests to finish, approve/reject pending mutations, or restart the server.
  • A state/stat read appears stale after a successful mutation: wait 33 ms for state or 100 ms for stats/diagnostics, then read again.
  • capture_debug_pack is rejected in read_only or waits in confirm_mutations: the tool temporarily changes debug-view/history state and therefore requires mutation access/approval.
  • lookdevpt://captures/latest.png fails: call lookdevpt.capture_viewport once before reading the resource.

References