Content
# DiagSession MCP Server
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.
## Features
- **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
## Architecture
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
└─────────────────────────────────────┘
```
### Key Components
- **Domain Models**: `CallTreeNode`, `FunctionStats`, `AnalysisResult`, `AnalysisOptions`
- **Domain Interfaces**: `IEtlAnalyzer`, `IDiagSessionExtractor`
- **Application**: `AnalyzeDiagSessionUseCase`, DTOs, `RequestContext`
- **Infrastructure**: `TraceEventEtlAnalyzer`, `DiagSessionArchiveExtractor`
- **MCP**: `AnalyzeCallTreeTool`
## Installation
### Prerequisites
- .NET 8.0 SDK or later
- Windows OS (required for TraceEvent library)
### Build
```bash
dotnet restore
dotnet build
```
### Run
```bash
dotnet run --project DiagSession-Mcp.csproj
```
The server will start and listen for MCP requests via stdio transport.
## MCP Tool: analyze_call_tree
### Parameters
| 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 |
### Response Schema
```json
{
"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": [...]
}
```
### Error Codes
- `FILE_NOT_FOUND`: Specified file does not exist
- `INVALID_PARAMS`: Invalid parameters provided
- `TIMEOUT`: Analysis timeout exceeded
- `INTERNAL_ERROR`: Unexpected server error
## Configuration
Configuration is loaded from `appsettings.json` and environment variables.
### appsettings.json
```json
{
"DiagSessionMcp": {
"SymbolPath": "srv*c:\\symbols*https://msdl.microsoft.com/download/symbols",
"DefaultTimeoutSeconds": 30,
"MaxConcurrentAnalyses": 2,
"MaxMemoryMB": 4096,
"AllowedDirectories": ["C:\\DiagSessions"],
"LogLevel": "Information"
}
}
```
### Environment Variables
- `_NT_SYMBOL_PATH`: Override symbol server path
- `DIAGSESSION_MCP__SYMBOLPATH`: Override symbol path via configuration
## Development
### Project Structure
```
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
```
### Testing
```bash
# Run all tests
dotnet test
# Run specific test category
dotnet test --filter Category=Unit
dotnet test --filter Category=Integration
```
## Design Principles
This 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
## License
MIT
## Credits
Built with:
- [ModelContextProtocol C# SDK](https://github.com/modelcontextprotocol/csharp-sdk)
- [Microsoft.Diagnostics.Tracing.TraceEvent](https://github.com/microsoft/perfview)