etw-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@etw-mcpGive me an auto-summary of the trace"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
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 for a 30-minute clone-to-first-query walkthrough, then 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 https://github.com/nijosmsft/etw-mcp/releases/latest 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 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
Related MCP server: MCP Server for WinDbg Crash Analysis
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.serveruv automatically downloads Python, creates a virtual environment, and installs all dependencies on first run. No separate Python install needed.
Release wheel — use the
.whlasset URL from the latest GitHub release. The examples use<release-tag>and<wheel-file>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.exeis 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<wheel-version>\. SetETW_MCP_NO_AUTO_DOWNLOAD=1to disable the fetch (the server then falls back to the native consumer) or setETW_MCP_DOTNET_SIDECARto pin a manually-built binary. Seedotnet/README.mdfor build instructions andsrc/etw_analyzer/native/SIDECAR.mdfor 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.dllon 10.0.26100-era systems cannot read those PDBs; install Debugging Tools for Windows / WinDbg (known-gooddbghelp.dll10.0.29507+) and placedbghelp.dll+symsrv.dllinC:\Debuggers, or setETW_MCP_DBGHELP=<full path to dbghelp.dll>and optionallyETW_MCP_SYMSRV=<full path to symsrv.dll>.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
serversas the top-level key, NOTmcpServers. Pasting anmcpServersblock into a VS Code config silently does nothing — the server will not appear in Copilot. Every other MCP client documented here usesmcpServers.
{
"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 sharingEvery 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 stopWPR 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 <trace>.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 |
| Find |
| Load an ETL file. Decodes events via the .NET sidecar (when configured), the in-process native consumer, or xperf — see Trace Loading Modes. Caches as parquet. Set |
| Return JSON status for a background load by |
| Show trace IDs currently loaded in memory and active load jobs |
| Remove a loaded trace from memory |
| Show loaded trace metadata by |
| Check symbol resolution by |
| Download PDBs from symbol servers and reload trace by |
| Explain why a module is EXPORT_ONLY / MISSING by reconciling the EXE's RSDS record, all candidate PDBs on disk, and what dbghelp actually loaded. |
| Remove stale |
Analysis
Tool | Purpose |
| One-call comprehensive report: sysconfig, per-CPU, hot functions, symbols, DPC health |
| CPU sampling grouped by process, module, function, or CPU. Per-CPU filtering supported. |
| Hot functions filtered to networking modules (customizable). Per-CPU filtering and denominator modes supported. |
| Per-CPU utilization with role classification (saturated/active/idle) |
| Per-CPU utilization over time with hot CPU identification |
| Hot stack functions with true inclusive/exclusive weights and selectable denominator |
| Who calls a function and what it calls, with parent and denominator percentages |
| Recursively walk caller/callee butterfly edges with dominant/all/threshold branch policy |
| Estimate aggregate butterfly sample counts for stack predicates |
| One-shot WPA-style chain export around a target function ( |
| DPC/ISR duration histogram per module with watchdog risk assessment |
| Per-CPU DPC breakdown |
| Spinlock contention from ReadyThread stacks |
| Kernel pool allocations by module and tag |
Networking & Packet Capture
Tool | Purpose |
| Per-TCP-connection bytes, packets, retransmits, and duration |
| Per-UDP-flow packet counts, bytes, duration, and packet rate |
| Per-process TCP/UDP PPS and MB/s, split by send and receive |
| Per-connection TCP retransmit counts and rates |
| Per-process TCP connect cadence/latency percentiles |
| Per-process TCP accept cadence/latency percentiles |
| NDIS dropped-packet counts by miniport and reason |
| Approximate packets per AFD/IOCP receive completion |
| Socket create/close timing, duration, recv/send counts, and bytes |
| Whether AFD recv completions cluster on one CPU per socket |
| Decode packet-capture frame bytes and group traffic by 5-tuple |
| Show chronological packets for a selected 5-tuple |
| Decode the Ethernet, IP, and L4 headers for the packet nearest a timestamp |
| Heuristic Send→Recv latency from matched packet-capture events |
| Estimate pktmon component/edge traversal latency for TCP, UDP, and IP packets |
| Compare NIC DPC CPUs with process CPU samples to spot cross-CPU dispatch |
| UDP receive-path CPU distribution and overlap with networking DPC CPUs |
| Per-CPU distribution of NIC-driver DPCs for RSS queue spread |
| Wait-reason and ReadyThread detail for network-active threads |
| Convenience view for hot functions in networking modules |
| Convenience view for hot stack frames in networking modules |
| Convenience view for DPC/ISR activity in networking modules |
| Convenience view for lock contention in networking modules |
| HTTP.sys request lifecycle, URL, status, and latency |
| HTTP.sys URL-group queue depth and completion latency |
| MsQuic connection lifetime, packets, bytes, and loss estimate |
| MsQuic CID hash bucket and CPU distribution |
| MsQuic AckDelay percentiles by connection |
System & Process Info
Tool | Purpose |
| CPU model, core count, memory, NIC details, disk config from trace |
| Running processes, command lines, loaded images. Filterable by process name. |
| Per-file disk I/O counts, bytes, and latency |
| Which ETW providers/events are in the trace. Diagnose missing data. |
Comparison & Export
Tool | Purpose |
| Diff two traces: hot functions, modules, or per-CPU utilization. Shows delta. |
| Save the auto-summary analysis to a .md file for sharing |
Common Parameters
Most analysis tools accept:
trace_id— required ID returned byload_tracecpu_filter— CPU range, e.g."0"or"18-39". Enables per-CPU extraction from raw events.start_time/end_time— seconds from trace startmodule_filter— substring match, e.g."tcpip.sys"process_filter— substring match, e.g."echo_server"max_rows— limit output rowsdenominator— percentage basis for hot stack/function tools:"trace","active_cpus","active_busy", or"custom"
Stack Analysis Notes
For full WPA/butterfly stack parity, load with mode="xperf" (or set ETW_MCP_MODE=xperf); native mode covers core stack analysis but may not expose every xperf-derived view.
Capturing traces
Most workflows start by analyzing an existing .etl. When you need to author one — locally or on a lab machine — use the four capture_profiles tools:
Tool | Purpose |
| Markdown table of the 9 bundled WPR scenarios ( |
| Metadata table + the bundled |
| Paste-ready 3-step PowerShell (start / sleep / stop) plus a verification step. Branches automatically for the |
| Long-form runbook covering prerequisites, profile save, start/verify, transfer-back examples (PowerShell remoting / LabLink MCP / scp) when |
The tools are transport-agnostic — they emit strings, never invoke wpr.exe or pktmon.exe themselves. Run the commands on local PowerShell, a LabLink MCP node, an SSH host, or hand them to a human. Then call load_trace(etl_path=...) on the resulting file to analyze it.
# Typical local capture: 10s CPU profile, then analyze
wpr -start .\cpu.wprp -filemode
Start-Sleep -Seconds 10
wpr -stop 'C:\traces\cpu.etl'
# → call load_trace(etl_path='C:\traces\cpu.etl')All WPR profiles require administrator elevation. WPR uses the NT Kernel Logger and so cannot run inside a Windows container.
Trace Loading Modes
load_trace accepts a mode argument that selects the extraction pipeline. Three pipelines coexist, each with the same trace_id and parquet cache layout so a trace extracted in one mode can be reloaded in another. The default mode="auto" walks the fallback chain .NET sidecar → native → xperf and picks the first one available.
The ETW_MCP_MODE environment variable overrides the default when mode= is left unspecified. The explicit mode= arg always wins over the env var. See CHANGELOG.md for the csharp → dotnet rename history.
Mode | What it is | When | Force with | Notes |
| Self-contained .NET 8 binary ( | Sidecar resolvable (auto-bootstrapped on first use). |
| Pin a specific binary with |
| In-process |
|
| For ETLs >1 GB also set |
| Subprocess pipeline that shells out to | Neither sidecar nor native consumer is available. |
| Requires WPT installed (default path |
Pre-populating or building the .NET sidecar
The wheel auto-bootstraps the matching binary on first use, so most users don't need to do anything. For locked-down environments (no GitHub access) you can pre-populate the per-version cache or build from source.
# Option A — download the prebuilt asset
New-Item -ItemType Directory -Force -Path "$env:LOCALAPPDATA\etw-mcp\sidecar\v0.6.0" | Out-Null
Invoke-WebRequest `
-Uri "https://github.com/nijosmsft/etw-mcp/releases/download/v0.8.5/etw-extract.exe" `
-OutFile "$env:LOCALAPPDATA\etw-mcp\sidecar\v0.6.0\etw-extract.exe"
# Option B — build from source (no .NET runtime required for the resulting binary; only for the build)
cd <repo>\dotnet
dotnet publish -c Release -r win-x64 --self-contained -o publish\win-x64
# Then either set ETW_MCP_DOTNET_SIDECAR to the published path or copy
# it into %LOCALAPPDATA%\etw-mcp\sidecar\v<wheel-version>\Two .NET-sidecar strategies are available: materialized-small (default, fastest) and event-store-streaming (bounded RSS for very large traces). Full build + run docs live in dotnet/README.md; supervisor / debugging notes in src/etw_analyzer/native/SIDECAR.md.
Forcing re-extraction across modes
All three pipelines write the same cache layout, so reloads can short-circuit even if you switch modes. Use force=True on load_trace when you need to re-extract with the selected mode (e.g. after rebuilding the .NET sidecar with a new event class).
Parallel Analysis
The server supports multiple loaded traces in one MCP server process when callers pass trace_id explicitly. Each analysis tool resolves data from the requested trace ID instead of using shared "current trace" state, so parallel agents can safely analyze different ETLs at the same time.
Architecture
AI Assistant ←stdio→ etw-mcp (Python)
│
├── .NET sidecar (preferred when configured, mode="dotnet" or auto)
│ ├── etw-extract.exe — self-contained .NET binary (~38 MB)
│ ├── Decodes Layer-1 events to per-class parquets
│ ├── JSONL heartbeat/progress over stdout
│ └── Python supervisor runs Layer-3 aggregators
│
├── Native consumer (default when no sidecar configured, mode="auto" or "native")
│ ├── OpenTraceW / ProcessTrace via advapi32
│ ├── TdhGetEventInformation via tdh.dll
│ ├── dbghelp.dll for symbolization
│ └── In-process event dispatch → aggregators
│ → CPU sampling, DPC/ISR, CSwitch, TCPIP, UDP,
│ AFD, NDIS PacketCapture, HTTP.sys, MsQuic, ...
│
├── xperf.exe (fallback, mode="xperf")
│ ├── profile -detail → CPU sampling (module!function)
│ ├── profile -util → Per-CPU utilization timeline
│ ├── dpcisr → DPC/ISR histograms
│ ├── stack -butterfly → Call stacks with callers/callees
│ ├── cswitch → Context switch data
│ ├── sysconfig → Hardware configuration
│ ├── process → Process/thread/image info
│ ├── diskio → Disk I/O summary
│ ├── tracestats → Trace metadata
│ └── dumper → Raw events (on-demand, cached)
│
├── parquet cache (.etw-export-<name>/)
│ Structured data saved as .parquet for instant reload.
│ Schema v3 manifest records producer ∈ {dotnet, native, xperf}.
│ Shared across all three modes — load once, reuse anywhere.
│
├── pandas (aggregation + filtering)
└── FastMCP (stdio transport)For end-to-end dataflow across the MCP ecosystem (analyzer + sidecar), see ARCHITECTURE.md.
Performance
First load (dotnet sidecar): ~13s on a 1.1 GB ETL (256 K events/sec). Subprocess overhead is paid once, Python stays free of the event buffer.
First load (native, default when no sidecar): 5-30s for typical traces. Single in-process pass — no subprocess overhead.
First load (xperf fallback): 30-180s (9 xperf actions run in parallel with 4 workers)
Subsequent loads: Instant (reads from parquet cache, regardless of mode)
Per-CPU queries: First query parses all SampledProfile events, subsequent queries filter in-memory (<1s)
Trace comparison: Uses cache from both traces — instant if both were previously loaded
Symbol Configuration
For Microsoft system binaries, use the public symbol server:
_NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbolsFor internal Microsoft builds, use the internal server:
_NT_SYMBOL_PATH=srv*C:\symbols*https://symweb.azurefd.netMultiple paths can be combined with semicolons. Add local PDB directories for your own binaries:
_NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbols;C:\myproject\build\binKernel symbol resolution
Starting in v0.7.0, etw-mcp resolves kernel-mode symbols (ntoskrnl.exe, tcpip.sys, afd.sys,
driver stack frames, etc.) correctly from cross-machine traces. Previously, the symbolizer
read the local analyst box's kernel image to derive the PDB GUID, which produced wrong
symbols on any machine that didn't match the trace host (bogus ntoskrnl entries such as
MmCopyMemory, strncpy, and FsRtlAreNamesEqual). Now the sidecar and native consumer
capture the exact PDB identity (GUID, age, name) from each image's DbgID_RSDS rundown
record embedded in the ETL, and the symbolizer loads PDBs by that exact identity via
SymFindFileInPathW. The result is correct PDB-resolved function names for all kernel
modules regardless of the analyst machine's installed OS version.
MSFZ PDB format requirement. Internal and lab symbol servers (including Microsoft's
internal symweb) distribute kernel/driver PDBs in MSFZ (compressed) format. The system
dbghelp.dll (v10.0.26100, shipped with Windows) cannot load MSFZ PDBs and silently falls
back to PE export-table symbols. etw-mcp automatically prefers the WinDbg "Debugging Tools
for Windows" dbghelp.dll at C:\Debuggers\dbghelp.dll (v10.0.29507 or later) over the
system one when it is present. Install WinDbg Preview from the Microsoft Store, or the
standalone Debugging Tools for Windows from the Windows ADK, to enable MSFZ support.
Public Microsoft symbol server (msdl.microsoft.com) PDBs use standard MSF7 format and
work correctly with the system dbghelp.dll. Only internal/lab PDB stores require the
upgraded dbghelp.
Contributing
Contributions welcome. See CONTRIBUTING.md for the project structure, how to run tests, and how maintainers publish releases. Please open an issue first to discuss what you'd like to change.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nijosmsft/etw-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server