Skip to main content
Glama
windows-debug-mcp

windows-debug-mcp

by emyk

windows-debug-mcp

A read-only MCP server for diagnosing Windows crashes, stability problems and gaming performance.

It reads event logs, crash dumps, error reports, hardware and driver inventory, performance counters, power configuration and the registry settings that matter for games — and it has no code that can change any of them.

The read-only guarantee

This is the whole design constraint, so it is enforced in four independent layers rather than by convention:

  1. No mutating code exists. The package never imports a write API. Files are opened in binary-read mode, registry keys with KEY_READ, and processes are spawned with a fixed argument vector and shell=False.

  2. No passthrough. No tool accepts a command, script or argument that is executed as code. Every PowerShell fragment that runs ships inside the package; caller-supplied values are passed to it as JSON in an environment variable and are only ever used as values.

  3. Allowlisted cmdlets. Before a script runs it is parsed and rejected unless every cmdlet in it is on a read-only allowlist. External executables are checked including their arguments — powercfg /query is allowed, powercfg /setactive is not.

  4. Deny patterns. A final scan rejects redirection, Invoke-Expression, Add-Type, .Delete(), reg add, shell escapes and environment mutation, even if they would otherwise slip past the allowlist.

Layers 3 and 4 run on every invocation, so a script edited on disk after installation is still rejected.

You do not have to take this on faith. The verify_read_only_guarantees tool scans the installed source and reports what it found:

> verify_read_only_guarantees
{
  "clean": true,
  "summary": "No write APIs, mutating cmdlets or shell escapes found in the installed source.",
  "findings": []
}

The same audit runs as a test (tests/test_safety.py), along with about forty cases asserting that mutating scripts and commands are refused.

Related MCP server: Linux MCP Server

Install

Requires Python 3.10+ on Windows 10 or 11.

git clone https://github.com/emyk/windows-mcp
cd windows-mcp
pip install .

Then register it with your MCP client. For Claude Desktop (%APPDATA%\Claude\claude_desktop_config.json) or Claude Code (.mcp.json):

{
  "mcpServers": {
    "windows-debug": {
      "command": "windows-debug-mcp"
    }
  }
}

Or without installing, using uv:

{
  "mcpServers": {
    "windows-debug": {
      "command": "uvx",
      "args": ["--from", "C:\\path\\to\\windows-mcp", "windows-debug-mcp"]
    }
  }
}

Run unelevated unless you need the Security event log or bcdedit output — everything else works as a normal user.

Tools

Crashes and the event log

Tool

What it gives you

get_crash_history

Every critical and error event from the System and Application logs over a window, with the known ones explained: bug checks, unexpected restarts, WHEA hardware errors, display driver resets, disk and NTFS errors, application crashes and hangs

query_event_log

Any log, filtered by time, severity, event ID, provider or message text

list_event_logs

Which logs exist and how many records they hold

list_crash_dumps

Kernel minidumps, MEMORY.DMP, live kernel reports and application dumps

inspect_crash_dump

Parses the dump header. For a kernel dump: the stop code, its four parameters and what they mean. For an application dump: the exception code, the faulting address and the module that address belongs to

list_error_reports / read_error_report

Windows Error Reporting entries — the faulting app, module, offset and exception code, which survive even when no dump was kept

get_pagefile_and_dump_settings

Why a dump was never written

get_reliability_history

The data behind Reliability Monitor

get_boot_performance

Boot and shutdown timings, and what specifically slowed them

inspect_crash_dump reads only header structures, so it returns in milliseconds even on a multi-gigabyte MEMORY.DMP. It also flags overlay and anti-cheat modules loaded into a crashed process — Steam overlay, Discord, RivaTuner, ShadowPlay, EAC, BattlEye and friends — because "disable the overlay" resolves a large share of game crashes.

Hardware and drivers

get_system_overview, get_gpu_info, get_display_info, get_memory_modules, get_storage_health, list_drivers, list_problem_devices, get_temperatures.

get_memory_modules calls out modules running below their rated speed or at mismatched speeds — the usual explanation for MEMORY_MANAGEMENT and WHEA_UNCORRECTABLE_ERROR. get_storage_health returns wear level, power-on hours and read errors from the drive's own reliability counters. list_problem_devices decodes Device Manager codes, so a GPU that has fallen over reads as "Code 43: Windows stopped this device because it reported problems" rather than as a number.

Performance

get_performance_snapshot, list_processes, get_startup_programs, list_services, get_power_configuration, get_sleep_states, get_network_configuration.

The performance snapshot reports the numbers that explain stutter rather than throughput: DPC and interrupt time, processor queue length, hard page faults, disk queue depth and per-engine GPU utilisation. Counters are read through the locale-independent CIM classes, so it works on non-English installations where counter paths are translated.

Settings

get_gaming_settings, get_per_application_graphics_settings, get_security_mitigations, get_installed_software, get_windows_updates, read_registry_key, read_registry_value.

get_gaming_settings covers Game Mode, Game Bar and background recording, hardware-accelerated GPU scheduling, multiplane overlay, TdrDelay, variable refresh rate and Auto HDR, the multimedia scheduler's reservations, Win32PrioritySeparation and power throttling. Each value is explained, and "not set" is distinguished from "set to zero" — most of these keys are absent by default, so the difference matters.

get_security_mitigations reports VBS, memory integrity (HVCI) and the speculative-execution mitigation overrides, which is where "everything got slower after an update" usually leads.

Meta

collect_diagnostic_snapshot runs the common starting set in one call, with each section independent so one unavailable data source does not lose the rest. verify_read_only_guarantees audits the server's own source. get_server_status reports whether the Windows data sources are reachable.

Two prompts, diagnose_blue_screen and diagnose_game_stutter, lay out an investigation order.

What it deliberately does not do

  • It cannot change anything. When a setting should change, it tells you which one and leaves you to apply it.

  • No stack analysis. Reading the call stack out of a dump needs WinDbg and symbol resolution. This server gives you the stop code, the parameters and the faulting module, which is usually enough to know where to look next.

  • Win32_Product is never enumerated. Doing so triggers an MSI consistency check that can reconfigure installed products, which would not be read-only. Installed software is read from the uninstall registry keys instead.

  • No tracing. Starting an ETW session is a write, so boot and shutdown timings come from the logs Windows already keeps.

  • Environment variables are not exposed, since they routinely carry tokens.

Development

pip install -e ".[dev]"
pytest

The test suite runs on any platform: the Windows-only paths are exercised through synthetic dumps and error reports, and the read-only guard is tested directly.

Licence

MIT

Available Tools

35 tools
collect_diagnostic_snapshotA

One call that gathers the usual starting point for a diagnosis.

System overview, GPU and drivers, memory modules, storage health, problem devices, crash dumps present, recent critical events, the gaming settings and a performance sample — each section independent, so one unavailable data source does not lose the rest.

Follow up with the specific tools for whatever looks wrong.

Inputs: days. Returns: result

get_boot_performanceA

Boot and shutdown timings, plus what specifically slowed them down.

Windows measures every boot and records which applications, services and drivers took longer than expected. Slow boots almost always have a named culprit here.

Inputs: max_events. Returns: result

get_crash_historyA

Every critical and error event from the System and Application logs, explained.

This is the right first call for "why did my PC crash". It picks up bug checks, unexpected restarts, WHEA hardware errors, display driver resets, disk and file system errors, application crashes and hangs, then labels the ones with a known meaning.

Args: days: How far back to scan. max_events: Maximum events per log. include_noise: Keep entries that are known to be harmless (DCOM 10016).

Inputs: days, max_events, include_noise. Returns: result

get_display_infoA

Connected monitors and the resolution and refresh rate each is being driven at.

A monitor running at 60 Hz when it supports more, or a mismatch between monitors, explains a lot of reported "stutter".

Inputs: no named parameters. Returns: result

get_gaming_settingsA

The Windows settings that affect games, read from the registry.

Game Mode, Game Bar and background recording, hardware-accelerated GPU scheduling, multiplane overlay, the display driver timeout, variable refresh rate and Auto HDR, the multimedia scheduler's reservations, CPU quantum and power throttling — with each value explained and "not set" distinguished from "set to zero".

Inputs: no named parameters. Returns: result

get_gpu_infoA

Graphics adapters, driver versions and dates, VRAM and the current display mode.

The driver version and date are the first thing to check against a VIDEO_TDR_FAILURE or a game that crashes on launch.

Inputs: no named parameters. Returns: result

get_installed_softwareA

Installed applications, read from the uninstall registry keys.

Args: name_filter: Substring matched against the name and the publisher. max_items: Maximum rows to return.

Overlay tools, RGB and fan utilities, VPN clients and old antivirus products are the software most likely to be involved in a crash, so it is worth scanning this list when a dump names an unfamiliar module.

Inputs: max_items, name_filter. Returns: result

get_memory_modulesA

Installed RAM modules: size, rated speed, configured speed and part numbers.

Modules running below their rated speed mean XMP/EXPO is off; mixed speeds or a configured speed above the rating point at an overclock, which is the usual suspect behind MEMORY_MANAGEMENT and WHEA bug checks.

Inputs: no named parameters. Returns: result

get_network_configurationC

Network adapters, drivers, IP configuration and the latency-relevant settings.

Interrupt moderation, energy-efficient Ethernet, receive-side scaling and TCP auto-tuning all show up here; they matter for online play far more than raw bandwidth does.

Inputs: include_advanced. Returns: result

get_pagefile_and_dump_settingsA

