<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>svnscha - 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/debugging/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://svnscha.de"/>
    <generator uri="https://astro.build/">Astro</generator>
    <updated>2026-09-10T00:00:00+00:00</updated>
    <id>https://svnscha.de/tags/debugging/atom.xml</id>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.3.0</title>
        <published>2026-09-10T00:00:00+00:00</published>
        <updated>2026-09-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-3-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-3-0-release/</id>
        <summary type="html">The MCP server, Claude Code skills, and crash-analysis agent are now separate plugins for use with your preferred installation.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-3-0-release/">&lt;p&gt;Version 1.3.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt; separates the Claude Code integration into three plugins. If you've already installed mcp-windbg yourself, you can now add the debugging skills and crash-analysis agent to that connection.&lt;/p&gt;
&lt;h2 id=&quot;three-separate-plugins&quot;&gt;Three Separate Plugins&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;/posts/mcp-windbg-1-2-0-release/&quot;&gt;1.2.0 release&lt;/a&gt; bundled the server, skills, and agent together. I split them so you can choose the parts you need:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plugin&lt;/th&gt;
&lt;th&gt;What it provides&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mcp-windbg-uvx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The MCP server, launched with uvx, and default symbol settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mcp-windbg-skills&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Four debugging skills&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mcp-windbg-agents&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;crash-analyst&lt;/code&gt; agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The uvx plugin now ships only the server configuration. Skills and agents are independent: install either, both, or neither.&lt;/p&gt;
&lt;h2 id=&quot;skills-and-agents-for-your-existing-server&quot;&gt;Skills and Agents for Your Existing Server&lt;/h2&gt;
&lt;p&gt;If mcp-windbg is already registered in Claude Code, add the marketplace and install the workflows you want:&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 add svnscha/mcp-windbg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/plugin install mcp-windbg-skills@mcp-windbg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/plugin install mcp-windbg-agents@mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The skills cover the same four tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;analyze-dump&lt;/code&gt;&lt;/strong&gt; for crash dump analysis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;debug-remote&lt;/code&gt;&lt;/strong&gt; for live user-mode debugging.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;kernel-debug&lt;/code&gt;&lt;/strong&gt; for live kernel debugging.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;windbg-doctor&lt;/code&gt;&lt;/strong&gt; for checking the debugging setup.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They use your configured MCP connection, whether it runs a native executable, a Python installation, or an HTTP service. Setup diagnosis checks that server's actual launcher and host. It no longer assumes every installation needs uv.&lt;/p&gt;
&lt;p&gt;For example:&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;/mcp-windbg-skills:analyze-dump C:\dumps\app.dmp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The agent is available as &lt;code&gt;mcp-windbg-agents:crash-analyst&lt;/code&gt;. It investigates a dump and reports its likely cause, debugger evidence, and next steps. It uses the MCP tools directly and does not need the skills plugin.&lt;/p&gt;
&lt;p&gt;If you want the plugin to start the server through uvx, install it as well:&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 install mcp-windbg-uvx@mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Windows and CDB/KD are still required on the debugging host. The server's built-in MCP prompts are available independently of these plugins.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Enterprise environments:&lt;/strong&gt; Managed &lt;code&gt;allowedMcpServers&lt;/code&gt; settings can cause Claude Code to silently skip plugin-bundled MCP servers (&lt;a href=&quot;https://github.com/anthropics/claude-code/issues/32882&quot;&gt;issue #32882&lt;/a&gt;). I recommend &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/reference/clients/#registering-the-server-directly&quot;&gt;manual installation and registration&lt;/a&gt; plus the skills plugin, with the agents plugin if needed. The server must still be permitted by your organization's MCP policy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;upgrading-from-the-bundled-plugin&quot;&gt;Upgrading from the Bundled Plugin&lt;/h2&gt;
&lt;p&gt;Update the marketplace and server 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;Then install the skills and agents plugins using the commands above if you want to keep those workflows.&lt;/p&gt;
&lt;p&gt;Skill commands now start with &lt;code&gt;/mcp-windbg-skills:&lt;/code&gt; instead of &lt;code&gt;/mcp-windbg:&lt;/code&gt;. For example, &lt;code&gt;/mcp-windbg:analyze-dump&lt;/code&gt; becomes &lt;code&gt;/mcp-windbg-skills:analyze-dump&lt;/code&gt;. References to the agent should use &lt;code&gt;mcp-windbg-agents:crash-analyst&lt;/code&gt;. Restart Claude Code if the new components do not appear.&lt;/p&gt;
&lt;p&gt;See the full &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.3.0&quot;&gt;v1.3.0 release notes&lt;/a&gt; and the &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/reference/plugin/&quot;&gt;plugin guide&lt;/a&gt; for installation, switching servers, and updating each plugin.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.2.2</title>
        <published>2026-09-05T00:00:00+00:00</published>
        <updated>2026-09-05T00: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-2-2-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-2-2-release/</id>
        <summary type="html">A fix for missing Unicode output on Chinese, Japanese, and Korean Windows systems.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-2-2-release/">&lt;p&gt;Version 1.2.2 of &lt;strong&gt;mcp-windbg&lt;/strong&gt; is out. This release fixes missing Unicode output on Windows systems that use a multibyte code page, including Chinese, Japanese, and Korean systems.&lt;/p&gt;
&lt;p&gt;The bug was reported by a community member in &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/issues/102&quot;&gt;issue #102&lt;/a&gt;. Thanks for taking the time to provide a clear report and help track it down.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;du&lt;/code&gt; command, which displays a Unicode string, sometimes returned an empty result through mcp-windbg. Running the same command directly in CDB worked as expected. Other commands such as &lt;code&gt;db&lt;/code&gt; and &lt;code&gt;dw&lt;/code&gt; also worked against the same address.&lt;/p&gt;
&lt;p&gt;The important detail was the reporter's Chinese Windows system locale.&lt;/p&gt;
&lt;h2 id=&quot;what-caused-it&quot;&gt;What Caused It&lt;/h2&gt;
&lt;p&gt;mcp-windbg communicates with &lt;code&gt;cdb.exe&lt;/code&gt; through a pipe. It sends a command and reads the debugger's response from that pipe.&lt;/p&gt;
&lt;p&gt;On multibyte system code pages, such as Chinese 936, Japanese 932, Korean 949, or the &quot;Use Unicode UTF-8&quot; setting, CDB can truncate text while writing it to a pipe. The end of a line may be missing, including the closing quote and newline.&lt;/p&gt;
&lt;p&gt;For &lt;code&gt;du&lt;/code&gt;, this could remove the entire string. If the output was cut in the middle of a character, later commands could also time out because the session could no longer parse the incomplete output correctly.&lt;/p&gt;
&lt;p&gt;This only affects redirected output, which is why the command still looks correct when run in a normal debugger window. There is no CDB option that fixes the pipe output; interactive mode, batch mode, and ANSI log files all show the same problem.&lt;/p&gt;
&lt;h2 id=&quot;the-fix&quot;&gt;The Fix&lt;/h2&gt;
&lt;p&gt;CDB can write complete UTF-16 log files using &lt;code&gt;.logopen /u&lt;/code&gt;, so mcp-windbg now uses one on affected systems. The pipe is still used to manage command timing, but the command output itself is read from the UTF-16 log.&lt;/p&gt;
&lt;p&gt;This is not a special case for &lt;code&gt;du&lt;/code&gt;. It also fixes Unicode text in module paths, &lt;code&gt;!analyze&lt;/code&gt; output, string dumps, and other debugger commands. Systems with a single-byte code page continue to use the existing pipe-based output.&lt;/p&gt;
&lt;p&gt;I tested the fix with real crash dumps, a live kernel target, and remote sessions using the 1252, 936, and 65001 code pages.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Upgrade with:&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;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, update the plugin to pick up the new version.&lt;/p&gt;
&lt;p&gt;The project is available on &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;GitHub&lt;/a&gt;. If you notice any other commands behaving differently on a non-English Windows system, please &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/issues&quot;&gt;open an issue&lt;/a&gt;.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.2.0</title>
        <published>2026-08-27T00:00:00+00:00</published>
        <updated>2026-08-27T00: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-2-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-2-0-release/</id>
        <summary type="html">mcp-windbg now ships as a Claude Code plugin with four debugging skills and a crash-analysis agent.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-2-0-release/">&lt;p&gt;Version 1.2.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt; adds a Claude Code plugin. It packages the MCP server together with the instructions and workflows needed for common debugging tasks, so Claude Code can install and use it without a separate Python setup or a hand-written MCP configuration.&lt;/p&gt;
&lt;h2 id=&quot;installing-the-plugin&quot;&gt;Installing the Plugin&lt;/h2&gt;
&lt;p&gt;Add the mcp-windbg marketplace and install the plugin from Claude Code:&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 add svnscha/mcp-windbg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;/plugin install mcp-windbg-uvx@mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The plugin starts mcp-windbg with &lt;code&gt;uvx&lt;/code&gt;, which downloads the pinned version from PyPI the first time it runs. You still need Windows, CDB, and &lt;code&gt;uv&lt;/code&gt;, but you do not need to install the Python package yourself.&lt;/p&gt;
&lt;p&gt;The existing &lt;code&gt;pip install mcp-windbg&lt;/code&gt; setup remains available for other MCP clients and for anyone who prefers a manual configuration.&lt;/p&gt;
&lt;h2 id=&quot;skills-for-common-debugging-tasks&quot;&gt;Skills for Common Debugging Tasks&lt;/h2&gt;
&lt;p&gt;The plugin includes four skills:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;analyze-dump&lt;/code&gt;&lt;/strong&gt; guides the analysis of a Windows crash dump.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;debug-remote&lt;/code&gt;&lt;/strong&gt; works with a live user-mode target through CDB.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;kernel-debug&lt;/code&gt;&lt;/strong&gt; handles live kernel debugging with KD.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;windbg-doctor&lt;/code&gt;&lt;/strong&gt; checks the local setup when CDB, KD, symbols, or the MCP server are not working as expected.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These skills only load when they are needed, which keeps the plugin's normal context use small. The underlying MCP tools are still available directly when you want to run a specific command or control a session yourself.&lt;/p&gt;
&lt;h2 id=&quot;the-crash-analyst-agent&quot;&gt;The Crash Analyst Agent&lt;/h2&gt;
&lt;p&gt;The plugin also includes a read-only &lt;strong&gt;&lt;code&gt;crash-analyst&lt;/code&gt;&lt;/strong&gt; agent. It can investigate a dump independently and return:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;its likely cause&lt;/li&gt;
&lt;li&gt;the debugger evidence supporting that conclusion&lt;/li&gt;
&lt;li&gt;alternative causes it checked&lt;/li&gt;
&lt;li&gt;practical next steps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The agent is kept away from mutating tools. It can inspect a debugging session, but it cannot resume a target or perform another action that would change its state.&lt;/p&gt;
&lt;h2 id=&quot;symbols-by-default&quot;&gt;Symbols by Default&lt;/h2&gt;
&lt;p&gt;Readable stack traces depend on symbols, and missing symbol configuration is a common source of poor results. The plugin now provides the Microsoft symbol server as the default value for &lt;code&gt;_NT_SYMBOL_PATH&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you already have &lt;code&gt;_NT_SYMBOL_PATH&lt;/code&gt; configured, the plugin leaves it unchanged. Existing private symbol servers and custom cache paths therefore continue to work.&lt;/p&gt;
&lt;h2 id=&quot;a-small-121-follow-up&quot;&gt;A Small 1.2.1 Follow-up&lt;/h2&gt;
&lt;p&gt;Version 1.2.1 followed later the same day. It reorganized the README installation guide by client and fixed a corrupted &lt;code&gt;C:\dumps\app.dmp&lt;/code&gt; example that contained a hidden control character. There were no runtime changes, so it does not need a separate post.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Use the two plugin commands above for Claude Code, or upgrade the Python package for another MCP client:&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;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;See the full release notes for &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.2.0&quot;&gt;v1.2.0&lt;/a&gt; and &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.2.1&quot;&gt;v1.2.1&lt;/a&gt;. The source and plugin marketplace are available in the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;mcp-windbg repository&lt;/a&gt;.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.1.0</title>
        <published>2026-08-26T00:00:00+00:00</published>
        <updated>2026-08-26T00: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-1-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-1-0-release/</id>
        <summary type="html">Support for the 2.x MCP SDK, a new wait_for_break tool, and fixes for 'g' freezing the machine it was supposed to release.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-1-0-release/">&lt;p&gt;Version 1.1.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt; is out. It's the first release since &lt;a href=&quot;/posts/mcp-windbg-1-0-0-release/&quot;&gt;1.0.0&lt;/a&gt;, which was broken on fresh installs for some time.&lt;/p&gt;
