-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Idea
Add an embedded web server so users can view monitoring dashboards remotely from any browser, without needing an RDP session to the machine running the desktop app.
Core Concept
Both Dashboard and Lite already have data service layers (DatabaseService / LocalDataService) that return plain C# model objects. An embedded Kestrel web server can call those same methods and return JSON to a browser. The data path is:
SQL Server / DuckDB → Existing data service (reuse as-is) → REST endpoints (new, thin) → Browser
The main work is:
- Thin REST endpoints wrapping existing
DatabaseService/LocalDataServicemethods - A JavaScript frontend with a charting library (Chart.js, Plotly, ECharts) to render the same graphs
- Authentication to control who can access the web UI
The query logic, data models, and connection handling already exist — this is primarily a presentation layer addition.
Approach: Embedded Kestrel in the WPF App
Host a minimal ASP.NET Core Kestrel web server inside the existing WPF process. Both apps already do this for MCP (localhost-only). Extending it to serve a web dashboard reuses the same infrastructure.
Advantages:
- Shares the same process, same
DatabaseServiceinstance, same connection pool — no data duplication - For Lite, avoids DuckDB's single-writer limitation (shared process = shared connection)
- No separate deployment; the web UI comes with the desktop app
- Can start localhost-only and optionally bind to a NIC for LAN access
Limitations:
- Web dashboard is only available while the desktop app is running
- Shares process/memory with the desktop app (a web-layer vulnerability could theoretically access in-process data)
Security Concerns
Network exposure
- Desktop apps currently have zero network attack surface (MCP is localhost-only)
- Binding to
0.0.0.0for LAN access requires firewall changes on monitoring machines - Microsoft recommends a reverse proxy (IIS/nginx) in front of Kestrel for non-localhost exposure
- Should be configurable: localhost-only (default) vs. LAN-accessible
Authentication
- Windows Auth (Kerberos): Natural fit for AD environments, zero credential management
- API key / bearer token: Simple for small teams, configurable in app settings
- ASP.NET Core Identity: Self-contained local accounts if needed
- At minimum: some form of auth before exposing SQL Server performance data over HTTP
Data sensitivity
- SQL Server credentials stay in-process, never sent to the browser
- Query text may contain PII in parameters (names, SSNs, emails)
- Blocking/deadlock XML contains full query text + login/host names
- Consider: role-based visibility, query text truncation, PII redaction options
- TLS required for any non-localhost deployment
Privacy Concerns
| Data Type | Risk |
|---|---|
| Query text | PII in parameters, schema exposure |
| Execution plans | Index/table structures, data volumes |
| Blocking/deadlock XML | Full query text + login/host names |
| Login/host names | Internal infrastructure topology |
| Aggregate metrics | Business patterns (peak hours, volumes) |
Mitigations: role-based access, truncation, audit logging, no client-side caching of sensitive data.
Architectural Challenges
Charting (main effort)
- ScottPlot is WPF-specific (
WpfPlotcontrol) — cannot render in a browser - Browser needs a JavaScript charting library (Chart.js, Plotly, ECharts, etc.)
- The data is the same — just needs different rendering
- ScottPlot can also render server-side SVGs (
Plot.GetSvgXml()) for a no-JS fallback, but loses interactivity
REST endpoint layer (straightforward)
- Existing
DatabaseServicemethods return model objects that serialize cleanly to JSON - MCP tools already wrap these methods — REST endpoints would follow the same pattern
- Thin controllers calling existing service methods, returning JSON
Real-time refresh
- Desktop uses
DispatcherTimerfor periodic refresh - Web options: SignalR push, Server-Sent Events, or simple client-side polling (
setInterval+ fetch) - For a monitoring dashboard refreshing every 15-30 seconds, client-side polling is perfectly adequate
DuckDB concurrency (Lite only)
- Embedded Kestrel avoids this entirely — shared process, shared connection
- No multi-process coordination needed
Minimum Viable Version
- Kestrel web server embedded in the existing app (extend current MCP hosting)
- REST endpoints for: overview, CPU, wait stats, blocking, deadlocks
- Static HTML/JS frontend with Chart.js or similar
- Basic authentication (API key or Windows Auth)
- Configurable binding (localhost-only by default)
Labels
This is an idea/exploration issue, not a committed feature.