<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>svnscha - remote-debugging</title>
    <subtitle>automating annoying tasks, sharing tips, and embracing less frustration</subtitle>
    <link rel="self" type="application/atom+xml" href="https://svnscha.de/tags/remote-debugging/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://svnscha.de"/>
    <generator uri="https://astro.build/">Astro</generator>
    <updated>2026-10-10T00:00:00+00:00</updated>
    <id>https://svnscha.de/tags/remote-debugging/atom.xml</id>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.5.1</title>
        <published>2026-10-10T00:00:00+00:00</published>
        <updated>2026-10-10T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/mcp-windbg-1-5-1-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-5-1-release/</id>
        <summary type="html">A standalone, code signed mcp-windbg.exe for machines without Python, and a fix for remote sessions whose target is already running when you connect.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-5-1-release/">&lt;p&gt;&lt;strong&gt;mcp-windbg&lt;/strong&gt; 1.5.1 is out, one day after 1.5.0. Two things are new: a single &lt;code&gt;mcp-windbg.exe&lt;/code&gt; you can download and point a client at, with no Python on the machine, and a fix for the one issue I left open in the &lt;a href=&quot;/posts/mcp-windbg-1-5-0-release/&quot;&gt;1.5.0 post&lt;/a&gt;: connecting to a debug server whose target is already running.&lt;/p&gt;
