Build, test, and maintain the Uno DevServer (CLI tool, RemoteControl Host, MCP proxy, add-in discovery). Use when working under src/Uno.UI.DevServer.Cli, src/Uno.UI.RemoteControl.Host, or src/Uno.UI.RemoteControl.DevServer.Tests, or on DevServer CLI commands, the MCP proxy, IDE channel, or add-in resolution.
72
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Maintain and extend the Uno DevServer: the CLI tool, the Host process, MCP proxy integration, and add-in discovery. The DevServer projects are independent of the UI framework and do not require crosstargeting_override.props.
Uno.UI.DevServer.Cli) – entry point, user-facing commands, MCP STDIO proxy, start-lifecycle management.Uno.UI.RemoteControl.Host) – ASP.NET Core server for Hot Reload, IDE channel, processors.The CLI start command handles existing-server detection (AmbientRegistry), IDE channel rebinding, port allocation, and launches the Host in direct mode (no --command), so all arguments (including --ideChannel) reach the Host via IConfiguration regardless of Host binary version. Non-start commands (stop, list, cleanup) use the Host's controller mode (--command=<verb>). The CLI can also run in MCP mode (--mcp-app) as a Model Context Protocol proxy between AI agents and the running Host.
| NuGet Package | Contents |
|---|---|
Uno.DevServer | CLI tool (installed via dotnet tool) |
Uno.WinUI.DevServer | Host binaries, processors, BuildTransitive targets |
| Directory | Purpose |
|---|---|
src/Uno.UI.DevServer.Cli/ | CLI tool: commands, helpers, MCP proxy |
src/Uno.UI.DevServer.Cli/Helpers/ | Discovery, caching, process helpers |
src/Uno.UI.DevServer.Cli/Mcp/ | MCP server, client proxy |
src/Uno.UI.RemoteControl.Host/ | Host process: server, extensibility, IDE channel |
src/Uno.UI.RemoteControl.Host/Extensibility/ | Add-in loading and discovery |
src/Uno.UI.RemoteControl.DevServer.Tests/ | Unit and integration tests |
build/test-scripts/ | PowerShell integration test harness |
build/nuget/Uno.WinUI.DevServer.nuspec | NuGet package definition |
Key files: CliManager.cs (command router), UnoToolsLocator.cs (SDK/package discovery from global.json, NuGet cache, AmbientRegistry), TargetsAddInResolver.cs (fast add-in discovery via .targets XML), ManifestAddInResolver.cs (manifest-first discovery from devserver-addin.json), DotNetVersionCache.cs, McpStdioServer.cs, ProxyLifecycleManager.cs, McpUpstreamClient.cs, ToolListManager.cs, DevServerMonitor.cs (+ MonitorDecisions.cs, pure decision logic for testability), HealthService.cs/HealthReport.cs, DiscoveryIssueMapper.cs, ConnectionState.cs, SolutionFileFinder.cs; Host: RemoteControlServer.cs (WebSocket server, processors), AddIns.cs (discovery + assembly loading).
dotnet build src/Uno.UI.DevServer.Cli/Uno.UI.DevServer.Cli.csproj
dotnet build src/Uno.UI.RemoteControl.Host/Uno.UI.RemoteControl.Host.csproj
dotnet test src/Uno.UI.RemoteControl.DevServer.Tests/Uno.UI.RemoteControl.DevServer.Tests.csprojThe test project links source files from CLI/Host (rather than referencing outputs) to avoid circular dependencies — when adding a new source file for testing, add a <Compile Include> link in the .csproj. Integration tests: build/test-scripts/run-devserver-cli-tests.ps1 with -DevServerCliDllPath. Test conventions: MSTest + AwesomeAssertions, naming Test_WhenCondition_ShouldExpectation, sequential ([assembly: Parallelize(Workers = 1)]), temp dirs + injectable delegates for subprocess mocking.
Commands: start, stop, list, disco (discover env/SDK/active server), login (open Uno settings app), --mcp-app (MCP STDIO proxy mode).
Flags: -l trace, -fl <path> (file logging, {Date} token), --json (disco output), --addins-only, --mcp-wait-tools-list, --force-roots-fallback (legacy override; auto-detected now), --solution-dir <path>.
devserver-addin.json): ManifestAddInResolver resolves entry points directly, with minHostVersion gating..targets parse (~200ms): TargetsAddInResolver parses packages.json + buildTransitive/*.targets for <UnoRemoteControlAddIns> without invoking MSBuild.dotnet build evaluation; --addins (opt-in) bypasses this when the CLI pre-resolves paths.McpStdioServer.cs / ProxyLifecycleManager.cs bridge AI agents to the Host over STDIO: returns tool defs while the Host launches in the background, sends tools/list_changed when tools are ready, detects client roots support.
MCP roots — two modes: some clients support roots (Claude Code, VS Code Copilot, Cursor); others don't (Windsurf, JetBrains, Gemini CLI, Claude Desktop).
--solution-dir/cwd; requests roots if supported; auto-enables roots fallback (agent calls uno_app_initialize) when unresolved + no roots support.--force-roots-fallback: defers startup until uno_app_initialize. Rarely needed.
StartOnceGuard (MonitorDecisions.cs) prevents duplicate starts when roots arrive after an immediate start.Solution discovery (SolutionFileFinder): recursive .sln/.slnx search up to 3 levels deep, respects .gitignore (via git check-ignore), falls back to a skip list (node_modules, bin, obj, .vs, .idea, packages) when git is unavailable.
ConnectionState lifecycle (Mcp/ConnectionState.cs):
Initializing → Discovering → Launching → Connecting → Connected
↓ (crash)
Reconnecting → Discovering (cycle)
↓ (max retries)
DegradedTwo retry counters: DevServerMonitor (3 startup attempts) and ProxyLifecycleManager (3 crash→restart cycles).
CliManager.cs (follow start/stop/disco), add help in Program.cs, add an integration test in run-devserver-cli-tests.ps1.Program.cs (routing), Startup.cs (ASP.NET config); test via dotnet run from the Host dir.TargetsAddInResolver.cs (+ TargetsAddInResolverTests.cs); verify with uno-devserver disco --json in a real project.McpStdioServer.cs/ProxyLifecycleManager.cs/ToolListManager.cs; test with --mcp-app + an MCP client; check --mcp-wait-tools-list for clients without tools/list_changed.All launchers use direct Host launch; the controller path (--command start) is only for non-start commands. The CLI start (StartCommandHandler) manages the start lifecycle itself. Consequences:
--addins MUST stay opt-in: absence = MSBuild discovery unchanged.disco --json returns an activeServer field (null, or processId/port/mcpEndpoint/parentProcessId/startTime) from AmbientRegistry — the recommended way for extensions to detect a running server.Visual Studio (uno.studio): probes Uno.UI.RemoteControl.VS.EntryPoint and constructor signatures v2/v3 via reflection — never rename or change those constructor signatures without coordinating with the VS extension team; EntryPointRegressionTests.cs guards the contract. Launch resolves tools/rc/host/net{major}.0/Uno.UI.RemoteControl.Host.dll and launches directly with --httpPort/--ppid/--solution.
Rider (uno.rider): inspects project references for uno.winui.devserver, derives host path from dotnet --version; fallback dotnet build /t:GetRemoteControlHostPath.
VS Code (uno.vscode): delegates to the CLI — dotnet dnx uno.devserver start --httpPort {port} --ideChannel {guid} --solution {sln}; supports external-host debug via .uno.vscode.remote-control marker.
Host CLI contract: args via ConfigurationBuilder.AddCommandLine(); --addins opt-in for backward compatibility.
doc/articles/dev-server.mdsrc/Uno.UI.DevServer.Cli/health-diagnostics.md, src/Uno.UI.DevServer.Cli/addin-discovery.mdspecs/001-fast-devserver-startup/build/test-scripts/run-devserver-cli-tests.ps1, build/nuget/Uno.WinUI.DevServer.nuspecunoplatform/uno
82b7598
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.