A production-grade Model Context Protocol (MCP) server for analyzing Windows ETL trace files from .diagsession archives. Built with clean architecture principles and enterprise best practices.
- ETL Trace Analysis: Analyzes Windows Performance Recorder traces with CPU sampling data
- Call Tree Generation: Builds hierarchical call trees showing inclusive/exclusive CPU time
- Symbol Resolution: Integrates with Microsoft symbol servers for function name resolution
- .diagsession Support: Automatically extracts ETL files from .diagsession ZIP archives
- Process Filtering: Filter analysis by specific process ID
- Depth Control: Limit call tree depth for efficient responses
- MCP Protocol: Exposes analysis via standard MCP tool interface
The server follows a layered architecture with strict separation of concerns:
┌─────────────────────────────────────┐
│ MCP Protocol Layer │ Tool handlers, schemas
├─────────────────────────────────────┤
│ Application Layer │ Use cases, DTOs
├─────────────────────────────────────┤
│ Domain Layer │ Business logic, models
├─────────────────────────────────────┤
│ Infrastructure Layer │ TraceEvent adapter, ZIP extraction
└─────────────────────────────────────┘
- Domain Models:
CallTreeNode,FunctionStats,AnalysisResult,AnalysisOptions - Domain Interfaces:
IEtlAnalyzer,IDiagSessionExtractor - Application:
AnalyzeDiagSessionUseCase, DTOs,RequestContext - Infrastructure:
TraceEventEtlAnalyzer,DiagSessionArchiveExtractor - MCP:
AnalyzeCallTreeTool
- .NET 8.0 SDK or later
- Windows OS (required for TraceEvent library)
dotnet restore
dotnet builddotnet run --project DiagSession-Mcp.csprojThe server will start and listen for MCP requests via stdio transport.
| Parameter | Type | Required | Description |
|---|---|---|---|
diagsession_path |
string | Yes | Path to .diagsession or .etl file |
max_depth |
integer | No | Maximum call tree depth (default: 10, max: 50) |
process_id |
integer | No | Filter by specific process ID |
symbol_path |
string | No | Symbol server path |
timeout_seconds |
integer | No | Symbol loading timeout (default: 30, max: 300) |
max_symbol_size_mb |
number | No | Skip symbols larger than this size |
verbose |
boolean | No | Enable verbose logging |
{
"callTrees": {
"4036": {
"functionName": "InterruptEstimator (PID: 4036)",
"moduleName": null,
"inclusiveSamples": 246,
"exclusiveSamples": 0,
"inclusivePercent": 100.0,
"exclusivePercent": 0.0,
"inclusiveTimeMs": 246.0,
"exclusiveTimeMs": 0.0,
"children": [...]
}
},
"processNames": {
"4036": "InterruptEstimator"
},
"totalSamples": 246,
"profileIntervalMs": 1.0,
"analysisTimestamp": "2025-11-25T07:36:00Z",
"correlationId": "abc123",
"topFunctionsByExclusive": [...],
"topFunctionsByInclusive": [...]
}FILE_NOT_FOUND: Specified file does not existINVALID_PARAMS: Invalid parameters providedTIMEOUT: Analysis timeout exceededINTERNAL_ERROR: Unexpected server error
Configuration is loaded from appsettings.json and environment variables.
{
"DiagSessionMcp": {
"SymbolPath": "srv*c:\\symbols*https://msdl.microsoft.com/download/symbols",
"DefaultTimeoutSeconds": 30,
"MaxConcurrentAnalyses": 2,
"MaxMemoryMB": 4096,
"AllowedDirectories": ["C:\\DiagSessions"],
"LogLevel": "Information"
}
}_NT_SYMBOL_PATH: Override symbol server pathDIAGSESSION_MCP__SYMBOLPATH: Override symbol path via configuration
DiagSession-Mcp/
├── src/
│ ├── Domain/
│ │ ├── Models/ # Domain entities
│ │ └── Interfaces/ # Domain contracts
│ ├── Application/
│ │ ├── UseCases/ # Application logic
│ │ ├── DTOs/ # Data transfer objects
│ │ └── Common/ # Cross-cutting concerns
│ ├── Infrastructure/
│ │ └── Adapters/ # External system adapters
│ ├── Mcp/
│ │ └── Tools/ # MCP tool implementations
│ └── Program.cs # Entry point
├── appsettings.json
└── DiagSession-Mcp.csproj
# Run all tests
dotnet test
# Run specific test category
dotnet test --filter Category=Unit
dotnet test --filter Category=IntegrationThis server follows enterprise architecture best practices:
- Bounded Context: Focused solely on ETL trace analysis
- Ports & Adapters: External dependencies behind interfaces
- Domain-Driven Design: Rich domain models with business logic
- Separation of Concerns: Strict layering with clear responsibilities
- Dependency Injection: All dependencies injected via constructors
- Immutability: DTOs and domain models are immutable where possible
- Explicit Contracts: Tool schemas versioned and documented
- Observability: Structured logging with correlation IDs
- Error Handling: Domain errors separated from technical failures
- Testability: Each layer independently testable
MIT
Built with: