AgentStack
MCP verified MIT Self-run

Etw Mcp

mcp-nijosmsft-etw-mcp · by nijosmsft

MCP server for analyzing Windows ETW (.etl) traces — xperf / native ETW / .NET sidecar + WPR & pktmon capture authoring

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add mcp-nijosmsft-etw-mcp

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Etw Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

etw-mcp

An MCP server that lets AI coding assistants analyze Windows WPR/ETW traces (.etl files). Load a trace, then ask questions in natural language — the server uses a self-contained .NET sidecar by default (auto-downloaded on first use), with a fast in-process ETW path and xperf.exe as fallbacks.

> [!IMPORTANT] > Personal hobby project — not endorsed by Microsoft. > > This repository is a personal side project. It is not an official > Microsoft product, is not affiliated with or endorsed by Microsoft, > and carries no warranty or support guarantee. Use at your own risk.

> New here? Start with [GETTING-STARTED.md](GETTING-STARTED.md) for a 30-minute clone-to-first-query walkthrough, then [ARCHITECTURE.md](ARCHITECTURE.md) for the cross-repo dataflow.

Works with any Windows performance trace: networking (tcpip.sys, NDIS, NIC drivers, HTTP.sys), kernel (DPCs, ISRs, context switches), and application workloads.

Quick Install

The snippet below pins v0.6.0 — grab the latest wheel URL from if you need a newer build. Install uv (winget install astral-sh.uv) and the Windows Performance Toolkit (winget install --id Microsoft.WindowsADK --override "/features OptionId.WindowsPerformanceToolkit /quiet"), then drop the config below into your MCP client. The top-level key is mcpServers for Claude / Copilot CLI / Claude Desktop / Cursor and servers for VS Code — per-client config paths are spelled out in [Setup](#setup) below. The first load_trace call auto-downloads the matching .NET sidecar (~40 MB) into %LOCALAPPDATA%\etw-mcp\sidecar\v0.6.0\ and pulls 200-500 MB of PDBs to C:\symbols; set ETW_MCP_NO_AUTO_DOWNLOAD=1 to skip the sidecar fetch.

{
  "mcpServers": {
    "etw-trace-analyzer": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--no-project", "--with",
               "https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw_mcp-0.8.5-py3-none-any.whl",
               "python", "-m", "etw_analyzer.server"],
      "env": {
        "_NT_SYMBOL_PATH": "srv*C:\\symbols*https://msdl.microsoft.com/download/symbols"
      }
    }
  }
}

Features

  • Auto-summary — one-call comprehensive analysis: system config, per-CPU utilization, hot functions, symbol status, DPC health
  • CPU sampling — hot functions by module, process, or call stack
  • Per-CPU breakdown — utilization per logical processor, identify hot/idle/saturated CPUs
  • Per-CPU filtering — drill into what's running on a specific CPU (e.g. "what's saturating CPU 0?")
  • Trace comparison — diff two traces to find regressions (hot functions, modules, or per-CPU utilization)
  • DPC/ISR analysis — duration histograms, per-CPU distribution, watchdog risk detection
  • Lock contention — spinlock contention from ReadyThread/context switch stacks
  • Symbol resolution — automatic PDB download from symbol servers
  • Call stacks — butterfly stacks with caller/callee relationships, recursive stack walks, and WPA-style chain exports
  • System info — CPU model, NIC details, memory, disk config from trace metadata
  • Process info — running processes, command lines, loaded driver versions
  • Disk I/O — per-file I/O summary to rule out storage bottlenecks
  • Network flows and sockets — TCP/UDP throughput, per-flow summaries, retransmits, socket lifecycle, and AFD batching
  • Packet capture analysis — decode NDIS PacketCapture frame bytes from WPR/pktmon-style ETLs, including 5-tuples, timelines, and Send→Recv latency estimates
  • Export — save analysis to markdown for sharing via email
  • Caching — parquet-based disk cache for instant reload, parallel xperf extraction

Installation

Windows only — this server uses Windows ETW APIs (advapi32, tdh, dbghelp).

# 1. Install prerequisites — skip any you already have
winget install astral-sh.uv              # Python package manager
winget install --id Microsoft.WindowsADK --override "/features OptionId.WindowsPerformanceToolkit /quiet"
                                         # Recommended — provides xperf for fallback and full analysis coverage.
                                         # NOTE: do NOT use Microsoft.WindowsSDK — it is not a valid winget package ID.
                                         # The --override flag installs just the ~150 MB WPT feature instead of the full ~5 GB ADK.

