# Reported issues for windbg-mcp

Pod holds 19 of 39 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [windbg-mcp](/mcp/windbg-mcp).

## Most discussed

### Install with scoop

I'm already enjoying using this mcp server, thanks! 🎉 

The installer is a little bit messy, and I want to be able to easily check for and install updates, so I created a scoop [bucket](https://github.com/gitfool/scoop-dungeon) for my "miscellaneous tools" and added [windbg-mcp](https://github.com/gitfool/scoop-dungeon/blob/main/bucket/windbg-mcp.json) to it first (which takes care of all the post install steps). 😉 

Note: anybody can install it using scoop as it's also [visible](https://scoop.s

[Read the thread](https://github.com/glslang/windbg-mcp/issues/109) · 2026-08-12 · closed · external user · 3 comments

### Support loading SOS for 32-bit .NET Framework dumps (x86 engine worker or guidance)

## Problem

When a 32-bit .NET Framework process dump is opened in windbg-mcp, SOS cannot be loaded. The engine worker is x64, and the two available SOS DLLs both fail:

- **64-bit SOS** (`Framework64\v4.0.30319\sos.dll`) loads into the x64 worker process but refuses to analyze the x86 target: `SOS does not support the current target architecture (14c)`
- **32-bit SOS** (`Framework\v4.0.30319\sos.dll`) can't load at all: `Win32 error 0n193 "%1 is not a valid Win32 application"`

`.effmach x86` i

[Read the thread](https://github.com/glslang/windbg-mcp/issues/234) · 2026-08-26 · closed · external user · 2 comments

### Single-tenancy and the lease are keyed on Mcp-Session-Id, which 2026-07-28 removed

## What happens

Against `--listen`, at protocol revision **`2026-07-28`** — the newest this server advertises, and
the one Claude Code negotiates — **two clients are both served**, and neither ever holds a lease.

```
Two independent clients at 2026-07-28 (sessions removed from the spec):
  client A tools/call -> HTTP 200  No debug session is open. Start one with open_dump / ...
  client B tools/call -> HTTP 200  No debug session is open. Start one with open_dump / ...

(a 409 for B is what the

[Read the thread](https://github.com/glslang/windbg-mcp/issues/162) · 2026-08-18 · closed · 2 comments

### An ARM64 engine cannot read virtual memory from an x64 kernel dump

Adding an ARM64 entry to the debugger tier (#141) turned up a real limitation on the first run. **41 passed, 4 failed**, and the four share one cause.

The dump opens and triages correctly. Bug check code, name and all four parameters are right, and the stack is attributed to `nt` with RVAs:

```json
"bug_check":{"code":"0x13a","name":"KERNEL_MODE_HEAP_CORRUPTION","parameters":["0x8","0xffff998228000140","0xffff99823034eb10","0x0"]},
"frames":[{"address":"0xfffff805cb8f93c0","index":0,"module":"

[Read the thread](https://github.com/glslang/windbg-mcp/issues/142) · 2026-08-16 · closed · 2 comments

### No CI coverage on ARM64, where the debugger tier would earn it

The repository now documents ARM64 hosts — `setup.md` has an ARM64 section, and the engine-bundling instructions carry an architecture warning — but nothing in CI runs on one. Both jobs that touch a debugger are `runs-on: windows-latest`, which is x64.

That gap matters most for the **debugger tier**, because that job's whole argument is that it is the only automated check of properties the architecture exists for, against a real `dbgeng.dll` and a checked-in dump. On ARM64 the engine is a diffe

[Read the thread](https://github.com/glslang/windbg-mcp/issues/134) · 2026-08-16 · closed · 2 comments

### A target exiting during the resume pump leaves the session half-dead and can take the worker down

## Summary

On launch/attach_process sessions, when the target process exits while the engine is running or being pumped to a stop after a resume, the session enters a broken state:

- the command whose release raced the exit returns only a silent echo; the pump's captured output (breakpoint banner, embedded script output) is discarded,
- thread-dependent commands (`k`, `registers`) then fail with a bare `E_UNEXPECTED` (0x80040205) while `.echo` and `.lastevent` still answer, which is indistingu

[Read the thread](https://github.com/glslang/windbg-mcp/issues/242) · 2026-08-26 · closed · external user · 1 comment

### Hosting the x86 engine in cdb -server keeps generating the same class of finding

Not a regression, and not something #239 introduced — the design it raises was chosen deliberately in #234, with the trade recorded at the time. What is new is evidence about that trade, and it accumulated fast enough to be worth writing down before the next change lands on the same seam.

## The observation

#239 puts the engine for a 32-bit dump in a `cdb.exe -server` child and drives it over DbgEng's remote transport. Across three review rounds, **seven distinct findings all landed on that on

[Read the thread](https://github.com/glslang/windbg-mcp/issues/240) · 2026-08-26 · closed · 1 comment

### execute silently swallows execution-control commands (g/p/t) — a plain Execute sets run state without pumping, and every later control call fails with 0x80040205

## Summary

The `execute` tool routes through `EngineOp::BoundedCommand` → `raw_command` → a plain `IDebugControl::Execute`. This repo's own docs say what that means (docs/tool-surface.md, "Control flow and the TTD wrappers"):

> a plain `Execute` only sets the run state — it doesn't move the target

Yet `execute` performs **no content check whatsoever**: it happily accepts `g`, `p`, `t`, compound commands like `bp X; g`, and breakpoints with embedded command strings. When any of these is issued

[Read the thread](https://github.com/glslang/windbg-mcp/issues/226) · 2026-08-25 · closed · external user · 1 comment

## Most recent

### record_trace reports a successful recording as a startup failure when the target outruns the 2.5s watch

## Summary

`record_trace` watches the recorder for 2.5s and treats **any** exit inside that window as a startup
failure. A target that runs to completion faster than that exits inside the window, so a perfectly
good recording is reported as an error:

```
record_trace { "target": "hostname.exe", "out_dir": "...\\ttd2" }
→ TTD recording failed to start (exit code: 0): Launching 'hostname.exe'.
  Full log: ...\ttd2\ttd_record.log
```

The recording had in fact succeeded completely. From the same 

[Read the thread](https://github.com/glslang/windbg-mcp/issues/233) · 2026-08-25 · closed · 0 comments

### record_trace cannot pass arguments to the target, though its schema says it can - the whole command line goes as one argv entry

## Summary

`record_trace`'s `target` is documented as *"Program (with optional arguments) to launch and
record."* (`src/server.rs`, `RecordArgs`), but arguments do not work: the whole string is handed to
`TTD.exe` as a **single** argv entry, so TTD treats it as one filename and the recording never
starts.

```
record_trace { "target": "cmd.exe /c dir C:\\Windows\\System32\\ntdll.dll", "out_dir": "..." }
→ TTD recording failed to start (exit code: 0x80004005):
  Launching '"cmd.exe /c dir C:\Win

[Read the thread](https://github.com/glslang/windbg-mcp/issues/232) · 2026-08-25 · closed · 0 comments

### ttd_calls and ttd_memory render every result as a blank row - dx without -r2 drops the fields their descriptions promise

## Summary

`ttd_calls` and `ttd_memory` run `dx` **without a recursion depth**, so the data model renders each
result as an index and nothing else. Every row comes back empty:

```
dx @$cursession.TTD.Calls("kernelbase!CreateFileW")
@$cursession.TTD.Calls("kernelbase!CreateFileW")
    [0x0]
    [0x1]
    [0x2]
```

The count is right and the payload is absent. Both tools' own descriptions promise the fields that
are missing — `ttd_calls` says *"Each result carries the time, thread, parameters, 

[Read the thread](https://github.com/glslang/windbg-mcp/issues/231) · 2026-08-25 · closed · 0 comments

### Both eval drivers handshake outside their cleanup, so a failure between initialize and initialized leaks an MCP session

## Summary

`handshake()` is two requests — `initialize`, which mints the `Mcp-Session-Id` the server then
records, and the `notifications/initialized` that follows it:

```python
def handshake():
    out = mcp("initialize", {...})
    mcp("notifications/initialized", notify=True)
    return out["result"]["protocolVersion"]
```

Both drivers call it **before** the `try` whose `finally` deletes that session:

- `tools/local_model_drive.py:695` — handshake; the `try`/`finally` that calls
  `close_

[Read the thread](https://github.com/glslang/windbg-mcp/issues/228) · 2026-08-25 · closed · 0 comments

### The eval matrix's row label drops the backend, so two backends sharing a model name render identically

## Summary

`matrix()` keys a cell by **backend** — `cell_id = (backend, model, num_ctx, surface.client)`
(`tools/local_model_eval.py:717`) — and `print_matrix` then throws that half away when it renders
the row:

```python
for cell, marks in sorted(rows.items(), key=lambda kv: (kv[0][0], kv[0][1],
                                                        -(kv[0][2] or 0), kv[0][3] or "")):
    backend, model, ctx, surface = cell
    label = f"{model[:24]} {str(ctx or 'dflt'):>6} {surface}"
```

`

[Read the thread](https://github.com/glslang/windbg-mcp/issues/227) · 2026-08-25 · closed · 0 comments

### outputSchema has no root `type: "object"` — strict TS-SDK 1.x clients reject the whole tools/list and drop every tool

## Summary

Every typed tool declares its `outputSchema` through `constraints_of` (`src/schema.rs`), which wraps
`rmcp::handler::server::tool::schema_for_output` and strips `description`s — but never adds a root
`type`. Since the structured result types are serde-internally-tagged enums (`Outcome<T>` on
`"status"`, `src/structured.rs`), schemars renders each schema as `{ $schema, oneOf, $defs }` with no
root-level `type`.

Clients built on the official TypeScript SDK 1.x (every released version 

[Read the thread](https://github.com/glslang/windbg-mcp/issues/223) · 2026-08-25 · closed · external user · 1 comment

### A client's identity is its name, so a re-added name is indistinguishable from its predecessor

Split out of [#189](https://github.com/glslang/windbg-mcp/pull/189), which produced five consecutive rounds of review findings on one mechanism. Each was locally real and each was fixed, but they were all the same root cause seen from a different consumer, and the last of them can only be closed here.

## The property that is missing

`crate::client::Client` is a name — `Arc<str>`, compared and hashed as a string. Everything keyed on identity keys on that name:

- session ownership (`Session::ow

[Read the thread](https://github.com/glslang/windbg-mcp/issues/190) · 2026-08-22 · closed · 1 comment

### The listener answers a 2026-07-28 handshake and then 400s the next request

`--listen` negotiates `2026-07-28` and then does not serve it.

## What was measured

A listener started from `target\debug` on the ARM64 bench, driven with a hand-written HTTP client
(`Invoke-WebRequest`, so nothing normalises a status for us):

| request | result |
| --- | --- |
| `initialize`, `protocolVersion: 2026-07-28` | **200**, and **no `Mcp-Session-Id` is minted** — correct, [SEP-2567] removed it |
| `initialize`, `protocolVersion: 2025-06-18` | 200, mints `Mcp-Session-Id` |
| `tools/l

[Read the thread](https://github.com/glslang/windbg-mcp/issues/168) · 2026-08-19 · closed · 0 comments

### Flaky: the rollback's final progress notification races the end_session response

## What fails

`ending_a_session_stops_a_running_batch_and_rolls_it_back`, intermittently, in the debugger tier:

```
thread 'ending_a_session_stops_a_running_batch_and_rolls_it_back' panicked at tests/mcp_smoke.rs:4955:
the rollback finished and the client was never told: ["a transaction is in flight; rolling it back (up to 2m03s)"]
```

The client sees the *promise* milestone and never the *retraction*. Seen four times across a working
session; three consecutive full-tier runs in between were 

[Read the thread](https://github.com/glslang/windbg-mcp/issues/163) · 2026-08-18 · closed · 1 comment

### Capture an ARM64 driver crash, so frame attribution is asserted on an ARM64 stack

#143 gave the debugger tier an ARM64 target and closed three of the four assertions that read one. The fourth — `a_driver_crash_names_the_driver_frame_that_analyze_cannot` — still runs against the x64 `MessageManager` dump on every architecture. That works (an engine with symbols reads it either way round, see #142), but it means **frame attribution to a third-party driver has never been exercised on an ARM64 stack**: the arithmetic that turns a captured frame into `module+RVA` off the load base

[Read the thread](https://github.com/glslang/windbg-mcp/issues/154) · 2026-08-18 · closed · 1 comment

### The result budget measures one channel, so a typed tool's text half can grow unwatched

Raised by Codex on #149, and it holds. Filing rather than fixing there: the honest fix touches what the harness claims about *clients*, and testing against more than one client is out of scope for now.

## The gap

`tool_results_stay_within_their_budget` (`tests/mcp_smoke.rs`) reduces each result to a single number before asserting:

```rust
let model = structured.unwrap_or(text);
…
assert!(model <= *ceiling, …);
```

That is right for the client it was measured against — Claude Code forwards `s

[Read the thread](https://github.com/glslang/windbg-mcp/issues/150) · 2026-08-17 · closed · 1 comment

The remaining reports are on [the project's issue tracker](https://github.com/glslang/windbg-mcp/issues).
