Skip to content
Agentmart
Submit a tool

CLAUDE.md · svnscha/mcp-windbg

CLAUDE.md from svnscha/mcp-windbg: 289 lines covering Build / test / run, Layout, Conventions, Versioning and release and more.

Template by svnscha

IndexedMIT★ 1,632
Write a review

Install

Works with Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/svnscha/mcp-windbg/develop/CLAUDE.md -o CLAUDE.md

Read it and adapt it to your project before use.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The CLAUDE.md file that svnscha/mcp-windbg (1,632 stars) keeps for coding agents. It has 289 lines in 5 sections: Build / test / run; Layout; Conventions; Versioning and release; Docs. Use it as a model for your own project's instructions.

Use cases: debugging, code-generation

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

A CLAUDE.md file: project memory Claude Code loads at the start of every session.

For
Claude Code
Length
289 lines
File
CLAUDE.md

Sections

  1. Build / test / run
  2. Layout
  3. Conventions
  4. Versioning and release
  5. Docs

First lines (shown under the repo's MIT license)

# mcp-windbg

A [Model Context Protocol](https://modelcontextprotocol.io/) server that lets AI models
analyze Windows crash dumps and drive live or remote debugging through WinDbg/CDB. It is a
Python wrapper around `cdb.exe`: the model calls MCP tools, the server runs the matching
debugger commands and returns the text output. Windows-only (needs CDB). The single entry
point is `mcp-windbg`, which speaks MCP over stdio or streamable-http.

## Build / test / run

Python 3.10+ with the `uv` package manager. CDB must be installed for the live tests (WinDbg
from the Microsoft Store, or the Windows SDK).

```powershell
uv sync --dev                                                       # install incl. dev deps
uv run pytest src/mcp_windbg/tests/ -v                             # full test suite
uv run pytest src/mcp_windbg/tests/ -v -m "not live"              # hermetic subset (no CDB)
uv run python -m mcp_windbg --verbose                              # run the server (stdio)
uv run python -m mcp_windbg --transport streamable-http --port 8000   # HTTP transport
pwsh scripts/Switch-McpWindbg.ps1 Local       # Claude Code in this checkout: use the working copy
pwsh scripts/Switch-McpWindbg.ps1 Released    # back to the published plugins, updated
```

### Signing releases

The isolated `sign` job reads `SIGNING_URL` and `SIGNING_API_KEY` through its environment.
The API key is a repository Actions secret, separate from the hardware PIN; the `signing`
environment must not shadow it with an older value. A missing key or HTTP failure stops the
job before a signed artifact is uploaded. `release-please.yml` forwards secrets with
`secrets: inherit`; reusable callers must also supply `SIGNING_API_KEY`.

For acceptance, dispatch `publish-mcp.yml` on `develop` with `rehearsal=true` and leave `tag`
empty. This signs and verifies the binary and runs its Windows scenarios, without publishing
to PyPI or attaching a release asset. Keep the signing job free of checkouts and write tokens.

### Standalone binary

`scripts/Build-Exe.ps1` freezes the checkout into `dist/mcp-windbg.exe` with PyInstaller, for
users who want nothing to do with Python. It carries its own interpreter and every dependency;
it does not carry `cdb.exe`, which stays a prerequisite.

```powershell
uv sync --dev --group dist              # pyinstaller lives in the dist group, not dev
pwsh scripts/Build-Exe.ps1              # -> dist/mcp-windbg.exe, with SHA256
pwsh scripts/Build-Exe.ps1 -Verify      # build, then run the scenarios against the binary
```

**Importing cleanly is not the test.** A frozen build only ships the modules PyInstaller's
static analysis saw, so a dependency that imports lazily or reads a data file at runtime fails
at the tool call, not at startup. `MCP_WINDBG_SERVER_EXE` points the e2e harness at a built
binary, so the whole scenario suite re-runs against it with the same assertions and a different
launcher. That is what `-Verify` does, and what the `exe` job in `build-and-test.yml` runs on
every PR. Set the variable by hand to drive a downloaded release asset the same way.

Two consequences of freezing worth knowing:

- `prompts/*.prompt.md` are read through `Path(__file__).parent`, which resolves inside the
  unpacked bundle. They are laid down there by `--add-data`, so moving or adding a prompt file
  means the build has to lay it down too, or `load_prompt` raises only in the binary.
- `--filter-script` still loads and runs, but it imports against the bundled standard library,
  which is the subset the analysis pulled in - `sqlite3`, `xml.etree` and `tkinter` are not in
  it. A filter script that needs more than the exe happens to carry wants the pip or uvx
  install instead.

### Coverage

The code under test runs in **two** processes, and both must be measured or the number lies:

- the hosted server subprocess, where tool dispatch executes. Set `MCP_WINDBG_COVERAGE` so the
  harness launches it under `coverage run --parallel-mode`.
- the pytest process itself, where the hermetic unit tests (`tests/test_*.py`) run. This needs
  `coverage run -m pytest`, not plain `pytest`. Miss this and every unit test reads as dead
  code: that is how `kd_session.py` once reported 34% while fully tested.

Both write parallel-mode data files that `coverage combine` merges:

```powershell
uv run coverage erase
$env:MCP_WINDBG_COVERAGE = "1"
uv run coverage run -m pytest src/mcp_windbg/tests/     # measures pytest AND the server
$env:MCP_WINDBG_COVERAGE = $null
uv run coverage combine                 # merge the per-process .coverage.* files
uv run coverage report                  # or: uv run coverage html  ->  htmlcov/
```

CI runs exactly this and gates on `--fail-under=88`. To reproduce CI's number, leave
`MCP_WINDBG_KERNEL_CONNECTION` unset so the kernel scenarios skip as they do there. Run it with
the variable set for the honest local number, which covers `kd_session.py` against a real
target rather than a fake process.

### Test suite

The suite is a declarative end-to-end harness: each `tests/scenarios/*.yaml` file is run
against a real `python -m mcp_windbg` server hosted over stdio and driven by a real MCP client
(only the LLM is faked, by the scripted tool calls). Scenarios that need a debugger carry the
`live` (and `remote` / `kernel`) marker and `pytest.skip` cleanly when `cdb.exe` or `kd.exe` is
absent, so `-m "not live"` always runs and stays green off-Windows. See
`src/mcp_windbg/tests/e2e/README.md` for the scenario format. Test dumps are ordinary files in
`src/mcp_windbg/tests/dumps/` (Git LFS was removed in #20). `.gitignore` excludes every other
`*.dmp`, so a new fixture is added deliberately: check it for sensitive data first, then list it
there.

**Kernel scenarios.** `kernel_dump.yaml` opens a committed kernel minidump and needs only
`kd.exe`, so it runs in CI. `kernel_session.yaml` drives a real kernel target through `kd.exe`. CI has
no target machine, so it skips there; locally, point it at a debuggable VM or box and it runs:

```powershell
$env:MCP_WINDBG_KERNEL_CONNECTION = "net:port=50005,key=1.2.3.4"   # the -k connection string
uv run pytest src/mcp_windbg/tests/ -m kernel -v
```

Kernel code paths that CI cannot reach are held up by the hermetic fake-`kd.exe` tests in
`tests/test_kd_session.py`. Treat those as the CI floor, not as proof the feature works: before
shipping a kernel change, run the `kernel` marker against a real target.

## Layout

```
src/mcp_windbg/
  __init__.py        main(): CLI argument parsing, picks the transport
  __main__.py        module entry point
  server.py          MCP server: session lifecycle + call_tool dispatch
  server_api.py      Tool param models + list_tools + packaged prompt handlers
  cdb_session.py     CDBSession: spawns cdb.exe, sends commands, reads output
  filter_script.py   --filter-script loader and tool content hooks
  prompts/           prompt templates (dump-triage.prompt.md)
  tests/             e2e harness: e2e/ (runner + harness), scenarios/*.yaml, dumps/
scripts/             check-version-consistency.ps1, validate-server-schema.py, Format-Docs.ps1,
                     Switch-McpWindbg.ps1, Build-Exe.ps1
examples/            small C++ programs that crash, for generating test dumps
docs/                MkDocs user guide (Material), deployed to GitHub Pages
.github/workflows/   ci.yml -> build-and-test.yml (tests), publish-mcp.yml (PyPI on v* tags),
                     pages.yml (docs deploy)
pyproject.toml       project + dependency config         server.json   MCP registry manifest
```

## Conventions

Topic-scoped conventions live in `.claude/rules/` and load automatically when you read a
matching file:

- `markdown.md` - Markdown typography for every `*.md`: plain hyphens (no em/en dashes), no
  emojis. Run `pwsh scripts/Format-Docs.ps1`. (`**/*.md`)
- `documentation.md` - authoring style for the `docs/` user guide (scenario-first, link to
  the reference, sentence-case). (`docs/**`)

Tool and CLI facts come from `src/mcp_windbg/server_api.py` (tool schemas) and
`src/mcp_windbg/__init__.py` (command-line options). Keep `docs/reference/` in sync with them.

**The plugin has two names, and they do different jobs.** The marketplace entry in
`.claude-plugin/marketplace.json` is named `mcp-windbg-uvx` - that is the install identity, so
the command is `/plugin install mcp-windbg-uvx@mcp-windbg`, and it is what the plugin cache
directory is named after. The `name` in `plugins/mcp-windbg/.claude-plugin/plugin.json` stays
`mcp-windbg`, and that is what its MCP tools are scoped by:
`mcp__plugin_mcp-windbg_mcp-windbg__<tool>`, whatever the entry is called.

That split is deliberate. It lets a second entry ship the same plugin a different way -
`mcp-windbg-native` for a bundled binary, `mcp-windbg-pipx` for `pipx run` - while every variant
keeps identical tool names and one set of documentation. Change `plugin.json`'s name
and you rename its tools with it.

Signals

Stars
1,632
Forks
164
Open issues
0
Contributors
13
Last commit (this folder)
Oct 23, 2026 (6 days ago)
Last release
Oct 23, 2026 (6 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from svnscha

Cite this page

CLAUDE.md · svnscha/mcp-windbg. Agent Mart. https://agentmart.dev/templates/svnscha-mcp-windbg-claude-md (last updated 2026-10-24)