&lt;h2 id=&quot;a-standalone-mcp-windbgexe&quot;&gt;A Standalone mcp-windbg.exe&lt;/h2&gt;
&lt;p&gt;Until now, running the server meant Python 3.10 and &lt;code&gt;pip&lt;/code&gt;, or &lt;code&gt;uv&lt;/code&gt; for the Claude Code plugin. That is fine on a developer machine. It is less fine on the box where the crash actually happens: a build agent, a test VM, or a colleague's laptop with WinDbg installed and nothing else.&lt;/p&gt;
&lt;p&gt;Every &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/latest&quot;&gt;release&lt;/a&gt; now ships &lt;code&gt;mcp-windbg.exe&lt;/code&gt;. It is one file, about 25 MB, with the Python interpreter and every dependency frozen in by PyInstaller. &lt;code&gt;cdb.exe&lt;/code&gt; is still required. The debugger is the one thing the binary cannot bundle.&lt;/p&gt;
&lt;p&gt;Download it, put it somewhere stable, and point the client at it. No &lt;code&gt;args&lt;/code&gt; needed:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;    &quot;servers&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;        &quot;mcp_windbg&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;stdio&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;command&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;C:&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;mcp-windbg.exe&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;env&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;                &quot;_NT_SYMBOL_PATH&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;SRV*C:&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Symbols*https://msdl.microsoft.com/download/symbols&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command-line options are the same as for the Python package, so &lt;code&gt;&quot;args&quot;: [&quot;--cdb-path&quot;, &quot;C:\\dbg\\cdb.exe&quot;]&lt;/code&gt; still works.&lt;/p&gt;
&lt;p&gt;Two build decisions worth knowing about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is a one-file build. It unpacks itself into &lt;code&gt;%TEMP%&lt;/code&gt; on every launch, which costs about a second. An MCP server starts once per session, so you pay that second once.&lt;/li&gt;
&lt;li&gt;It is not UPX-compressed. Packed binaries get flagged by antivirus, and a debugging tool starts out suspicious enough.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;signed-with-a-checksum&quot;&gt;Signed, With a Checksum&lt;/h3&gt;
&lt;p&gt;The executable is code signed, and each release publishes a &lt;code&gt;SHA256SUMS&lt;/code&gt; file next to it. Both are easy to check:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;powershell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Get-FileHash&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; .\&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;mcp-windbg.exe&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; -Algorithm SHA256).Hash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Get-AuthenticodeSignature&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; .\&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;mcp-windbg.exe&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Format-List&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; Status, SignerCertificate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Status&lt;/code&gt; should read &lt;code&gt;Valid&lt;/code&gt;, and the signer is Liasoft GmbH. That is my company, and the certificate belongs to it. mcp-windbg stays a personal project, so Windows shows the company as the publisher and the file properties name me as the author. Having a certificate at hand is the only reason the binary is signed at all. Otherwise this would have been the step I skipped.&lt;/p&gt;
&lt;h3 id=&quot;importing-cleanly-is-not-the-test&quot;&gt;Importing Cleanly Is Not the Test&lt;/h3&gt;
&lt;p&gt;A frozen build only contains the modules PyInstaller could see. A dependency that imports lazily, or reads a data file at runtime, fails at the tool call rather than at startup. So a binary that launches and answers &lt;code&gt;initialize&lt;/code&gt; proves very little.&lt;/p&gt;
&lt;p&gt;The project already has an end-to-end harness that drives a real server through a real MCP client with scripted tool calls. It can now run against the binary instead of &lt;code&gt;python -m mcp_windbg&lt;/code&gt;, with the same assertions. That happens on every pull request, and locally with &lt;code&gt;scripts/Build-Exe.ps1 -Verify&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The release workflow runs the suite a second time against the signed binary. Signing rewrites the executable, and nothing had ever tested the result. The &lt;code&gt;SHA256SUMS&lt;/code&gt; file is taken after signing for the same reason.&lt;/p&gt;
&lt;p&gt;One limitation of the frozen build: &lt;code&gt;--filter-script&lt;/code&gt; still works, but it only sees the parts of the standard library the bundle contains. &lt;code&gt;sqlite3&lt;/code&gt;, &lt;code&gt;xml.etree&lt;/code&gt; and &lt;code&gt;tkinter&lt;/code&gt; are not in it. A filter script that needs more than that wants the pip install.&lt;/p&gt;
&lt;h2 id=&quot;opening-a-remote-session-whose-target-is-running&quot;&gt;Opening a Remote Session Whose Target Is Running&lt;/h2&gt;
&lt;p&gt;This is the issue I listed under &quot;Still Open&quot; last week: item 2 of &lt;a href=&quot;https://github.com/xiaozhu1337&quot;&gt;@xiaozhu1337&lt;/a&gt;'s report in &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/issues/130&quot;&gt;#130&lt;/a&gt;, with a fix proposed in &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/pull/127&quot;&gt;#127&lt;/a&gt;. I did not ship a fix in 1.5.0 because two attempts had each broken a different case, and there was no automated test for a running remote target at all. This time the test came first.&lt;/p&gt;
&lt;p&gt;The bug: &lt;code&gt;open_cdb_remote&lt;/code&gt; against a debug server whose target is running never got a prompt. A running target reads no commands, so the probe the open relied on was never answered. The open waited out its whole timeout, 60 seconds by default, and then failed with &lt;code&gt;Debugger initialization timed out&lt;/code&gt;. The session was fine.&lt;/p&gt;
&lt;p&gt;To reproduce it, I started &lt;code&gt;cdb -server tcp:port=N waitfor.exe X&lt;/code&gt;, typed &lt;code&gt;g&lt;/code&gt; on the server, and attached a &lt;code&gt;-remote&lt;/code&gt; client. The client prints its connect banner, replays the server's transcript, and then nothing. I had assumed the probe would complete without a context, as the proposed fix described. It does not. It is simply never answered.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;-remote&lt;/code&gt; client now starts in two phases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wait for the &lt;code&gt;Connected to server with&lt;/code&gt; banner, up to the open timeout. That is where connection latency belongs. A failed connect still reports the debugger's own error, and a connect that never completes now says &lt;code&gt;Timed out connecting to the debug server&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Give the target two seconds to answer the prompt probe. A stopped target answers in about 0.1 seconds on localhost. Silence means it is running, and the session opens in that state.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The initial triage then breaks in, the same way any command on a running target does after &lt;code&gt;g&lt;/code&gt;. The result says so under &lt;code&gt;Target State&lt;/code&gt;, and the target stays stopped until you resume it or close the session.&lt;/p&gt;
&lt;p&gt;A wrong guess is cheap. A CTRL+BREAK sent to a target that is already stopped produces no output and leaves the session usable, so a slow connect misread as running costs nothing.&lt;/p&gt;
&lt;p&gt;The new live scenario resumes the server's target before the open, checks the &lt;code&gt;Target State&lt;/code&gt; line and the break banner, and makes sure the next &lt;code&gt;r&lt;/code&gt; does not break in again. The hermetic tests cover the four startup outcomes: stopped, running, exited mid-connect, and never connected. After &lt;a href=&quot;/posts/mcp-windbg-1-5-0-release/#what-i-measured-before-merging&quot;&gt;last week's lesson&lt;/a&gt;, I treat those as the floor, and the live scenario as the proof.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -U&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you use the Claude Code plugin:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/plugin marketplace update mcp-windbg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/plugin update mcp-windbg-uvx@mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or skip all of that and download &lt;code&gt;mcp-windbg.exe&lt;/code&gt; from the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.5.1&quot;&gt;v1.5.1 release&lt;/a&gt;. Thanks again to &lt;a href=&quot;https://github.com/xiaozhu1337&quot;&gt;@xiaozhu1337&lt;/a&gt; for the original report. If the executable behaves differently from the Python package on your machine, I want to hear about it, so please &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/issues&quot;&gt;open an issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To put it to work, follow &lt;a href=&quot;/posts/claude-agent-sdk-crash-triage/&quot;&gt;Getting started with the Claude Agent SDK and mcp-windbg&lt;/a&gt;. The guide builds a TypeScript worker that investigates incoming application dumps, compares previous reports, and saves Markdown findings with a structured result.&lt;/p&gt;
</content>
    </entry>
</feed>