Page file configuration and how Windows is told to write crash dumps.

Worth checking whenever a blue screen was reported but no dump exists: a disabled page file, a page file on a different volume, or dump collection set to "none" all prevent one from being written.

Inputs: no named parameters. Returns: result

get_per_application_graphics_settingsA

Per-application GPU preferences and compatibility shims.

Shows which executables are pinned to a specific GPU and which have fullscreen optimisations, DPI overrides or compatibility modes applied — the usual explanation for one game behaving differently from the rest.

Inputs: no named parameters. Returns: result

get_performance_snapshotA

An instantaneous read of CPU, memory, disk and GPU utilisation.

Includes the numbers that matter for stutter rather than throughput: time spent in DPCs and interrupts, the processor queue length, hard page faults, disk queue depth and per-engine GPU utilisation.

This is a single sample. Call it a few times while reproducing the problem rather than reading one snapshot as a trend.

Inputs: no named parameters. Returns: result

get_power_configurationA

The active power plan and the detail of one of its subgroups.

Processor minimum/maximum state, PCI Express link state power management and USB selective suspend are the settings that most often cost frames or cause devices to drop out.

Args: section: One of processor, pcie, disk, display, sleep, usb, graphics. Use "all" for every subgroup of the active plan (long output).

Inputs: section. Returns: result

get_reliability_historyB

The data behind Reliability Monitor: crashes, hangs, failed updates and driver problems.

Useful for spotting when trouble started, because it lines up software installs and updates against failures on the same timeline.

Inputs: days. Returns: result

get_security_mitigationsA

Virtualisation-based security, memory integrity, CPU mitigations and antivirus state.

These are the settings behind "my whole machine got slower after an update". Memory integrity and VBS in particular cost measurable performance in CPU-bound games and are switched on by default on many recent installations.

Inputs: no named parameters. Returns: result

get_server_statusB

Whether this server can reach the Windows data sources it needs.

Inputs: no named parameters. Returns: result

get_sleep_statesA

Which sleep states the firmware supports and what is blocking the others.

Relevant to DRIVER_POWER_STATE_FAILURE and to machines that wake up on their own or fail to resume.

Inputs: no named parameters. Returns: result

get_startup_programsA

Everything that starts with Windows: Run keys, the Startup folder and logon tasks.

The practical list to work through when boot is slow or something is interfering with games in the background.

Inputs: no named parameters. Returns: result

get_storage_healthA

Disks, their SMART-derived health counters, and free space per volume.

Wear level, reallocated sectors and read errors here explain KERNEL_DATA_INPAGE_ERROR, stutter during loading screens and failed updates. A system volume below roughly 10% free also blocks crash dumps.

Inputs: no named parameters. Returns: result

get_system_overviewA

What this machine is: Windows edition and build, uptime, CPU, RAM, board and firmware.

Start here. The build number decides which known issues apply, and the uptime tells you whether a "fix" has actually been through a reboot.

Inputs: no named parameters. Returns: result

get_temperaturesA

ACPI thermal zone temperatures, throttling state and fan status.

Coverage depends entirely on the firmware. Many desktop boards report nothing, in which case an empty result means "not exposed", not "cool".

Inputs: no named parameters. Returns: result

get_windows_updatesA

Installed updates and recent Windows Update activity, newest first.

Line the install dates up against the date problems started; a cumulative update or a driver delivered through Windows Update is a common trigger.

Inputs: max_items. Returns: result

inspect_crash_dumpA

Read a dump file's headers and report what crashed.

For a kernel dump this returns the bug check code, its four parameters and what they mean — the same information the blue screen showed.

For an application dump it returns the exception code, the faulting address, and the module that address belongs to, which is normally the answer. It also flags overlay and anti-cheat modules loaded into the crashed process, since those are a frequent cause of game crashes.

Only header structures are read, so this is fast even on a multi-gigabyte MEMORY.DMP. Full stack analysis still needs WinDbg.

Args: path: Absolute path to a .dmp file, from list_crash_dumps. include_modules: Also return the complete loaded-module list.

Inputs: path (required), include_modules. Returns: result

list_crash_dumpsA

List crash dumps on this machine, newest first.

Covers kernel minidumps (C:\Windows\Minidump), the full dump (MEMORY.DMP), live kernel reports — which are written when a driver hangs and recovers without a blue screen — and application dumps under %LOCALAPPDATA%\CrashDumps and Windows Error Reporting.

Pass a path from here to inspect_crash_dump.

Inputs: limit. Returns: result

list_driversA

Installed drivers with versions and dates, newest first.

Args: name_filter: Substring matched against device name and provider. device_class: Substring matched against the device class, e.g. "Display", "Net", "System". third_party_only: Exclude drivers provided by Microsoft. unsigned_only: Only drivers without a valid signature. max_items: Maximum rows to return.