&lt;h2 id=&quot;what-happened-101&quot;&gt;What Happened: 1.0.1&lt;/h2&gt;
&lt;p&gt;The dependency was &lt;code&gt;mcp&amp;gt;=1.28.1&lt;/code&gt; with no upper bound. When the MCP Python SDK shipped 2.0.0 - renaming &lt;code&gt;McpError&lt;/code&gt; to &lt;code&gt;MCPError&lt;/code&gt; and dropping the &lt;code&gt;@server.list_tools()&lt;/code&gt; decorator - every fresh install broke at import:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Existing installs worked fine; only new ones broke. That's the worst kind of bug: invisible to anyone who could report it. 1.0.1 capped the requirement at &lt;code&gt;&amp;lt;2.0.0&lt;/code&gt;. Thanks to @aphroteus for the fix and @arjunarjun07 for finding the cause.&lt;/p&gt;
&lt;p&gt;If you're still on 1.0.0, run &lt;code&gt;pip install --upgrade mcp-windbg&lt;/code&gt;. Any &lt;code&gt;pip install &quot;mcp&amp;lt;2&quot;&lt;/code&gt; workaround can go.&lt;/p&gt;
&lt;h2 id=&quot;support-for-the-2x-sdk&quot;&gt;Support for the 2.x SDK&lt;/h2&gt;
&lt;p&gt;A cap is a stopgap, not a fix. 1.1.0 runs on &lt;code&gt;mcp&amp;gt;=2.0.0&lt;/code&gt;: handlers are passed straight to &lt;code&gt;Server(...)&lt;/code&gt; instead of registered via decorators, and they return the SDK's result types (&lt;code&gt;ListToolsResult&lt;/code&gt;, &lt;code&gt;CallToolResult&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Nothing changes for clients - same tools, same schemas, stdio and streamable-http both work as before. Python support is unchanged (the 2.x SDK wants 3.10+, like this project already did).&lt;/p&gt;
&lt;p&gt;Two changes so the next SDK release is boring instead of another five silent weeks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;All runtime dependencies are capped at the next major version.&lt;/strong&gt; Without a ceiling, moving to 2.x would have left the same trap for 3.0.0. Since mcp-windbg is an application, not a library, upper bounds can't conflict with anything downstream - a breaking SDK release just becomes a failing CI run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A weekly canary tests what users actually get.&lt;/strong&gt; CI installed from &lt;code&gt;uv.lock&lt;/code&gt;, so it only tested pinned versions, while real installs resolve whatever the ranges allow. The canary ignores the lock, installs the newest allowed versions, and runs the test suite every Monday. It's scheduled rather than tied to pull requests on purpose: an upstream break should page me, not block someone's unrelated PR.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;wait_for_break&quot;&gt;&lt;code&gt;wait_for_break&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The one new tool. Resume a target with &lt;code&gt;g&lt;/code&gt;, go do something else, then call &lt;code&gt;wait_for_break&lt;/code&gt; to block until it stops again - breakpoint, bugcheck, or CTRL+BREAK. It returns everything the debugger printed along the way.&lt;/p&gt;
&lt;p&gt;If the wait expires, the target keeps running. Waiting never halts your machine behind your back.&lt;/p&gt;
&lt;h2 id=&quot;fixing-g-freezing-the-target&quot;&gt;Fixing &lt;code&gt;g&lt;/code&gt; Freezing the Target&lt;/h2&gt;
&lt;p&gt;This was bad and hid for a while, so let me be honest about it.&lt;/p&gt;
&lt;p&gt;Go-class commands (&lt;code&gt;g&lt;/code&gt;, &lt;code&gt;gh&lt;/code&gt;, &lt;code&gt;gn&lt;/code&gt;, &lt;code&gt;gN&lt;/code&gt;, &lt;code&gt;gc&lt;/code&gt;, &lt;code&gt;gu&lt;/code&gt;) hand control back to the target, after which the debugger stops reading stdin. The server queued an &lt;code&gt;.echo&lt;/code&gt; marker behind the &lt;code&gt;g&lt;/code&gt;, which never got answered - so the command sat until timeout, and the timeout's CTRL+BREAK halted the target again. Ask the machine to run, get it frozen a minute later. The opposite of what you asked for.&lt;/p&gt;
&lt;p&gt;Go-class commands are now sent bare and return immediately. Step commands (&lt;code&gt;p&lt;/code&gt;, &lt;code&gt;t&lt;/code&gt;, &lt;code&gt;pa&lt;/code&gt;, &lt;code&gt;ta&lt;/code&gt;, ...) are unaffected.&lt;/p&gt;
&lt;p&gt;Fixing that exposed several related problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A command right after &lt;code&gt;g&lt;/code&gt; breaks in cleanly.&lt;/strong&gt; No manual &lt;code&gt;send_ctrl_break&lt;/code&gt;, and the target's output isn't thrown away.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A break-in sent immediately after &lt;code&gt;g&lt;/code&gt; no longer gets lost.&lt;/strong&gt; Resuming used to return before the debugger read the &lt;code&gt;g&lt;/code&gt;, leaving a window where a CTRL+BREAK hit the prompt instead of the target. Against a live KDNET target, a break sent with no gap was lost &lt;em&gt;every single time&lt;/em&gt;. The resume is now confirmed consumed before reporting success.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Break-in checks before signaling.&lt;/strong&gt; A CTRL+BREAK aimed at an already-stopped target would queue and re-halt it later. The session now probes for a prompt first and only signals if there's no answer, making speculative &lt;code&gt;send_ctrl_break&lt;/code&gt; calls safe.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;bp nt!X; g&lt;/code&gt; reports whether the breakpoint was set.&lt;/strong&gt; A typo'd symbol now shows up as &lt;code&gt;Couldn't resolve error&lt;/code&gt; instead of an endless wait.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One operation per session at a time.&lt;/strong&gt; &lt;code&gt;wait_for_break&lt;/code&gt; parks on a worker thread while the server keeps answering other requests; a second call on the same session is refused immediately. Closing a session also ends any wait parked on it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kernel sessions over named pipe or serial connect.&lt;/strong&gt; &lt;code&gt;kd&lt;/code&gt; announces those links with a different message than KDNET, and only the latter was matched - so sessions that were actually attached timed out.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Still one line:&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;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:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Release notes: &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.1.0&quot;&gt;v1.1.0&lt;/a&gt; - Docs: &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/&quot;&gt;svnscha.github.io/mcp-windbg&lt;/a&gt; - Source: &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;github.com/svnscha/mcp-windbg&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;No headline features here. Just a dependency cap, a canary, one new tool, and a long list of places where the debugger and the server disagreed about who was talking. That's what a &lt;code&gt;.1&lt;/code&gt; release should be - especially after a 1.0.0 nobody could install.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If mcp-windbg has helped you, I'd love to hear about it. Open an issue, reach out, or star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository&lt;/a&gt;. Thank you.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.0.0</title>
        <published>2026-07-16T00:00:00+00:00</published>
        <updated>2026-07-16T00: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-0-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-0-0-release/</id>
        <summary type="html">Kernel debugging, session IDs, and a redesigned tool surface. The first stable release.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-0-0-release/">&lt;p&gt;I've just released version 1.0.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt;. Yes, one-point-zero. The headline: &lt;strong&gt;your AI assistant can now debug the Windows kernel.&lt;/strong&gt; The fine print: every tool has a new name, so bring your prompts. Both below.&lt;/p&gt;