# 2. Verify the latest release wheel starts (Ctrl+C to stop)
uv run --no-project --with https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw_mcp-0.8.5-py3-none-any.whl python -m etw_analyzer.server
  • uv automatically downloads Python, creates a virtual environment, and installs all dependencies on first run. No separate Python install needed.
  • Release wheel — use the .whl asset URL from the latest GitHub release. The examples use ` and ` placeholders because the URL is only valid after a release is published. Maintainers can publish that asset with the manual Manual release GitHub Actions workflow.
  • .NET sidecar (default; auto-bootstrapped)etw-extract.exe is a self-contained .NET binary (~40 MB, no .NET install required) that decodes ETL files faster than the in-process path and frees the Python process from holding the full event buffer. The wheel auto-fetches the matching version from the GitHub release on first use and caches it at %LOCALAPPDATA%\etw-mcp\sidecar\v\. Set ETW_MCP_NO_AUTO_DOWNLOAD=1 to disable the fetch (the server then falls back to the native consumer) or set ETW_MCP_DOTNET_SIDECAR to pin a manually-built binary. See [dotnet/README.md](dotnet/README.md) for build instructions and [src/etw_analyzer/native/SIDECAR.md](src/etw_analyzer/native/SIDECAR.md) for the supervisor plumbing.
  • Native ETW consumer (fallback when sidecar is unavailable) — the server decodes ETL files in-process via OpenTraceW/tdh.dll. This path is enough to start the MCP server and run the core native analysis tools on recent Windows builds and is the automatic fallback when auto-bootstrap is blocked.
  • Kernel symbols need an MSFZ-capable dbghelp — published Windows OS PDBs for kernel modules can be MSFZ-compressed. The inbox C:\Windows\System32\dbghelp.dll on 10.0.26100-era systems cannot read those PDBs; install Debugging Tools for Windows / WinDbg (known-good dbghelp.dll 10.0.29507+) and place dbghelp.dll + symsrv.dll in C:\Debuggers, or set ETW_MCP_DBGHELP= and optionally ETW_MCP_SYMSRV=.
  • xperf.exe / Windows Performance Toolkit — installed as part of the Windows SDK. Recommended for complete results because it enables fallback extraction, richer WPA-derived stack views, xperf-only tools such as pool analysis, and older Windows builds where the native bindings can't load. Expected location: C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\xperf.exe

Setup

Configure your AI assistant to use the server:

Claude Code

Add to your .mcp.json (project root or ~/.claude/.mcp.json):

{
  "mcpServers": {
    "etw-trace-analyzer": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--no-project", "--with", "https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw_mcp-0.8.5-py3-none-any.whl", "python", "-m", "etw_analyzer.server"],
      "env": {
        "_NT_SYMBOL_PATH": "srv*C:\\symbols*https://msdl.microsoft.com/download/symbols"
      }
    }
  }
}

VS Code (GitHub Copilot)

Add to .vscode/mcp.json (workspace) or %APPDATA%\Code\User\mcp.json (user-scoped):

> Note: VS Code uses servers as the top-level key, NOT mcpServers. Pasting an mcpServers block into a VS Code config silently does nothing — the server will not appear in Copilot. Every other MCP client documented here uses mcpServers.

{
  "servers": {
    "etw-trace-analyzer": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--no-project", "--with", "https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw_mcp-0.8.5-py3-none-any.whl", "python", "-m", "etw_analyzer.server"],
      "env": {
        "_NT_SYMBOL_PATH": "srv*C:\\symbols*https://msdl.microsoft.com/download/symbols"
      }
    }
  }
}

Claude Desktop

Add to %APPDATA%\Claude\claude_desktop_config.json (top-level key: mcpServers):

{
  "mcpServers": {
    "etw-trace-analyzer": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--no-project", "--with", "https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw_mcp-0.8.5-py3-none-any.whl", "python", "-m", "etw_analyzer.server"],
      "env": {
        "_NT_SYMBOL_PATH": "srv*C:\\symbols*https://msdl.microsoft.com/download/symbols"
      }
    }
  }
}

GitHub Copilot CLI

Add to %USERPROFILE%\.copilot\mcp-config.json (top-level key: mcpServers):

{
  "mcpServers": {
    "etw-trace-analyzer": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--no-project", "--with", "https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw_mcp-0.8.5-py3-none-any.whl", "python", "-m", "etw_analyzer.server"],
      "env": {
        "_NT_SYMBOL_PATH": "srv*C:\\symbols*https://msdl.microsoft.com/download/symbols"
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json (project root) or %USERPROFILE%\.cursor\mcp.json (user-scoped). Top-level key: mcpServers. The JSON body is identical to the Claude Code example above.

Replace the release URL in every example with the wheel asset from the release you want to run.

Usage

Just Ask

You don't need to know tool names. Just describe what you want:

"Load the trace at C:\traces\mytrace.etl"
"Use the returned trace_id for the next questions"
"Give me a summary of this trace"
"Where is CPU time being spent?"
"What's running on CPU 0?"
"Which CPUs have echo_server active?"
"Show me the hottest functions in tcpip.sys"
"Walk the caller chain for KeAcquireInStackQueuedSpinLock"
"Count stacks containing KxWaitForSpinLockAndAcquire and IppResolveNeighbor"
"What are the DPC durations for the NIC driver?"
"Which CPUs are active and which are idle?"
"Is there lock contention in the networking stack?"
"Show TCP and UDP throughput by process"
"Summarize UDP flows in this trace"
"Show packet drops by miniport and reason"
"Summarize packet-capture 5-tuples from this pktmon trace"
"Show the packet timeline for 10.0.0.1:5000 -> 10.0.0.2:6000/udp"
"Decode the packet closest to timestamp 123456789"
"Estimate Send -> Recv latency from packet capture data"
"Compare this trace with the baseline"
"Export the analysis to a markdown file"
"What hardware is this trace from?"
"Which processes were running during the trace?"

Workflow

load_trace(path)          → Parse ETL via dotnet sidecar, native ETW, or xperf;
                            cache as parquet; return trace_id, or return
                            status="extracting" for long async loads
get_load_status(path)     → Poll background extraction progress / failures
analyze(trace_id)         → One-call comprehensive report
detailed tools(trace_id)  → Drill into specific areas
export_analysis(trace_id) → Save to .md for sharing

Every analysis tool requires the trace_id returned by load_trace. This allows multiple traces to be analyzed concurrently in the same MCP server process without cross-trace contamination.

Packet Capture and pktmon Examples

Packet-level drill-down tools need an ETL that includes NDIS PacketCapture frame bytes or pktmon packet bytes. For pktmon, collect with --pkt-size 0; the analyzer can convert the ETL with pktmon etl2txt/pktmon etl2pcap, summarize top flows, show timelines, decode packets, estimate Send -> Recv latency, and report pktmon component/edge layer latency. Latency estimates are heuristic and are most reliable on loopback or hosts with synchronized clocks:

pktmon filter remove
pktmon filter add UdpEcho -t UDP -p 4444
pktmon start --capture --pkt-size 0 --file-name C:\traces\pktmon-udp.etl
# Run the workload you want to inspect.
pktmon stop

WPR profiles work too as long as they enable the Microsoft-Windows-NDIS-PacketCapture provider.

Pktmon ETLs expose numeric component/edge IDs in packet events. For friendly component names, the analyzer uses pktmon comp list --all on the analysis host or a sidecar file named .components.txt / pktmon.components.txt captured from the target machine.

Then ask questions like:

"Load C:\traces\pktmon-udp.etl and show the packet capture summary"
"Which 5-tuples account for the most bytes?"
"Show packet timeline for 10.0.0.1:4444 -> 10.0.0.2:4444/udp"
"Decode the packet closest to timestamp 123456789"
"Estimate one-way Send -> Recv latency for captured packets and explain any clock-sync caveats"
"Show pktmon layer latency for the top TCP and UDP flows"
"Show NDIS packet drops by miniport and reason"
"Check whether UDP recv processing is staying on the same CPUs as NIC DPCs"

Remote Collection with LabLink MCP

LabLink — lightweight Go MCP for remote command execution on Windows lab machines. When the AI client has both MCP servers configured, LabLink can collect traces from remote Windows machines; etw-mcp analyzes the ETL after LabLink pulls it to the operator machine.

Common combined prompts:

"On vm-server, collect a 60 second networking trace and tell me which network functions are hottest."
"Capture UDP port 4444 packets on vm-server for 30 seconds and show the top flows."
"Get a 30 second performance log from the server role and summarize CPU, DPCs, and TCP/UDP throughput."
"Trace traffic between 10.0.0.1 and 10.0.0.2 on vm-server, then decode the largest flow and estimate Send -> Recv latency with clock-sync caveats."

For WPR captures, ask for the outcome instead of naming tools:

"Collect a 60 second networking trace from vm-server and tell me which modules and functions used the most CPU."
"Capture a performance trace from the server role, then summarize CPU usage, DPC time, TCP/UDP throughput, and any packet drops."
"Get a WPR trace from vm-server while I reproduce the issue, then analyze network hot functions and lock contention."

For pktmon captures, describe the traffic pattern and the analysis you want:

"Collect packet monitor traffic on vm-server for UDP port 4444 for 30 seconds, then show the top flows."
"Trace packets between 10.0.0.1 and 10.0.0.2 on vm-server, then decode the busiest flow and estimate layer latency with confidence levels."
"Capture pktmon data for TCP 443 on vm-server, pull it back, and tell me which component/edge hop adds the most latency."
"Collect a packet trace for this pattern and analyze it end to end: top flows, timeline, packet decode, and pktmon layer latency."

Run the LabLink agent elevated, or under an account with permission to start ETW sessions and write the chosen remote ETL path. The analyzer runs locally after the .etl is pulled back, so it only needs read access to the local trace file.

Available Tools

Trace Management

| Tool | Purpose | |------|---------| | list_traces | Find .etl files in a directory | | load_trace | Load an ETL file. Decodes events via the .NET sidecar (when configured), the in-process native consumer, or xperf — see [Trace Loading Modes](#trace-loading-modes). Caches as parquet. Set force=True to re-export. Long extracts run in the background by default; tune the inline wait with wait_seconds. | | get_load_status | Return JSON status for a backgr

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.