A driver dated years before the rest, or an unsigned one, next to a recent bug check is worth investigating first.

Inputs: max_items, name_filter, device_class, unsigned_only, +1 more. Returns: result

list_error_reportsA

List Windows Error Reporting reports, newest first.

Every application crash and hang leaves one of these even when no dump file was kept, so they are often the only remaining record.

Inputs: limit. Returns: result

list_event_logsA

List the Windows event logs that contain records.

Use this to discover which log to query. Names like "System", "Application" and "Microsoft-Windows-Kernel-Power/Operational" are what query_event_log expects.

Args: name_filter: Optional wildcard, e.g. "Kernel" or "Microsoft-Windows-Diag*".

Inputs: name_filter. Returns: result

list_problem_devicesB

Devices Windows reports a problem with, with the Device Manager code decoded.

Code 43 on a GPU, code 10 on a controller and code 28 for a missing driver are the ones that most often explain a hardware failure.

Inputs: no named parameters. Returns: result

list_processesA

Running processes with CPU, memory, I/O and their executable paths.

Args: sort_by: "cpu", "memory" or "handles". top: How many rows to return. name_filter: Substring matched against the process name.

Inputs: top, sort_by, name_filter. Returns: result

list_servicesA

Windows services with their state, start mode and the account they run as.

Args: state: "Running", "Stopped" … start_mode: "Auto", "Manual", "Disabled". name_filter: Substring matched against the service and display name. failed_only: Only automatic services that are not running — i.e. things that should have started and did not.

Inputs: state, start_mode, failed_only, name_filter. Returns: result

query_event_logA

Read events from one log with the usual filters applied.

Args: log_name: Log to read, e.g. "System", "Application", or a channel name such as "Microsoft-Windows-Diagnostics-Performance/Operational". hours: How far back to look. Use a larger window for rare crashes. levels: Severity filter — 1 critical, 2 error, 3 warning, 4 information. event_ids: Restrict to specific event IDs. providers: Restrict to specific event sources, e.g. ["Microsoft-Windows-WHEA-Logger"]. contains: Keep only events whose message contains this text. max_events: Maximum events to return, newest first. message_limit: Characters of each message to keep.

The Security log requires an elevated server process; other logs do not.

Inputs: hours, levels, contains, log_name, +4 more. Returns: result

read_error_reportA

Read one Windows Error Reporting report.

Returns the problem signature: the faulting application and version, the faulting module and version, the offset into it, and the exception code with its meaning.

Args: path: Path to a .wer file, from list_error_reports.

Inputs: path (required). Returns: result

read_registry_keyA

Read every value under a registry key.

Args: path: Full key path, e.g. "HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers". Hives may be abbreviated: HKLM, HKCU, HKCR, HKU, HKCC. view: "native", "64" or "32" to choose the registry view on 64-bit Windows. include_subkeys: Also list the immediate child key names.

The key is opened for reading only. Binary values are returned as hex and truncated. A key that does not exist is reported as such rather than failing, since absence is often the answer.

Inputs: path (required), view, include_subkeys. Returns: result

read_registry_valueA

Read a single registry value.

Args: path: Full key path. name: Value name. Use "" for the key's default value. view: "native", "64" or "32".

Inputs: name (required), path (required), view. Returns: result

verify_read_only_guaranteesA

Prove that this server cannot modify the machine.

Scans the server's own installed source — every Python module and every PowerShell script it ships — for write APIs, mutating cmdlets, shell escapes and dynamic code execution, and reports what it allows.

Run this if you want to confirm the guarantee against the code that is actually installed rather than take the documentation's word for it.

Inputs: no named parameters. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 35 tools

    Disambiguation5/5

    Each tool targets a specific diagnostic area with minimal overlap. For example, get_crash_history, get_reliability_history, and list_crash_dumps serve different purposes (event analysis, reliability timeline, dump file listing). Tools like read_registry_key and read_registry_value are clearly distinct by scope. The descriptions further clarify boundaries.

    Naming Consistency5/5

    Tool names follow a consistent verb_noun pattern using prefixes like get_, list_, read_, inspect_, query_, verify_, and collect_. No mixing of camelCase or inconsistent verb styles, making the set predictable for an agent.

    Tool Count4/5

    35 tools is on the higher side, but the domain of Windows debugging is broad, covering hardware, software, events, performance, and settings. The count is justified given the need for specialized tools, though some agents might find it slightly heavy. It remains within a reasonable scope without being overwhelming.

    Completeness5/5

    The tool surface covers the full lifecycle of diagnostic tasks: system overview, hardware status, software inventory, event logs, crash analysis, performance monitoring, and configuration inspection. It includes both high-level summaries and detailed queries, with no obvious gaps for the stated purpose of diagnosing crashes, stutter, and performance issues.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers