| title | Unified Remote API and MCP |
|---|
AXSG now has one shared remote-operation layer that serves LSP, MCP, preview orchestration, and studio/runtime remote surfaces.
The important design choice is:
- reuse JSON-RPC transport infrastructure across LSP and MCP
- do not reuse LSP semantics as if they were MCP
LSP and MCP both use JSON-RPC 2.0 and commonly run over framed stdio transports, but they solve different problems:
- LSP is document and editor oriented
- MCP is tool and resource oriented
AXSG therefore shares:
- message framing
- serialization options
- request and response helpers
- transport-neutral command routers
- transport-neutral query and mutation services
AXSG does not share:
- lifecycle assumptions
- method names
- editor-specific payloads
That keeps the remote stack reusable without forcing editor concepts onto MCP clients.
| Surface | Adapter | Shared layer underneath |
|---|---|---|
| Standalone language server | XamlToCSharpGenerator.LanguageServer.Tool |
RemoteProtocol.JsonRpc plus shared query services |
| Workspace MCP host | XamlToCSharpGenerator.McpServer.Tool |
RemoteProtocol.JsonRpc plus McpServerCore plus shared query services |
| Preview helper command transport | PreviewHostCommandRouter |
shared preview payload contracts |
| Preview MCP host | PreviewHostMcpServer |
shared preview payload contracts plus shared MCP core |
| Studio remote design server | AxsgStudioRemoteCommandRouter |
shared runtime query services plus shared studio contracts |
| Runtime MCP host | XamlSourceGenRuntimeMcpServer |
shared runtime query services plus shared MCP core |
This package is the reusable transport and contract layer. It contains:
- JSON-RPC framing helpers
- MCP server core
- preview host contracts
- studio remote contracts
It is the package to reuse when you need AXSG remote protocols without copying transport code.
The transport-neutral query layer now lives in services such as:
AxsgPreviewQueryServiceAxsgRuntimeQueryServiceAxsgWorkspaceLanguageQueryService
The transport-neutral runtime mutation layer now lives in services such as:
AxsgRuntimeHotReloadServiceAxsgRuntimeHotDesignServiceAxsgRuntimeStudioService
Those are consumed by LSP, MCP, preview, and studio adapters so the same operation shape does not get reimplemented per adapter.
AXSG intentionally has more than one MCP host because workspace state and live runtime state are not the same thing.
This host:
- runs independently as
axsg-mcp - sees files, projects, and workspace options
- is best for preview project-context resolution, metadata/projection queries, cross-language navigation, and rename planning
It does not automatically attach to a live Avalonia app.
This host:
- runs inside the Avalonia process
- sees hot reload, hot design, and studio state directly
- supports
resources/subscribe, focused snapshot resources, per-build hot design workspace resources, and event-style resource updates
This is the host you want for dotnet watch, hot reload, hot design, and live-app inspection.
This host:
- runs inside the preview helper process
- exposes explicit preview lifecycle and preview hot-reload tools/resources
- supports dynamic tool and resource catalogs as the active preview session starts or stops
This is the host you want when preview is the system under test.
The VS Code extension is a product surface, not just a transport wrapper. It still owns:
- activation behavior
- lazy language-server startup
- VS Code preview webview integration
- editor middleware and inline-C# projection interop
The extension can reuse the shared remote-operation layer, but it still needs editor-specific orchestration that does not belong in MCP or LSP core contracts.
AXSG now uses a capability-based model:
- workspace MCP host: query-oriented, poll after changes
- runtime MCP host: subscribe to status, focused snapshot, and event resources
- preview MCP host: subscribe to lifecycle resources and react to list-changed notifications
This split matches the real ownership model of the processes instead of pretending one host can answer every question equally well.
Preview MCP now supports in-process live preview application directly through:
axsg.preview.hotReload
That operation is intentionally different from the lower-level:
axsg.preview.update
hotReload waits for the preview session to complete the in-process apply and returns the concrete result payload. update is still available for dispatch-only flows and compatibility with clients that already consume the lifecycle resources asynchronously.
This keeps the preview host aligned with the rest of AXSG’s shared remote-operation model:
- transport-neutral preview session/router underneath
- MCP adapter on top
- status and event resources as the subscription surface
The runtime MCP host now distinguishes between:
- coarse snapshots such as
axsg://runtime/hotdesign/status - focused snapshots such as
axsg://runtime/hotdesign/workspace/current,.../document/selected, and.../element/selected - dynamic per-build workspace resources under
axsg://runtime/hotdesign/workspace/by-build-uri/<escaped-build-uri>
That split exists so clients can keep local state synchronized without rereading the entire coarse workspace after every small mutation.