&lt;h2 id=&quot;kernel-debugging&quot;&gt;Kernel Debugging&lt;/h2&gt;
&lt;p&gt;Three new tools, &lt;code&gt;open_kd_session&lt;/code&gt;, &lt;code&gt;run_kd_command&lt;/code&gt;, and &lt;code&gt;close_kd_session&lt;/code&gt;, drive &lt;code&gt;kd.exe&lt;/code&gt; against a live kernel target over the connections you would actually use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;KDNET&lt;/strong&gt; (&lt;code&gt;net:port=...,key=...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Named pipes&lt;/strong&gt; (&lt;code&gt;com:pipe,port=\\.\pipe\...&lt;/code&gt;) - the classic VM setup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Serial&lt;/strong&gt; - because sometimes it is 2003 in your lab and that is fine&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Point your assistant at a VM, ask what that driver is up to, and let it run &lt;code&gt;!process&lt;/code&gt;, &lt;code&gt;!irql&lt;/code&gt;, &lt;code&gt;lm&lt;/code&gt;, and friends while you have your coffee.&lt;/p&gt;
&lt;p&gt;A kernel target is not a dump file: break in at the wrong moment and you have halted an entire machine. The tools are built around that reality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sessions arrive already stopped.&lt;/strong&gt; &lt;code&gt;open_kd_session&lt;/code&gt; waits for the connect banner and breaks in for you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Closing resumes the target.&lt;/strong&gt; &lt;code&gt;close_kd_session&lt;/code&gt; sends &lt;code&gt;g&lt;/code&gt; by default; pass &lt;code&gt;resume: false&lt;/code&gt; only if you want the machine frozen on purpose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--kd-path&lt;/code&gt;&lt;/strong&gt; points the server at a specific &lt;code&gt;kd.exe&lt;/code&gt;, the counterpart to &lt;code&gt;--cdb-path&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also two new guided prompts to go with it: &lt;strong&gt;&lt;code&gt;kernel-triage&lt;/code&gt;&lt;/strong&gt; investigates a kernel target (including telling a real bugcheck apart from a plain break-in, and releasing the machine at the end), and &lt;strong&gt;&lt;code&gt;remote-triage&lt;/code&gt;&lt;/strong&gt; does the same for a live user-mode process.&lt;/p&gt;
&lt;h2 id=&quot;session-ids&quot;&gt;Session IDs&lt;/h2&gt;
&lt;p&gt;The other big change: sessions are now first-class. Every &lt;code&gt;open_*&lt;/code&gt; tool returns an opaque &lt;strong&gt;session ID&lt;/strong&gt; (&lt;code&gt;cdb-…&lt;/code&gt; or &lt;code&gt;kd-…&lt;/code&gt;), and &lt;code&gt;run_*&lt;/code&gt;, &lt;code&gt;close_*&lt;/code&gt;, and &lt;code&gt;send_ctrl_break&lt;/code&gt; address a session by that ID. No more implicit sessions, no more addressing by dump path: open first, then talk. Opening the same dump twice gives you two independent sessions.&lt;/p&gt;
&lt;p&gt;The kind is enforced, too: pass a &lt;code&gt;cdb&lt;/code&gt; ID to &lt;code&gt;run_kd_command&lt;/code&gt; and you get an error naming the right tool. That matters more than it sounds when the caller is a model that occasionally guesses.&lt;/p&gt;
&lt;h2 id=&quot;the-breaking-changes&quot;&gt;The Breaking Changes&lt;/h2&gt;
&lt;p&gt;The old names conflated the product (WinDbg) with the engines doing the work (&lt;code&gt;cdb.exe&lt;/code&gt; for user mode, &lt;code&gt;kd.exe&lt;/code&gt; for kernel). That distinction is now load-bearing, so everything got renamed:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0.x&lt;/th&gt;
&lt;th&gt;1.0.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_windbg_dumps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;list_dumps&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;open_windbg_dump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;open_cdb_dump&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;open_windbg_remote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;open_cdb_remote&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;run_windbg_cmd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;run_cdb_command&lt;/code&gt; / &lt;code&gt;run_kd_command&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;close_windbg_dump&lt;/code&gt;, &lt;code&gt;close_windbg_remote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;close_cdb_session&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Also: &lt;code&gt;send_ctrl_break&lt;/code&gt; takes a &lt;code&gt;session_id&lt;/code&gt;, and the &lt;code&gt;connection_type&lt;/code&gt; parameter is gone because the tool name now says which engine you mean. If you have prompts or agent instructions written against the 0.x names, they need updating - that is exactly why this is 1.0.0 and not 0.16.0. The &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/&quot;&gt;docs&lt;/a&gt; are rewritten around the new flow, including a &quot;Debug a kernel target&quot; guide.&lt;/p&gt;
&lt;h2 id=&quot;smaller-but-you-will-notice&quot;&gt;Smaller, But You Will Notice&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Per-call timeouts&lt;/strong&gt;: &lt;code&gt;timeout_seconds&lt;/code&gt; on any &lt;code&gt;open_*&lt;/code&gt; / &lt;code&gt;run_*&lt;/code&gt; overrides that tool's default. Useful when that one &lt;code&gt;!analyze -v&lt;/code&gt; against a 30 GB dump needs its time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A slow command no longer wedges the session.&lt;/strong&gt; On timeout the server breaks in with CTRL+BREAK and resynchronizes, so the session is usable for the next command instead of stranded.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Output goes to the right command.&lt;/strong&gt; Every command waits on its own unique completion marker, so late output from a slow command can never be mistaken for the next one's result.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No more orphaned debuggers.&lt;/strong&gt; &lt;code&gt;cdb.exe&lt;/code&gt; launched via the Microsoft Store aliases spawns a child that a plain terminate left behind, still holding the target. Shutdown now kills the whole process tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Still a one-liner:&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;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:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Full release notes are on the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.0.0&quot;&gt;v1.0.0 release page&lt;/a&gt;, and the project lives at &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;github.com/svnscha/mcp-windbg&lt;/a&gt;. A star is always appreciated.&lt;/p&gt;
&lt;h2 id=&quot;one-point-zero&quot;&gt;One-Point-Zero&lt;/h2&gt;
&lt;p&gt;Fourteen months ago this was a &lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;weekend experiment&lt;/a&gt;. Today it sits at 1.4k stars and debugs kernels. Calling it 1.0 is a promise more than a milestone: the names are stable now, and breaking changes from here on will be rare and loud.&lt;/p&gt;
&lt;p&gt;Here is to stable.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If mcp-windbg has helped you, I would love to hear about it. Reach out, open an issue, or just star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository&lt;/a&gt;. Thank you all.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 0.15.0</title>
        <published>2026-06-09T00:00:00+00:00</published>
        <updated>2026-06-09T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/mcp-windbg-0-15-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-0-15-0-release/</id>
        <summary type="html">Break into live sessions, redact sensitive output before it reaches the model, and a brand-new documentation site. A year and a month in, with 1.4k stars and a community that keeps showing up.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-0-15-0-release/">&lt;p&gt;I've just released version 0.15.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt;. It has been a while since the &lt;a href=&quot;/posts/mcp-windbg-0-12-2-release/&quot;&gt;0.12.2 post&lt;/a&gt;, and three releases have landed since then. Rather than a single feature, this is a round-up of everything that has shipped: a way to break into a running session, a hook to scrub sensitive data before it ever reaches the model, and a proper documentation site to tie it all together.&lt;/p&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;What's New&lt;/h2&gt;
&lt;h3 id=&quot;break-into-a-live-session&quot;&gt;Break into a live session&lt;/h3&gt;
&lt;p&gt;If you have used a real debugger, you know the moment: the process is spinning, you want to know what it is doing &lt;em&gt;right now&lt;/em&gt;, and you reach for CTRL+BREAK. That now works through the MCP interface too.&lt;/p&gt;
&lt;p&gt;The new &lt;code&gt;send_ctrl_break&lt;/code&gt; tool, contributed by &lt;a href=&quot;https://github.com/GeoYS&quot;&gt;@GeoYS&lt;/a&gt;, interrupts an active CDB/WinDbg session, for both dump and remote debugging workflows. So when you are driving a live target and it wanders off into a tight loop or a long wait, the model can break in, inspect the state, and carry on, the same way you would at the keyboard. This closes a real gap: before, a live session that was busy was a session you could only wait on.&lt;/p&gt;
&lt;h3 id=&quot;redact-sensitive-data-before-it-leaves-the-machine&quot;&gt;Redact sensitive data before it leaves the machine&lt;/h3&gt;
&lt;p&gt;Crash dumps are full of things you might not want to hand to a model: file paths with usernames, machine names, environment variables, command lines, sometimes worse. The new &lt;code&gt;--filter-script&lt;/code&gt; option lets you point the server at a trusted Python helper that can rewrite string-valued tool arguments and tool text output on the way through.&lt;/p&gt;
&lt;p&gt;The important part is the boundary. Your script only sees the string values, not the full MCP protocol messages, so you can do focused PII redaction (mask a username, strip a token, normalize a path) without writing a protocol-aware proxy. If you run a centralized analysis service, this is the piece that lets you control what actually crosses the wire.&lt;/p&gt;
&lt;h3 id=&quot;a-real-documentation-site&quot;&gt;A real documentation site&lt;/h3&gt;
&lt;p&gt;The project has outgrown a README and a wiki. There is now a proper &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/&quot;&gt;documentation site&lt;/a&gt; built with MkDocs Material and deployed to GitHub Pages. It covers getting started, the individual use cases, and a reference for the command-line options, the tools, and client configuration.&lt;/p&gt;
&lt;p&gt;A few highlights worth calling out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use-case guides&lt;/strong&gt; for the things people kept asking about: running the server over HTTP to &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/scenarios/http-service/&quot;&gt;debug from another machine&lt;/a&gt;, and scrubbing tool output to &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/scenarios/redaction/&quot;&gt;redact sensitive data&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The built-in &lt;code&gt;dump-triage&lt;/code&gt; prompt&lt;/strong&gt; is now &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/reference/prompts/&quot;&gt;documented&lt;/a&gt;, including its &lt;code&gt;dump_path&lt;/code&gt; argument, so you can trigger a full structured triage without hand-writing the workflow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Honest limitations&lt;/strong&gt; are written down rather than discovered the hard way: the HTTP transport has no authentication, attach-by-PID is not supported, and sessions run concurrently.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quieter-sturdier-foundations&quot;&gt;Quieter, sturdier foundations&lt;/h3&gt;
&lt;p&gt;This release also includes several smaller changes that matter in daily use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;stdio transport no longer crashes on a malformed input line&lt;/strong&gt;. A single unparseable line used to tear down the whole process; now it is logged and the server keeps running.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;test suite was rebuilt&lt;/strong&gt; as a declarative end-to-end harness. Every scenario runs against a really-hosted &lt;code&gt;python -m mcp_windbg&lt;/code&gt; server driven by a real MCP client, with only the LLM faked. Coverage now sits above 90 percent, measured in the subprocess where tool dispatch actually runs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Package metadata is complete&lt;/strong&gt;, so &lt;code&gt;pip show&lt;/code&gt; and the PyPI page now carry the author, project URLs, and proper classifiers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Symbols resolve more often out of the box&lt;/strong&gt;: the dump's own directory is now auto-included in the symbol search path, so PDBs sitting next to a dump are found without extra configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;community-contributions&quot;&gt;Community Contributions&lt;/h2&gt;
&lt;p&gt;This stretch of releases leaned on the community, and two contributions stand out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/GeoYS&quot;&gt;@GeoYS&lt;/a&gt; added the live break-in feature in &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/pull/40&quot;&gt;#40&lt;/a&gt;, which became the &lt;code&gt;send_ctrl_break&lt;/code&gt; tool above. It is the headline of the 0.13.0 release.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/SSyl&quot;&gt;@SSyl&lt;/a&gt; made symbols just work in more cases by auto-including the dump directory in the symbol search path (&lt;a href=&quot;https://github.com/svnscha/mcp-windbg/pull/41&quot;&gt;#41&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is exactly the kind of contribution that makes a tool better for everyone, not just the person who filed it. Thank you both.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Installation is unchanged and still a one-liner:&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;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:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The project is open source and available on GitHub at &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;https://github.com/svnscha/mcp-windbg&lt;/a&gt;. If you find it useful, a star on the repository is always appreciated.&lt;/p&gt;
&lt;h2 id=&quot;a-year-and-a-month-in&quot;&gt;A Year and a Month In&lt;/h2&gt;
&lt;p&gt;It is hard to believe, but mcp-windbg is now a year and a month old. When I &lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;first wrote about it&lt;/a&gt; in May 2025, it was a weekend experiment to scratch my own itch: I was tired of typing the same WinDbg commands over and over, and I wanted to see whether a model could drive the debugger for me. I genuinely did not expect it to go anywhere.&lt;/p&gt;
&lt;p&gt;It went somewhere. The repository now sits at &lt;strong&gt;1.4k stars&lt;/strong&gt;, the original article reached tens of thousands of readers in its first days, and the project has shown up in conversations, talks, and threads far beyond anything I planned. People have used it to triage real production crashes, wired it into team workflows, and sent screenshots of it cracking bugs that had been open for weeks. Every one of those still makes my day.&lt;/p&gt;
&lt;p&gt;What has meant the most, though, is not the numbers. It is the people. Contributors who saw a gap and just fixed it. Folks who filed thoughtful issues, asked sharp questions, or pushed back when something did not work the way they needed. The many of you who reached out directly, by email, on LinkedIn, in DMs, to say the tool saved you an afternoon, or to suggest where it should go next. A project like this is only as good as the community around it, and this one has been generous well beyond what I could have hoped for.&lt;/p&gt;
&lt;p&gt;So this is mostly a thank-you note. Thank you for the stars, the pull requests, the issues, the messages, and for trusting a small open-source tool with your hardest crashes. You are the reason it keeps getting better, and the reason I keep shipping.&lt;/p&gt;
&lt;p&gt;Here is to the next year.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If mcp-windbg has helped you, I would love to hear about it. Reach out, open an issue, or just star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository&lt;/a&gt;. Thank you all.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Introducing Native Windows Debugging for VS Code: Kernel &amp; Remote Debugging</title>
        <published>2026-06-07T00:00:00+00:00</published>
        <updated>2026-06-07T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/native-windows-kernel-remote-debugging-vscode/"/>
        <id>https://svnscha.de/posts/native-windows-kernel-remote-debugging-vscode/</id>
        <summary type="html">Last time I had a proof of concept. This time I closed the gap: remote debugging and Windows kernel debugging, straight from VS Code, powered by the same engine as WinDbg. It's open source and on the Marketplace.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/native-windows-kernel-remote-debugging-vscode/">&lt;h2 id=&quot;remember-the-cliffhanger&quot;&gt;Remember the Cliffhanger?&lt;/h2&gt;
&lt;p&gt;A while back I wrote about &lt;a href=&quot;/posts/the-joy-of-writing-a-debugger-adapter-for-visual-studio-code/&quot;&gt;the joy of writing a debugger adapter for Visual Studio Code&lt;/a&gt;. It started with a simple wish - I just wanted a faster way to remote-debug a service running in a VM - and ended with a working proof of concept: VS Code driving WinDbg through a custom Debug Adapter Protocol implementation.&lt;/p&gt;
&lt;p&gt;But that post ended on an honest note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have not implemented remote debugging or kernel debugging yet, but I now feel ready to take a real shot at both without getting lost in the basics again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well. I took the shot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remote debugging works. Kernel debugging works.&lt;/strong&gt; And the whole thing is now a real, installable VS Code extension: &lt;strong&gt;Native Windows Debugging (dbgeng)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Debug native Windows code - C and C++ programs, services, and even the Windows kernel - straight from Visual Studio Code, using the same engine that powers WinDbg.&lt;/p&gt;
&lt;div style=&quot;position:relative;padding-bottom:56.25%;height:0;overflow:hidden;margin:1.5rem 0;&quot;&gt;
  &lt;iframe style=&quot;position:absolute;top:0;left:0;width:100%;height:100%;border:0;&quot; src=&quot;https://www.youtube-nocookie.com/embed/bEuCPRmjE8o&quot; title=&quot;Native Windows Debugging (dbgeng) for VS Code&quot; loading=&quot;lazy&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;That's the whole pitch in under two minutes. Now let me show you what's behind it.&lt;/p&gt;
&lt;h2 id=&quot;get-it-right-now&quot;&gt;Get It Right Now&lt;/h2&gt;
&lt;p&gt;No waiting, no building from source:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Marketplace:&lt;/strong&gt; &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=svnscha.vscode-dap-dbgeng&quot;&gt;Native Windows Debugging (dbgeng)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href=&quot;https://github.com/svnscha/dap-dbgeng&quot;&gt;github.com/svnscha/dap-dbgeng&lt;/a&gt; (MIT licensed)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href=&quot;https://svnscha.github.io/dap-dbgeng/&quot;&gt;svnscha.github.io/dap-dbgeng&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The adapter is &lt;strong&gt;bundled inside the extension&lt;/strong&gt;, so there's nothing separate to build, download, or point at. Install it, write a &lt;code&gt;launch.json&lt;/code&gt;, press &lt;kbd&gt;F5&lt;/kbd&gt;. That's it.&lt;/p&gt;
&lt;h2 id=&quot;four-ways-to-debug---two-of-them-were-never-possible-before&quot;&gt;Four Ways to Debug - Two of Them Were Never Possible Before&lt;/h2&gt;
&lt;p&gt;VS Code has always had great local debugging for plenty of languages. But the moment you wanted &lt;em&gt;native Windows&lt;/em&gt; remote or kernel debugging, you hit a wall. That stack lives in Visual Studio and WinDbg, not in VS Code - because of course it does.&lt;/p&gt;
&lt;p&gt;This extension closes exactly that gap. One adapter, four scenarios:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Local&lt;/strong&gt; - the debugger starts your program and debugs it from launch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attach&lt;/strong&gt; - connect to a process that's already running, by its PID.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote&lt;/strong&gt; - debug a user-mode process on &lt;em&gt;another&lt;/em&gt; machine via &lt;code&gt;dbgsrv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kernel&lt;/strong&gt; - debug kernel-mode drivers and the OS around them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first two are the comfortable ones. The last two are the gap I set out to close. Let's walk through them.&lt;/p&gt;
&lt;h2 id=&quot;local-the-comfortable-starting-point&quot;&gt;Local: The Comfortable Starting Point&lt;/h2&gt;
&lt;p&gt;Start simple. The debugger launches your program and you step through it like any other debugger in VS Code. It's just a &lt;code&gt;launch.json&lt;/code&gt;:&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;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Debug myapp&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;dbgeng&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;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;launch&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;program&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;${workspaceFolder}/build/Debug/myapp.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;stopAtEntry&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&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;&lt;code&gt;program&lt;/code&gt; is the only thing you really have to provide. &lt;code&gt;dbgeng.dll&lt;/code&gt; is found automatically from your installed Windows SDK, so you usually don't even set a path. Set a breakpoint, press &lt;kbd&gt;F5&lt;/kbd&gt;, and you get the full loop: continue, step over, step into, step out, call stack, locals, watch expressions, and a Debug Console that evaluates expressions through the real engine.&lt;/p&gt;
&lt;p&gt;If you use the &lt;strong&gt;CMake Tools&lt;/strong&gt; extension, you can even drop the &lt;code&gt;program&lt;/code&gt; line entirely - the adapter defaults to your selected CMake launch target. Point CMake's debug command at the &lt;code&gt;dbgeng&lt;/code&gt; type and &lt;strong&gt;CMake: Debug&lt;/strong&gt; just works.&lt;/p&gt;
&lt;h2 id=&quot;attach-already-running-just-connect&quot;&gt;Attach: Already Running? Just Connect&lt;/h2&gt;
&lt;p&gt;Sometimes the process is already alive and you don't want to restart it. Attach to it by its process ID:&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;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Attach to myapp&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;dbgeng&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;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;attach&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;processId&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;12345&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;Don't know the PID off the top of your head? Set &lt;code&gt;&quot;processId&quot;: &quot;${command:dap-dbgeng.pickProcess}&quot;&lt;/code&gt; and you get a process picker at debug time. Same familiar VS Code interface, with the real Windows debug engine underneath.&lt;/p&gt;
&lt;h2 id=&quot;remote-my-favorite-part&quot;&gt;Remote: My Favorite Part&lt;/h2&gt;
&lt;p&gt;This was the first scenario I implemented: debugging a user-mode process on &lt;strong&gt;another machine&lt;/strong&gt; while keeping the debug engine and symbols on the local system.&lt;/p&gt;
&lt;p&gt;The trick is the Windows process server, &lt;code&gt;dbgsrv&lt;/code&gt;. You run it on the target, and your machine connects to it over TCP (or a named pipe).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On the target&lt;/strong&gt;, start the process server:&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;cmd&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;dbgsrv -t tcp:port=&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;5005&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;On your machine&lt;/strong&gt;, point a &lt;code&gt;launch.json&lt;/code&gt; at it:&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;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Attach on TARGETPC&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;dbgeng&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;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;attach&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;processId&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;${command:dap-dbgeng.pickProcess}&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;connectionString&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;tcp:port=5005,server=TARGETPC&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;Press &lt;kbd&gt;F5&lt;/kbd&gt;, pick the remote process from the list (the picker now shows processes on the &lt;code&gt;dbgsrv&lt;/code&gt; host), and you're debugging it remotely. The engine and symbols never leave your machine - only the debuggee lives on the other side.&lt;/p&gt;
&lt;p&gt;This is precisely the workflow I wanted at the very beginning: compile locally, deploy to the VM, attach, get back to work. Now it's a one-keystroke thing.&lt;/p&gt;
&lt;h2 id=&quot;kernel-yes-really&quot;&gt;Kernel: Yes, Really&lt;/h2&gt;
&lt;p&gt;And then there's the big one. &lt;strong&gt;Kernel-mode debugging from VS Code.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Kernel debugging is whole-machine, so you need two boxes: a &lt;strong&gt;host&lt;/strong&gt; (VS Code + the adapter) and a &lt;strong&gt;target&lt;/strong&gt; being debugged - almost always a throwaway VM, because kernel debugging halts the entire target at breakpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On the target&lt;/strong&gt;, enable kernel debugging and reboot:&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;cmd&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;bcdedit&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; /debug on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;bcdedit&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; /dbgsettings &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;net&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; hostip:&amp;lt;HOST-IP&amp;gt; port:50005 key:1.2.3.4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;On the host&lt;/strong&gt;, point a kernel config at it:&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;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Debug driver (KDNET)&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;dbgeng&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;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;attach&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;kernel&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&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;connectionString&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;net:port=50005,key=1.2.3.4&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;kernel: true&lt;/code&gt; flips the adapter into kernel mode and turns &lt;code&gt;connectionString&lt;/code&gt; into a kernel transport. There's no &lt;code&gt;processId&lt;/code&gt; here - the session &lt;em&gt;is&lt;/em&gt; the whole machine. Press &lt;kbd&gt;F5&lt;/kbd&gt;, it connects over KDNET, and breaks at &lt;code&gt;DriverEntry&lt;/code&gt;. From the same editor people keep telling me is &quot;just a text editor.&quot;&lt;/p&gt;
&lt;p&gt;Kernel debugging. Just another breakpoint. That still feels a little unreal to type.&lt;/p&gt;
&lt;p&gt;KDNET isn't the only option, either - the same &lt;code&gt;connectionString&lt;/code&gt; field speaks serial (named pipe), 1394, and USB transports too. Whatever your VM or test box gives you.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;p&gt;A few things changed since the proof of concept, and they're worth a mention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It talks to the engine natively.&lt;/strong&gt; The adapter uses the real DbgEng APIs throughout - &lt;code&gt;IDebugClient&lt;/code&gt;, &lt;code&gt;IDebugControl&lt;/code&gt;, &lt;code&gt;IDebugSymbols&lt;/code&gt;, &lt;code&gt;IDebugSystemObjects&lt;/code&gt;, with &lt;code&gt;IDebugEventCallbacks&lt;/code&gt; and &lt;code&gt;IDebugOutputCallbacks&lt;/code&gt; for events. No fragile text-scraping of WinDbg console output. When the engine knows something, the adapter asks it directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The protocol layer is still generated.&lt;/strong&gt; That code-generation step I was so happy about last time paid off again. &lt;code&gt;src/protocol/&lt;/code&gt; is generated from the official DAP schema, so every request, response, and event stays in lockstep with the spec instead of drifting from hand-written DTOs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The POC grew up - and changed language.&lt;/strong&gt; The original proof of concept was C#. Hardening it into something I'd actually ship meant rebuilding the adapter in &lt;strong&gt;C++20&lt;/strong&gt; (CMake + Ninja, vcpkg manifest mode), sitting much closer to the engine it wraps. That was part of the &quot;harden the rough edges&quot; plan, and it made the kernel and remote work far less painful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It records itself.&lt;/strong&gt; There's a built-in session-trace recorder that doubles as the project's replay-test format. Recorded sessions get replayed against real test debuggees in CI, so the behaviors you see in those videos are the same behaviors the test suite asserts on.&lt;/p&gt;
&lt;h2 id=&quot;an-honest-word-on-scope&quot;&gt;An Honest Word on Scope&lt;/h2&gt;
&lt;p&gt;I'm keeping the same promise I made in the first post: the adapter advertises only what it implements &lt;em&gt;correctly&lt;/em&gt;, rather than dangling buttons that misbehave.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What works today:&lt;/strong&gt; line and conditional breakpoints, step over/into/out, continue, pause, instruction-level stepping in the disassembly view, call stack with delayed frame loading, variables and scopes (including registers), set-variable, expression evaluation in the Watch pane and Debug Console, disassembly view, and clean terminate/disconnect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What's planned but not advertised yet:&lt;/strong&gt; function breakpoints, data breakpoints (watchpoints), hit-conditional breakpoints, logpoints, read/write memory, a modules view, evaluate-on-hover, and hex formatting toggles. The engine can do all of these - the adapter just doesn't expose them yet. The &lt;a href=&quot;https://svnscha.github.io/dap-dbgeng/reference/features/&quot;&gt;features reference&lt;/a&gt; keeps the full, deliberately conservative list.&lt;/p&gt;
&lt;p&gt;And here's the escape hatch: anything the UI doesn't surface, you can usually still do by typing native debugger commands straight into the Debug Console. It's the real engine - it'll answer.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;If you want to try it, the whole loop is about ten minutes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;strong&gt;Native Windows Debugging (dbgeng)&lt;/strong&gt; from the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=svnscha.vscode-dap-dbgeng&quot;&gt;Marketplace&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make sure you have &lt;strong&gt;Debugging Tools for Windows&lt;/strong&gt; (it ships &lt;code&gt;dbgeng.dll&lt;/code&gt;, via the Windows SDK or WDK installer). The adapter finds it automatically.&lt;/li&gt;
&lt;li&gt;Drop a &lt;code&gt;dbgeng&lt;/code&gt; configuration into &lt;code&gt;.vscode/launch.json&lt;/code&gt; - pick the scenario from above.&lt;/li&gt;
&lt;li&gt;Set a breakpoint, press &lt;kbd&gt;F5&lt;/kbd&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href=&quot;https://svnscha.github.io/dap-dbgeng/getting-started/&quot;&gt;Getting Started guide&lt;/a&gt; walks through it in detail, and each scenario has its own page in the docs.&lt;/p&gt;
&lt;h2 id=&quot;your-turn&quot;&gt;Your Turn&lt;/h2&gt;
&lt;p&gt;This is open source, and it's at the stage where real-world usage is the most valuable thing it can get. So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;Star it&lt;/strong&gt; on &lt;a href=&quot;https://github.com/svnscha/dap-dbgeng&quot;&gt;GitHub&lt;/a&gt; if it's useful to you.&lt;/li&gt;
&lt;li&gt;🐛 &lt;strong&gt;Report a bug&lt;/strong&gt; through the &lt;a href=&quot;https://github.com/svnscha/dap-dbgeng/issues&quot;&gt;issue tracker&lt;/a&gt; - the templates tell you what to include.&lt;/li&gt;
&lt;li&gt;🔧 &lt;strong&gt;Contribute&lt;/strong&gt; if you're into native Windows debugging internals; see &lt;code&gt;CONTRIBUTING.md&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Last time I closed with &quot;I just want to remote debug a service on a VM.&quot; That was the entire ambition.&lt;/p&gt;
&lt;p&gt;It turned into DAP, a code generator, a &lt;code&gt;dbgeng&lt;/code&gt; wrapper, a pile of state-machine bugs - and now remote debugging, kernel debugging, a published extension, and a documentation site.&lt;/p&gt;
&lt;p&gt;The gap between &quot;VS Code can't do native Windows kernel and remote debugging&quot; and &quot;actually, now it can&quot; is closed. With the same engine that powers WinDbg, sitting quietly behind the editor you already use every day.&lt;/p&gt;
&lt;p&gt;And yes - it still started with &quot;I just want to remote debug a service on a VM.&quot;&lt;/p&gt;
&lt;h2 id=&quot;ps---one-more-thing-about-those-videos&quot;&gt;P.S. - One More Thing About Those Videos&lt;/h2&gt;
&lt;p&gt;While you're here: how did you actually like the videos? Be honest.&lt;/p&gt;
&lt;p&gt;Because here's the fun part - this is the first time I generated end-to-end videos, all the way from Claude to YouTube. No editing suite, no timeline scrubbing, no manual voiceover takes. Just prompting and vibing until it looked right.&lt;/p&gt;
&lt;p&gt;The stack, if you're curious:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.remotion.dev/&quot;&gt;Remotion&lt;/a&gt;&lt;/strong&gt; for the video itself - everything you see is React, rendered to MP4. Code as video turns out to be a really nice fit for the &quot;iterate fast&quot; loop.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My &lt;a href=&quot;/posts/dgx-spark-hello-word/&quot;&gt;DGX Spark&lt;/a&gt;&lt;/strong&gt; doing the heavy lifting locally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/OpenMOSS/MOSS-TTS&quot;&gt;MOSS-TTS&lt;/a&gt;&lt;/strong&gt; for the voice. And here's a little detour: I first deep-cloned &lt;em&gt;my own&lt;/em&gt; voice. The result was genuinely impressive - but not quite perfect, and the &quot;almost me&quot; uncanny gap bugged me more than I expected. So I switched to a fully synthesized voice instead, and I was happier with that than with a not-quite-right clone of myself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think that's pretty cool. A little surreal, honestly. The same &quot;describe what you want, iterate, ship&quot; loop that built the debugger also produced the launch video for it.&lt;/p&gt;
&lt;p&gt;So let me know what you think - of the extension &lt;em&gt;and&lt;/em&gt; of the videos. What worked, what felt off, what you'd want next. There's no comment box here, so just &lt;strong&gt;hit me up&lt;/strong&gt; (&lt;a href=&quot;https://www.linkedin.com/in/svnscha/&quot;&gt;LinkedIn&lt;/a&gt; or &lt;a href=&quot;https://github.com/svnscha/&quot;&gt;GitHub&lt;/a&gt;) or open an issue. I'm genuinely curious.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>The Joy of Writing a Debugger Adapter for Visual Studio Code</title>
        <published>2026-04-15T00:00:00+00:00</published>
        <updated>2026-04-15T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/the-joy-of-writing-a-debugger-adapter-for-visual-studio-code/"/>
        <id>https://svnscha.de/posts/the-joy-of-writing-a-debugger-adapter-for-visual-studio-code/</id>
        <summary type="html">I only wanted a faster remote debugging workflow for a service running in a VM. Instead, I ended up learning DAP, wrapping WinDbg, and building a working first proof of concept debugger adapter for VS Code.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/the-joy-of-writing-a-debugger-adapter-for-visual-studio-code/">&lt;h2 id=&quot;current-state&quot;&gt;Current State&lt;/h2&gt;
&lt;p&gt;Before I get into the story, here is the current result: Visual Studio Code debugging a C++ application with WinDbg under the hood through my first proof of concept integration.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/screenshots/2026-04-15-dap-windbg.png&quot; alt=&quot;WinDbg running through the VS Code debugger adapter&quot;&gt;&lt;/p&gt;
&lt;p&gt;Right now this is still an early POC, not a finished debugger experience. It proves the architecture works and that VS Code can drive WinDbg through a custom adapter, but it still needs a lot more iteration before I would call it really useful.&lt;/p&gt;
&lt;p&gt;One detail I already like is that the debugger command window is not a fake simplified console. I can type regular WinDbg commands straight into it.&lt;/p&gt;
&lt;h2 id=&quot;why&quot;&gt;Why&lt;/h2&gt;
&lt;p&gt;Because I do what I always do when a workflow annoys me: I build a tool until the annoyance goes away.&lt;/p&gt;
&lt;p&gt;This time the pain point was remote debugging a service application running inside a VM. My ideal flow was simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compile locally&lt;/li&gt;
&lt;li&gt;Deploy to the VM&lt;/li&gt;
&lt;li&gt;Start or restart the service&lt;/li&gt;
&lt;li&gt;Attach a debugger&lt;/li&gt;
&lt;li&gt;Get back to work without ten minutes of clicking around&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That sounded perfectly reasonable: a small helper extension for Visual Studio Code, a bit of automation, some launch configuration glue, and done.&lt;/p&gt;
&lt;p&gt;That was the plan.&lt;/p&gt;
&lt;p&gt;It did not stay the plan.&lt;/p&gt;
&lt;h2 id=&quot;removing-friction&quot;&gt;Removing Friction&lt;/h2&gt;
&lt;p&gt;I started with the pragmatic part first: automate the annoying steps.&lt;/p&gt;
&lt;p&gt;I wired up a helper extension that could compile the service, copy the binaries to the VM, and prepare the remote machine for debugging. This is my favorite kind of productivity work, because the payoff is immediate. Every bit of friction you remove saves time again and again.&lt;/p&gt;
&lt;p&gt;Once the plumbing was in place, I expected the final step to be easy: tell VS Code to remote debug the service and call it a day.&lt;/p&gt;
&lt;p&gt;Instead, I hit a wall.&lt;/p&gt;
&lt;h2 id=&quot;vs-code-is-not-visual-studio&quot;&gt;VS Code Is Not Visual Studio&lt;/h2&gt;
&lt;p&gt;At first glance, this feels like something that should already exist. Visual Studio has mature debugging capabilities. VS Code has debugging. Microsoft builds both. Surely there must be a supported path to do classic remote Windows debugging from VS Code, right?&lt;/p&gt;
&lt;p&gt;Not really.&lt;/p&gt;
&lt;p&gt;The more I dug into it, the clearer it became that the debugging stack in VS Code is a different world. VS Code speaks the Debug Adapter Protocol, or DAP. It expects debugger extensions to implement that protocol and sit between the editor and the actual debugger engine.&lt;/p&gt;
&lt;p&gt;That part is good. DAP is a clean idea.&lt;/p&gt;
&lt;p&gt;The frustrating bit was this: the specific native Windows remote-debugging flow I wanted was not available through a supported public route in VS Code. The Visual Studio native debugger stack is not something you can just plug into from your own VS Code extension and say, &quot;Thanks, I will take remote debugging from here.&quot; And the VS Code side does not magically inherit Visual Studio's remote debugging capabilities just because both products come from Microsoft.&lt;/p&gt;
&lt;p&gt;So after spending time exploring options, the conclusion was simple:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There was no supported way to get the workflow I wanted with the existing pieces.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;building-it-anyway&quot;&gt;Building It Anyway&lt;/h2&gt;
&lt;p&gt;Once I accepted that I would not be wiring together existing public APIs, the problem changed shape.&lt;/p&gt;
&lt;p&gt;The question was no longer, &quot;How do I enable remote debugging in VS Code?&quot;&lt;/p&gt;
&lt;p&gt;It became:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&quot;What debugger engine can I control myself, and how do I make VS Code talk to it properly?&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That is where WinDbg entered the story.&lt;/p&gt;
&lt;p&gt;WinDbg already knows how to do the important parts. User-mode debugging. Remote debugging. Kernel debugging. Crash dump analysis. It is a serious tool with decades of capability behind it.&lt;/p&gt;
&lt;p&gt;But again, my tool of choice did not give me the VS Code experience I wanted out of the box.&lt;/p&gt;
&lt;p&gt;So the next step was clear:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build a debugger adapter for WinDbg.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;learning-dap&quot;&gt;Learning DAP&lt;/h2&gt;
&lt;p&gt;If you want to integrate a debugger with VS Code, DAP is the contract. Once I sat down and read it properly, a lot of things clicked.&lt;/p&gt;
&lt;p&gt;The official home for it is the &lt;a href=&quot;https://microsoft.github.io/debug-adapter-protocol/&quot;&gt;Debug Adapter Protocol website&lt;/a&gt;, and that site is worth bookmarking because it has both the overview and the actual specification. At the time I was working through this, the important mental model was simple: VS Code and the adapter exchange JSON messages with a very predictable shape, and the protocol defines what those messages are supposed to mean.&lt;/p&gt;
&lt;p&gt;The protocol is straightforward. VS Code sends requests like &lt;code&gt;initialize&lt;/code&gt;, &lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;attach&lt;/code&gt;, &lt;code&gt;setBreakpoints&lt;/code&gt;, &lt;code&gt;stackTrace&lt;/code&gt;, &lt;code&gt;variables&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, &lt;code&gt;next&lt;/code&gt;, and so on, and your adapter answers them while emitting events like &lt;code&gt;initialized&lt;/code&gt;, &lt;code&gt;stopped&lt;/code&gt;, &lt;code&gt;continued&lt;/code&gt;, and &lt;code&gt;terminated&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That sounds simple enough until you remember that a debugger is mostly state, timing, and edge cases.&lt;/p&gt;
&lt;p&gt;Still, the protocol gave me exactly what I needed: a structured way to make VS Code think in terms of debugging, while I figured out how to translate that into WinDbg behavior.&lt;/p&gt;
&lt;p&gt;This was the moment where the project stopped being a helper extension and became a real debugger adapter.&lt;/p&gt;
&lt;p&gt;To make that a bit more concrete, a minimal launch payload for the current POC looks roughly like this:&lt;/p&gt;
&lt;p&gt;The adapter currently points at the debugging engine directly, so the &lt;code&gt;windbg&lt;/code&gt; setting names the WinDbg stack even though the configured path is &lt;code&gt;dbgeng.dll&lt;/code&gt; rather than &lt;code&gt;windbg.exe&lt;/code&gt;.&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;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;dapwdbg&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;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;launch&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;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Launch through 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;windbg&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:/Program Files (x86)/Windows Kits/10/Debuggers/x64/dbgeng.dll&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;program&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;${workspaceFolder}/build/Debug/testapp.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;stopAtEntry&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&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;That &lt;code&gt;stopAtEntry&lt;/code&gt; flag is a small but useful quality-of-life feature. I added it because it is a familiar debugger option and useful to have. By default it is &lt;code&gt;false&lt;/code&gt;, so the adapter continues after &lt;code&gt;configurationDone&lt;/code&gt;. If you set it to &lt;code&gt;true&lt;/code&gt;, VS Code stays paused at entry and waits for the next command.&lt;/p&gt;
&lt;p&gt;And on the wire, the messages are simple, which is exactly what you want from a protocol. A stop event coming back from the adapter looks roughly like this:&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;seq&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;17&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;event&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;event&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;stopped&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;body&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;reason&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;entry&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;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Paused at process entry.&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;threadId&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;1&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;allThreadsStopped&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&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;That might not look exciting, but it is the important part: once VS Code receives something in that shape at the right time, it knows how to show the stack, scopes, variables, and stepping UI around it.&lt;/p&gt;
&lt;h2 id=&quot;step-1-parse-the-schemas-instead-of-hand-writing-everything&quot;&gt;Step 1: Parse the Schemas Instead of Hand-Writing Everything&lt;/h2&gt;
&lt;p&gt;One thing became obvious very quickly: I did not want to manually model the entire protocol by hand in C#.&lt;/p&gt;
&lt;p&gt;That is the kind of task that feels fine for the first ten message types and becomes a waste of time by the next fifty.&lt;/p&gt;
&lt;p&gt;DAP is defined by schemas. Machines should read schemas. Machines should generate code. Humans should not write all of that by hand.&lt;/p&gt;
&lt;p&gt;So one of the first pieces I built was a small toolchain around the protocol definitions.&lt;/p&gt;
&lt;p&gt;The idea was straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Parse the protocol schemas&lt;/li&gt;
&lt;li&gt;Convert them into C# types&lt;/li&gt;
&lt;li&gt;Use generated models for requests, responses, events, and payloads&lt;/li&gt;
&lt;li&gt;Stop wasting time on repetitive plumbing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This bought me two things immediately:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better consistency with the protocol&lt;/li&gt;
&lt;li&gt;Faster iteration whenever I needed to expand coverage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also reduced a whole category of annoying bugs where hand-written DTOs silently drift away from the spec.&lt;/p&gt;
&lt;p&gt;That generator phase was not glamorous, but it kept paying off. Every time I added another request handler later, I was very happy not to be hand-authoring another stack of protocol classes.&lt;/p&gt;
&lt;p&gt;The nice part is that the generated code stays very literal. For example, the generated &lt;code&gt;LaunchRequest&lt;/code&gt; model is basically just a strongly typed wrapper around the DAP shape, with &lt;code&gt;Command = &quot;launch&quot;&lt;/code&gt; baked in and a typed &lt;code&gt;Arguments&lt;/code&gt; property. A generated event model like &lt;code&gt;StoppedEvent&lt;/code&gt; then points at a generated &lt;code&gt;StoppedEventBody&lt;/code&gt; class with fields such as &lt;code&gt;Reason&lt;/code&gt;, &lt;code&gt;Description&lt;/code&gt;, &lt;code&gt;ThreadId&lt;/code&gt;, and &lt;code&gt;AllThreadsStopped&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That is exactly the level of abstraction I wanted. The protocol layer should be boring and explicit so the interesting work can happen one layer above it.&lt;/p&gt;
&lt;h2 id=&quot;step-2-a-python-generator-that-produces-c&quot;&gt;Step 2: A Python Generator That Produces C#&lt;/h2&gt;
&lt;p&gt;Yes, the adapter is in C#.&lt;/p&gt;
&lt;p&gt;Yes, I used Python to generate part of it.&lt;/p&gt;
&lt;p&gt;That combination made sense for the job. Python is still one of the fastest ways to build a transformation tool, especially when the task is basically: read structured input, normalize it, and generate source code.&lt;/p&gt;
&lt;p&gt;So I built a Python tool that parsed the protocol definitions and generated the corresponding C# code.&lt;/p&gt;
&lt;p&gt;That generator handled the boring but important parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Request and response classes&lt;/li&gt;
&lt;li&gt;Event payloads&lt;/li&gt;
&lt;li&gt;Shared protocol types&lt;/li&gt;
&lt;li&gt;Optional fields and enum-like shapes&lt;/li&gt;
&lt;li&gt;Enough structure to keep serialization predictable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This turned out to be one of the highest leverage steps in the whole project. Instead of spending my time on protocol plumbing, I could focus on the parts that actually matter: session management, command execution, state transitions, and debugger behavior.&lt;/p&gt;
&lt;p&gt;In other words, I automated the boring part so I could focus on the interesting part.&lt;/p&gt;
&lt;h2 id=&quot;step-3-wrap-windbg-through-dbgeng&quot;&gt;Step 3: Wrap WinDbg Through dbgeng&lt;/h2&gt;
&lt;p&gt;Once the protocol layer was under control, the next question was how to talk to the debugger engine itself.&lt;/p&gt;
&lt;p&gt;For that I went with &lt;code&gt;dbgeng&lt;/code&gt;, the Windows debugging engine behind the debugger family. That is where the real power is. It is also where some of the complexity is.&lt;/p&gt;
&lt;p&gt;On the package side, the current codebase still reflects some iteration. The wrapper layer currently leans on the public DbgEng interop exposed through the ClrMD packages &lt;code&gt;Microsoft.Diagnostics.Runtime&lt;/code&gt; and &lt;code&gt;Microsoft.Diagnostics.Runtime.Utilities&lt;/code&gt;. Separately, the broader adapter codebase also references &lt;code&gt;Microsoft.Debugging.Platform.DbgEng&lt;/code&gt; and &lt;code&gt;Microsoft.Debugging.Platform.DbgX&lt;/code&gt;, which are part of the newer Microsoft debugging platform stack. That split is real in the code today, but I do not want to pretend it is already the final architecture.&lt;/p&gt;
&lt;p&gt;In the wrapper itself, the core interfaces in use right now are &lt;code&gt;IDebugClient&lt;/code&gt;, &lt;code&gt;IDebugControl&lt;/code&gt;, &lt;code&gt;IDebugSymbols&lt;/code&gt;, and &lt;code&gt;IDebugSystemObjects&lt;/code&gt;. For callbacks, I register &lt;code&gt;IDebugEventCallbacks&lt;/code&gt; and &lt;code&gt;IDebugOutputCallbacks&lt;/code&gt;. That gives me the essential surface area I need to launch or attach, execute commands, inspect symbols, enumerate threads, and react to breakpoints, exceptions, exits, and debugger output.&lt;/p&gt;
&lt;p&gt;This wrapper layer became the core of the adapter. Its job was to expose the debugger in a way that fit the expectations of DAP rather than the expectations of a human typing commands into a debugger console.&lt;/p&gt;
&lt;p&gt;That means translating concepts like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Launching or attaching to a target&lt;/li&gt;
&lt;li&gt;Resuming and breaking execution&lt;/li&gt;
&lt;li&gt;Enumerating threads&lt;/li&gt;
&lt;li&gt;Building stack traces&lt;/li&gt;
&lt;li&gt;Reading locals and variables&lt;/li&gt;
&lt;li&gt;Handling modules and symbols&lt;/li&gt;
&lt;li&gt;Surfacing exceptions, exits, and other stop reasons&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have ever worked with debugger APIs, you know they do not hide much complexity. You need to be explicit. You need to think about ownership, state, timing, callbacks, and edge cases that often show up only once things are already going wrong.&lt;/p&gt;
&lt;p&gt;One small example was line stepping. I had already enabled source line support and saw source locations show up, so for a moment I thought &lt;code&gt;step over&lt;/code&gt; was working.&lt;/p&gt;
&lt;p&gt;It did not.&lt;/p&gt;
&lt;p&gt;What I had actually proven was that WinDbg could show me line information. That is not the same thing as telling it to do source-based stepping. I had forgotten to enable that part as well. The fix was one extra command:&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;c#&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt; EnableSourceLineSupport&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:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;	ThrowIfDisposed&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:#DCDCAA&quot;&gt;	ExecuteDebuggerCommand&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;.lines -e&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Could not enable source line support&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:#DCDCAA&quot;&gt;	ExecuteDebuggerCommand&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;l+t&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Could not enable source-based stepping&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:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That was a very debugger-adapter kind of bug. Everything looked correct for just long enough to be misleading.&lt;/p&gt;
&lt;h2 id=&quot;step-4-implement-the-real-requests-and-iterate&quot;&gt;Step 4: Implement the Real Requests and Iterate&lt;/h2&gt;
&lt;p&gt;With the generated protocol types on one side and the WinDbg wrapper on the other, I could finally work on the adapter loop itself.&lt;/p&gt;
&lt;p&gt;At this point, the adapter was useful for actual debugging.&lt;/p&gt;
&lt;p&gt;I began with the core requests: &lt;code&gt;initialize&lt;/code&gt;, &lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;attach&lt;/code&gt;, &lt;code&gt;setBreakpoints&lt;/code&gt;, &lt;code&gt;configurationDone&lt;/code&gt;, &lt;code&gt;threads&lt;/code&gt;, &lt;code&gt;stackTrace&lt;/code&gt;, &lt;code&gt;scopes&lt;/code&gt;, &lt;code&gt;variables&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, &lt;code&gt;pause&lt;/code&gt;, &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;stepIn&lt;/code&gt;, &lt;code&gt;stepOut&lt;/code&gt;, &lt;code&gt;disconnect&lt;/code&gt;, ...&lt;/p&gt;
&lt;p&gt;On paper that looks like a clean checklist. In reality, each of those requests is a conversation between at least three parties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VS Code and its expectations&lt;/li&gt;
&lt;li&gt;The adapter and its internal state machine&lt;/li&gt;
&lt;li&gt;The debugger engine and its current state&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the implementation loop looked roughly like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add one request&lt;/li&gt;
&lt;li&gt;Run it in VS Code&lt;/li&gt;
&lt;li&gt;Watch it fail in an interesting way&lt;/li&gt;
&lt;li&gt;Fix the translation layer&lt;/li&gt;
&lt;li&gt;Hit the next state mismatch&lt;/li&gt;
&lt;li&gt;Repeat until the experience works the way it should&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is also where you learn that &quot;technically works&quot; and &quot;feels right to use&quot; are not the same thing.&lt;/p&gt;
&lt;p&gt;It is not enough to answer the request. You have to answer it in the right order, at the right time, and with enough fidelity that the editor can build a coherent UI around it.&lt;/p&gt;
&lt;p&gt;That was one of the more interesting parts of the project.&lt;/p&gt;
&lt;p&gt;Here is a tiny slice of what that translation layer looks like today. After launch, the adapter records whether it should remain paused at entry or continue once VS Code finishes sending its setup messages:&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;c#&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;_launchAwaitingConfigurationDone&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&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;_launchStopAtEntry&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;DapArgumentReader&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;TryGetBoolean&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;arguments&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;stopAtEntry&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:#D4D4D4&quot;&gt;	?? &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;DapArgumentReader&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;TryGetBoolean&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;arguments&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;stopOnEntry&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:#D4D4D4&quot;&gt;	?? &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the kind of code that looks harmless until you realize it decides whether the whole session feels smooth or broken.&lt;/p&gt;
&lt;h2 id=&quot;when-it-worked&quot;&gt;When It Worked&lt;/h2&gt;
&lt;p&gt;At some point the pieces clicked together.&lt;/p&gt;
&lt;p&gt;I could launch a debugging session from VS Code, talk to WinDbg through the adapter, and use the editor as if this had always been a normal supported workflow.&lt;/p&gt;
&lt;p&gt;It also stopped being just about the original VM service scenario. Because the adapter sits on top of WinDbg, it opened the door to more than the first use case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Local launch and local attach already work in the adapter&lt;/li&gt;
&lt;li&gt;Dump-file attach is wired in&lt;/li&gt;
&lt;li&gt;Remote attach and kernel scenarios are the next serious end-to-end targets&lt;/li&gt;
&lt;li&gt;Crash dump debugging is now a realistic extension of the same architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That was the point where the project started to feel solid.&lt;/p&gt;
&lt;h2 id=&quot;why-this-was-fun&quot;&gt;Why This Was Fun&lt;/h2&gt;
&lt;p&gt;This was fun for the same reason good tooling work is always fun: it changes how you work.&lt;/p&gt;
&lt;p&gt;You remove friction once, then benefit from it every day after that. And along the way, you learn where the real product boundaries are. Visual Studio and VS Code may look adjacent from the outside, but their debugging plumbing is very different. Once that became clear, the path forward became clear too.&lt;/p&gt;
&lt;h2 id=&quot;what-i-learned&quot;&gt;What I Learned&lt;/h2&gt;
&lt;p&gt;This project taught me a few things very clearly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a workflow matters enough, it is often worth productizing it for yourself&lt;/li&gt;
&lt;li&gt;DAP is a really good abstraction for debugger integration&lt;/li&gt;
&lt;li&gt;Code generation is the right answer when a protocol brings lots of repetitive structure&lt;/li&gt;
&lt;li&gt;Debugger adapters are mostly about state, timing, and translation&lt;/li&gt;
&lt;li&gt;WinDbg becomes much more approachable when you put a good UX in front of it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also: if you think you fixed stepping, make sure you actually fixed it and did not just make the debugger show line numbers.&lt;/p&gt;
&lt;p&gt;Most importantly, I was reminded again that some of the best side projects start as practical attempts to make tomorrow less annoying than today.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;I only wanted a better remote debugging workflow for a service running in a VM.&lt;/p&gt;
&lt;p&gt;That turned into DAP, schema parsing, code generation, &lt;code&gt;dbgeng&lt;/code&gt;, and a long series of state-machine bugs.&lt;/p&gt;
&lt;p&gt;The result so far is a working first proof of concept: a WinDbg-backed debugger adapter for Visual Studio Code with local &lt;code&gt;launch&lt;/code&gt;, local attach, dump-file attach, stack traces, scopes, variables, breakpoints, and step commands working well enough to prove the architecture.&lt;/p&gt;
&lt;p&gt;That matters because it means I finally have a base I can build on. I have not implemented remote debugging or kernel debugging yet, but I now feel ready to take a real shot at both without getting lost in the basics again.&lt;/p&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;The next step is to use this base for the work I actually set out to do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Harden the current adapter and clean up rough edges in the state machine&lt;/li&gt;
&lt;li&gt;Start implementing the actual remote debugging flow for the VM scenario&lt;/li&gt;
&lt;li&gt;Take a first real implementation shot at kernel debugging too&lt;/li&gt;
&lt;li&gt;Keep the scope under control so the project does not drift again like it did at the start&lt;/li&gt;
&lt;li&gt;Open source the project once the foundation is stable enough&lt;/li&gt;
&lt;li&gt;Keep turning WinDbg power into something that feels normal inside VS Code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And yes, this all started with &quot;I just want to remote debug a service on a VM.&quot;&lt;/p&gt;
&lt;p&gt;That is usually how the best tools start.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 0.12.2</title>
        <published>2025-12-15T00:00:00+00:00</published>
        <updated>2025-12-15T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/mcp-windbg-0-12-2-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-0-12-2-release/</id>
        <summary type="html">Adding Prompts API support and streamable-http transport to mcp-windbg.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-0-12-2-release/">&lt;p&gt;I've just released version 0.12.2 of &lt;strong&gt;mcp-windbg&lt;/strong&gt;, bringing some significant enhancements that expand how and where you can perform crash dump analysis.&lt;/p&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;What's New&lt;/h2&gt;
&lt;p&gt;This release introduces two major features that address the flexibility and deployment needs many of you have been asking about.&lt;/p&gt;
&lt;p&gt;First up is support for the &lt;strong&gt;Prompts API&lt;/strong&gt;, which fundamentally changes how you can interact with crash dump analysis. Rather than being tied to a local setup, you can now trigger triage analysis from anywhere in your environment. The server can be deployed on any machine in your network, whether that's a dedicated analysis box, a build server, or even directly on a file server hosting your crash dumps. This means you can centralize your debugging infrastructure and access it from wherever you're working.&lt;/p&gt;
&lt;p&gt;Second, this release adds &lt;strong&gt;streamable-http&lt;/strong&gt; as an alternative transport backend. This gives you more options for how the server communicates, particularly useful in containerized or networked environments where different transport mechanisms might be preferable.&lt;/p&gt;
&lt;p&gt;The combination of these features means you can now set up a centralized crash analysis service that developers across your team can leverage without needing to install WinDbg or configure everything locally. Want to analyze dumps directly on the file server where they're stored? Now you can.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;If you want to try out the latest version, installation is straightforward:&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;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:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The project is open source and available on GitHub at &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;https://github.com/svnscha/mcp-windbg&lt;/a&gt;. If you find it useful, a star on the repository is always appreciated.&lt;/p&gt;
&lt;h2 id=&quot;a-real-world-example&quot;&gt;A Real-World Example&lt;/h2&gt;
&lt;p&gt;No release post would be complete without putting the tool to work on an actual crash dump. Here's an example of the analysis in action:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/screenshots/2025-12-15-mcp-windbg-copilot-crash.jpg&quot; alt=&quot;Crash Analysis&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Even Copilot needs a debugger sometimes.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 0.10.0</title>
        <published>2025-10-11T00:00:00+00:00</published>
        <updated>2025-10-11T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/mcp-windbg-0-10-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-0-10-0-release/</id>
        <summary type="html">AI-powered crash analysis gets a major upgrade with PyPI availability, live debugging sessions, and community-driven improvements. One-command installation is finally here.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-0-10-0-release/">&lt;h2 id=&quot;mcp-windbg-0100-now-available-on-pypi&quot;&gt;mcp-windbg 0.10.0: Now Available on PyPI&lt;/h2&gt;
&lt;p&gt;Five months after the initial release of &lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;mcp-windbg&lt;/a&gt;, I'm releasing version 0.10.0 with significant improvements and simplified deployment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;mcp-windbg is now officially available on &lt;a href=&quot;https://pypi.org/project/mcp-windbg/&quot;&gt;PyPI&lt;/a&gt;.&lt;/strong&gt; Installation no longer requires cloning repositories or setting up development environments:&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;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:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This represents a significant simplification from the original setup process described in &lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;my first article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Additionally, mcp-windbg is now listed on the &lt;a href=&quot;https://github.com/modelcontextprotocol/registry&quot;&gt;official Model Context Protocol registry&lt;/a&gt;, which should improve discoverability and enable integrations with various MCP-compatible tools.&lt;/p&gt;
&lt;h2 id=&quot;release-0100-key-features-and-improvements&quot;&gt;Release 0.10.0: Key Features and Improvements&lt;/h2&gt;
&lt;p&gt;Version 0.10.0 incorporates community feedback and focuses on improving usability across different experience levels with debugging tools.&lt;/p&gt;
&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Live Debugging Sessions&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added &lt;code&gt;open_windbg_remote&lt;/code&gt; and &lt;code&gt;close_windbg_remote&lt;/code&gt; functions&lt;/li&gt;
&lt;li&gt;Support for connecting to live processes beyond crash dump analysis&lt;/li&gt;
&lt;li&gt;Real-time debugging through conversational AI interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Extended Dump File Support&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full compatibility with &lt;code&gt;.mdmp&lt;/code&gt; and &lt;code&gt;.hdmp&lt;/code&gt; formats&lt;/li&gt;
&lt;li&gt;Microsoft Store WinDbg CDB compatibility&lt;/li&gt;
&lt;li&gt;Improved automatic discovery of crash dump files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Development Infrastructure&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Migrated to &lt;code&gt;uv&lt;/code&gt; package manager for improved build performance&lt;/li&gt;
&lt;li&gt;Significantly reduced development setup and build times&lt;/li&gt;
&lt;li&gt;Streamlined dependency management&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;community-contributions&quot;&gt;Community Contributions&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;@sooknarine&lt;/strong&gt; contributed several key improvements that made this release possible:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/svnscha/mcp-windbg/pull/6&quot;&gt;#6: Find local dumps with other common extensions&lt;/a&gt;&lt;/strong&gt; - Enhanced automatic discovery of crash dump files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/svnscha/mcp-windbg/pull/10&quot;&gt;#10: Add support for remote debugging&lt;/a&gt;&lt;/strong&gt; - Implemented live debugging session support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These contributions demonstrate the value of community involvement in open source development.&lt;/p&gt;
&lt;h3 id=&quot;infrastructure-improvements&quot;&gt;Infrastructure Improvements&lt;/h3&gt;
&lt;p&gt;Several behind-the-scenes improvements enhance reliability and maintainability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Continuous Integration&lt;/strong&gt;: Automated testing across Python versions 3.10 through 3.14&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependency Management&lt;/strong&gt;: Automated security updates and dependency maintenance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Release Process&lt;/strong&gt;: Streamlined deployment for faster delivery of updates&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;documentation-updates&quot;&gt;Documentation Updates&lt;/h3&gt;
&lt;p&gt;The documentation has been restructured for better usability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AGENTS.md&lt;/strong&gt;: Comprehensive debugging instructions specifically for AI assistants&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured Templates&lt;/strong&gt;: &lt;code&gt;.github/prompts/dump-triage.prompt.md&lt;/code&gt; for consistent crash analysis (inspired by my &lt;a href=&quot;/posts/howto-extend-copilot-with-prompt-files/&quot;&gt;prompt engineering article&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Repository Wiki&lt;/strong&gt;: All documentation now lives in an easily searchable wiki&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simplified README&lt;/strong&gt;: Focused on getting you started in minutes, not hours&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;This Changelog&lt;/strong&gt;: So you know what's changing and why&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;installation-from-tedious-to-trivial&quot;&gt;Installation: From Tedious to Trivial&lt;/h2&gt;
&lt;p&gt;Remember the old installation process? Clone, setup virtual environment, install dependencies, configure paths... ugh.&lt;/p&gt;
&lt;p&gt;Here's the new process:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;# Install mcp-windbg&lt;/span&gt;&lt;/span&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:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;# That's it. Seriously.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add this to your &lt;code&gt;.vscode/mcp.json&lt;/code&gt;:&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;python&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;args&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:#CE9178&quot;&gt;				&quot;-m&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:#CE9178&quot;&gt;				&quot;mcp_windbg&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:#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 installation process is now considerably simplified compared to the previous manual setup requirements.&lt;/p&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;With 0.10.0 released, these are the next areas I plan to work on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More AI integrations&lt;/strong&gt; beyond VS Code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced live debugging capabilities&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance optimizations&lt;/strong&gt; for large dump files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Community-requested features&lt;/strong&gt; (keep them coming!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The development roadmap will continue to incorporate community feedback and feature requests.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;To begin using mcp-windbg 0.10.0:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Install&lt;/strong&gt;: &lt;code&gt;pip install mcp-windbg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure&lt;/strong&gt;: Add the MCP server to your VS Code configuration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use&lt;/strong&gt;: Load crash dumps and interact through natural language queries&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contribute&lt;/strong&gt;: Report issues, suggest features, or contribute code improvements&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pypi.org/project/mcp-windbg/&quot;&gt;PyPI Package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/registry&quot;&gt;MCP Registry Listing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;Article: AI Meets WinDbg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/howto-extend-copilot-with-prompt-files/&quot;&gt;Article: Prompt Engineering with Copilot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;community-response-and-impact&quot;&gt;Community Response and Impact&lt;/h2&gt;
&lt;p&gt;Since the initial release in May, the project has received significant community engagement. The &lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;original article&lt;/a&gt; generated over 40,000 page views within the first two days, along with thousands of LinkedIn impressions and direct messages from developers worldwide.&lt;/p&gt;
&lt;p&gt;The feedback has been constructive and encouraging. Developers have shared how the tool helped reduce time spent on crash analysis, and several teams have integrated it into their debugging workflows. I've had opportunities to present this work both internally and externally, leading to valuable discussions about AI-assisted development tools.&lt;/p&gt;
&lt;p&gt;The open source community response has been particularly gratifying. Contributors like &lt;a href=&quot;https://github.com/sooknarine&quot;&gt;@sooknarine&lt;/a&gt; have stepped in to add functionality that benefits all users. The GitHub repository has gained considerable attention, and the project's inclusion in the official MCP registry should further improve its discoverability.&lt;/p&gt;
&lt;p&gt;Building something that genuinely helps other developers solve real problems has been rewarding beyond what I expected when I first started working on this as a way to improve my own debugging workflow.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Thanks to everyone who has contributed, shared feedback, or simply tried the tool. The community response has made this project much better than it would have been otherwise.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>AI Meets WinDBG: A Different Way to Analyze Crashes</title>
        <published>2025-05-04T00:00:00+00:00</published>
        <updated>2025-05-04T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/ai-meets-windbg/"/>
        <id>https://svnscha.de/posts/ai-meets-windbg/</id>
        <summary type="html">Because manually squinting at hex dumps is so last century. Let me show you how AI-assisted debugging is leaving WinDBG's command line in the dust.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/ai-meets-windbg/">&lt;h2 id=&quot;old-meets-new-bringing-crash-analysis-into-2025&quot;&gt;Old Meets New: Bringing Crash Analysis into 2025&lt;/h2&gt;
&lt;p&gt;Let's face it - while the rest of software development has evolved at warp speed, crash dump analysis feels like it's been preserved in digital amber for decades. We've got self-driving cars and pocket-sized supercomputers, yet here we are, still pecking away at command prompts like it's the dawn of the internet. Why is debugging the only area where we cling to tools that look like they belong in a computer history museum?&lt;/p&gt;
&lt;p&gt;Picture this: You, a professional software engineer in 2025, hunched over a terminal, manually typing arcane commands like &lt;code&gt;!analyze -v&lt;/code&gt; and &lt;code&gt;.ecxr&lt;/code&gt;, squinting at hexadecimal memory addresses, and mentally translating stack traces. All while your friends in other industries are delegating their work to AI assistants that can write entire documents, create art, or automate complex workflows.&lt;/p&gt;
&lt;p&gt;Something's wrong with this picture, right?&lt;/p&gt;
&lt;p&gt;I wanted a simpler workflow: ask questions in plain language and let an AI assistant run the relevant debugger commands. This is more than a new interface for WinDBG; it changes how you interact with the debugger.&lt;/p&gt;
&lt;h2 id=&quot;when-inspiration-strikes&quot;&gt;When Inspiration Strikes&lt;/h2&gt;
&lt;p&gt;During a debugging session at work, I had one of those lightning bolt moments. What if - and stick with me here - we could apply the same AI-assisted &quot;vibe coding&quot; approach to crash dump analysis?&lt;/p&gt;
&lt;p&gt;Picture this: instead of manually slogging through memory dumps and command outputs, you simply ask, &quot;Hey, why did this application crash?&quot; and get an intelligent, contextual answer that actually helps you solve the problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The idea was too compelling not to pursue. So I built it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;see-it-in-action-ai-powered-crash-analysis&quot;&gt;See It In Action: AI-Powered Crash Analysis&lt;/h2&gt;
&lt;p&gt;Before diving into the technical details, let me show you what this looks like in practice. I have prepared a demo application to showcase two different use cases:&lt;/p&gt;
&lt;h3 id=&quot;video-1-crash-analysis-and-automated-bugfix&quot;&gt;Video 1: Crash Analysis and Automated Bugfix&lt;/h3&gt;
&lt;p&gt;In this video, I show how Copilot can analyze a crash dump, identify the bug and auto-fix the issue.&lt;/p&gt;
&lt;video class=&quot;cast&quot; src=&quot;/casts/2025-05-03-CrashDump1.webm&quot; controls&gt;
  Your browser does not support the video tag.
&lt;/video&gt;
&lt;p&gt;As you can see in the video, instead of manually running WinDBG commands and interpreting the cryptic output, I'm having a natural conversation with GitHub Copilot. The AI quickly identifies that the application crashed, explains which specific conditions led to the crash, and suggests a fix.&lt;/p&gt;
&lt;h3 id=&quot;video-2-automated-crash-dump-analysis-of-multiple-crash-dump-files&quot;&gt;Video 2: Automated Crash Dump Analysis of multiple crash dump files&lt;/h3&gt;
&lt;p&gt;This video demonstrates a different capability: analyzing multiple crash dump files at once. It shows how the tool can quickly identify which dumps belong to your application and which don't.&lt;/p&gt;
&lt;video class=&quot;cast&quot; src=&quot;/casts/2025-05-03-CrashDump2.webm&quot; controls&gt;
  Your browser does not support the video tag.
&lt;/video&gt;
&lt;p&gt;Worth noting, it takes just a few seconds until you get your first useful answer. I've played around with this for many hours and let me tell you one thing: You can really go deep. If you ask the right questions, the AI runs WinDBG/CDB commands that I haven't seen in all these years of debugging, and that is simply amazing.&lt;/p&gt;
&lt;h2 id=&quot;how-can-this-help-the-industry&quot;&gt;How can this help the industry?&lt;/h2&gt;
&lt;p&gt;I believe this is one of the really good examples of how AI can boost productivity. Analyzing crash dumps is a very tedious task. It begins with quickly checking and identifying whether crashes are the same or different, and often requires very advanced knowledge when a crash is challenging - really challenging.&lt;/p&gt;
&lt;p&gt;Copilot can help here tremendously; it knows how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interpret assembly code (without you having to remember what EAX stands for)&lt;/li&gt;
&lt;li&gt;Check memory contents (so you don't have to count hex bytes on your fingers)&lt;/li&gt;
&lt;li&gt;Traverse structures with symbols (goodbye to manual pointer arithmetic!)&lt;/li&gt;
&lt;li&gt;And so much more&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This can help engineers, support teams, and QA staff work with crash dumps without memorizing every debugger command.&lt;/p&gt;
&lt;h2 id=&quot;how-did-i-build-this&quot;&gt;How did I build this?&lt;/h2&gt;
&lt;p&gt;If you've ever worked with WinDBG, you know the drill: cryptic commands, obscure syntax, and endless scrolling through memory addresses and stack traces that make your eyes glaze over. It's the kind of specialized knowledge that takes years to master and feels like speaking an alien language even when you do.&lt;/p&gt;
&lt;p&gt;The trick here is connecting WinDBG with AI. To do that, you first need to programmatically control a debugging session, right? There are plenty of options on how to do this. I prefer to keep things simple, so I have chosen &lt;a href=&quot;https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-using-cdb-and-ntsd&quot;&gt;CDB&lt;/a&gt;, which is Microsoft's Console Debugger. It operates on standard input and output, and that's so much more fun to deal with than setting up COM APIs or similar approaches.&lt;/p&gt;
&lt;p&gt;The second part is &quot;connecting with AI.&quot; That's where Model Context Protocol Servers come into the game.&lt;/p&gt;
&lt;h2 id=&quot;understanding-model-context-protocol-servers&quot;&gt;Understanding Model Context Protocol Servers&lt;/h2&gt;
&lt;p&gt;MCP is an open standard developed by Anthropic, released in November 2024. This protocol allows AI models to interact with external tools and data sources - think of it as giving AI assistants &quot;hands&quot; to work with other software. It defines a way for AI assistants to discover, access, and use tools through a consistent interface. In essence, it's what allows GitHub Copilot to &quot;talk&quot; to external programs like WinDBG.&lt;/p&gt;
&lt;p&gt;An MCP server acts as the intermediary between the AI model and the tool. It:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Registers available tools with the client&lt;/li&gt;
&lt;li&gt;Handles requests from AI models to use these tools&lt;/li&gt;
&lt;li&gt;Executes the tool operations and returns results&lt;/li&gt;
&lt;li&gt;Maintains context across interactions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Any tool can be made available to an AI model through an MCP server. I built one for WinDBG's CDB debugger.&lt;/p&gt;
&lt;h3 id=&quot;why-mcp-instead-of-languagemodeltool-api&quot;&gt;Why MCP Instead of LanguageModelTool API?&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://code.visualstudio.com/api/extension-guides/tools&quot;&gt;LanguageModelTool API&lt;/a&gt; might eventually be a better fit for this specific use-case. Creating a Visual Studio Extension that &quot;just works&quot; out of the box would potentially simplify the integration process significantly.&lt;/p&gt;
&lt;p&gt;However, using MCP directly offers several notable advantages. It works with any AI model, not just limiting itself to Copilot. The server can be used outside VS Code, functioning with various other tools. New features can be easily added without necessitating changes to the core integration. Moreover, it remains platform-independent, avoiding lock-in to any single company's implementation.&lt;/p&gt;
&lt;h2 id=&quot;the-mcp-windbg-project&quot;&gt;The MCP-WinDBG Project&lt;/h2&gt;
&lt;p&gt;I've implemented a &lt;a href=&quot;https://www.anthropic.com/news/model-context-protocol&quot;&gt;Model Context Protocol&lt;/a&gt; server that wraps WinDBG/CDB and exposes its capabilities to AI models within VS Code. Better yet, I've made it open source so everyone can experience this new workflow.&lt;/p&gt;
&lt;p&gt;The project, &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;mcp-windbg&lt;/a&gt;, connects VS Code and GitHub Copilot to WinDBG's analysis commands.&lt;/p&gt;
&lt;p&gt;The actual &quot;hard part&quot; was implementing the CDB (Command-Line WinDBG) interaction layer. And by &quot;hard&quot;, I mean vibe-coding with two coffees on a Saturday morning, where I spent more time being annoyed by pyTest failures than actual coding difficulties. The core implementation came together surprisingly quickly!&lt;/p&gt;
&lt;p&gt;The rest is primarily wrapper code that implements the Model Context Protocol specifications. Now that I've established and defined the core WinDBG interaction logic, I'm considering refactoring the project to TypeScript. This would enable me to create both an MCP Server in TypeScript and a dedicated Visual Studio Extension, with both implementations leveraging the same underlying CDB interaction layer.&lt;/p&gt;
&lt;h2 id=&quot;what-does-this-mean-in-practice&quot;&gt;What Does This Mean In Practice?&lt;/h2&gt;
&lt;p&gt;Let me walk you through what this enables:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Natural language crash analysis&lt;/strong&gt;: &quot;Why is this application crashing with an access violation at this address?&quot; (Instead of: &quot;What the $%#@ is this heap corruption!?&quot;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Contextual debugging&lt;/strong&gt;: &quot;Show me the stack trace for thread 5 and explain what each function is doing based on the symbols.&quot; (Instead of staring at call stacks like they're ancient hieroglyphics)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Root cause identification&lt;/strong&gt;: &quot;What's causing this null pointer dereference and where should I look in the code to fix it?&quot; (Instead of playing detective with memory addresses)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Instead of typing obscure commands like &lt;code&gt;!analyze -v&lt;/code&gt; followed by a series of manual investigations, you simply ask questions in plain language, and the AI interprets the crash data for you. It's like having a WinDBG expert whispering in your ear, except it doesn't get annoyed when you ask the same question five times.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;p&gt;The MCP server connects GitHub Copilot to WinDBG:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It provides a set of tools that Copilot can use to interact with crash dumps&lt;/li&gt;
&lt;li&gt;It translates natural language questions into appropriate WinDBG commands&lt;/li&gt;
&lt;li&gt;It parses and interprets the often cryptic WinDBG output into more useful information&lt;/li&gt;
&lt;li&gt;It maintains context throughout a debugging session, enabling follow-up questions to work naturally&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The technical implementation uses Python to spawn and communicate with CDB (the command-line version of WinDBG), parses the output, and exposes the functionality through the Model Context Protocol to VS Code.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-with-mcp-windbg&quot;&gt;Getting Started With mcp-windbg&lt;/h2&gt;
&lt;p&gt;Ready to try it yourself? Here's how to get started:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, make sure you have the Windows SDK installed with Debugging Tools for Windows&lt;/li&gt;
&lt;li&gt;Clone the repository: &lt;code&gt;git clone https://github.com/svnscha/mcp-windbg.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set up a Python virtual environment and install the package&lt;/li&gt;
&lt;li&gt;Configure VS Code to use the MCP server&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For complete details, check out the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository README&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once configured, create a &lt;code&gt;.vscode/mcp.json&lt;/code&gt; file in your project that points to the server:&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_server_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;python&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;args&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:#CE9178&quot;&gt;                &quot;-m&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:#CE9178&quot;&gt;                &quot;mcp_server_windbg&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:#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;You might need to update the command, depending on where and how you have installed the mcp_server_windbg to.&lt;/p&gt;
&lt;h2 id=&quot;the-human-touch-still-matters&quot;&gt;The Human Touch Still Matters&lt;/h2&gt;
&lt;p&gt;Just like with &lt;a href=&quot;/posts/vscode-vibe-coding/&quot;&gt;code refactoring&lt;/a&gt;, the AI assistance isn't perfect. The human element - your experience, intuition, and domain knowledge - remains crucial. Sometimes you'll need to guide the analysis, ask follow-up questions, or provide additional context.&lt;/p&gt;
&lt;p&gt;The useful part is the combination: AI can process a large amount of debugger output quickly, while you provide the context needed to judge the result. It still needs supervision and can follow the wrong lead, so treat its findings as a starting point rather than a final answer.&lt;/p&gt;
&lt;h2 id=&quot;join-the-experience&quot;&gt;Join The Experience&lt;/h2&gt;
&lt;p&gt;I'd love for you to try this out, contribute to the project, and share your experiences. If you're interested:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Try it on your own crash dumps&lt;/li&gt;
&lt;li&gt;Report issues, suggest improvements, or contribute code&lt;/li&gt;
&lt;li&gt;Share your success stories (or even failures - we learn from those too!)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;the-magic-is-in-the-flow&quot;&gt;The Magic Is In The Flow&lt;/h2&gt;
&lt;p&gt;Just like with my code refactoring experience, the real magic isn't about any single capability - it's about the flow. When debugging stops being a tedious chore and becomes a fluid conversation, something fundamentally changes in how you approach problem-solving.&lt;/p&gt;
&lt;p&gt;Gone are the days of dreading crash analysis. Instead, each debugging session becomes an opportunity for collaboration with an AI partner that helps you understand what's happening at a deeper level.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Crash dump analysis has traditionally been one of the most technically demanding and least enjoyable parts of software development. It's like archaeology with a keyboard - painstakingly excavating through layers of memory and CPU state to unearth what went wrong. With AI assistance through tools like mcp-windbg, it becomes another area where we can experience that perfect &quot;vibe state&quot; of frictionless problem-solving.&lt;/p&gt;
&lt;p&gt;If you're still manually typing WinDBG commands and squinting at memory dumps in 2025, you're not just missing out on productivity - you're missing out on a fundamentally more enjoyable way to work.&lt;/p&gt;
&lt;p&gt;Try it. Debug it. Vibe it.&lt;/p&gt;
</content>
    </entry>
</feed>
