Code Action workflows
Roslyn Workbench exposes Roslyn Code Fixes and refactorings through three Host-owned MCP tools:
list-code-actionsdiscovers applicable actions and returns temporary opaque references;prepare-fix-allevaluates one supported Fix All scope without staging changes; andstage-code-actionstages either one discovered action or one prepared Fix All action into the active transaction.
MCP tools/list is authoritative for their live schemas and metadata. Code Actions are composed once when the Host starts, are reported as a Host component rather than a plugin, and do not add one MCP tool per Roslyn provider.
Safe staging workflow
Use the normal workspace and transaction workflow:
- Open a fully trusted workspace and check
workspace-status. - Start a transaction with
transaction-start. - Call
list-code-actionsagainst the transaction's current revision. - Select one result using its title, precise location and diagnostic context where present.
- Pass its
actionIdand the currentexpectedSnapshottostage-code-action. - Inspect the result and call
transaction-preview. - Commit the final revision with
transaction-commit, or discard it withtransaction-rollback.
Successful staging advances the transaction revision. Discover again before selecting another action for that new revision. Do not assume that a title, location or reference from an older revision still identifies the same operation.
Discover actions
list-code-actions accepts:
| Argument | Requirement | Meaning |
|---|---|---|
workspace |
Optional when exactly one workspace is loaded | Selects the loaded workspace. |
document |
Required | Selects one source document by workspace-relative path or document ID, with an optional project selector for linked or multi-target documents. |
range |
Optional | Omitted means complete-document discovery; a positive length means selection discovery; zero length means caret discovery. Positions are zero-based UTF-16 values. |
expectedSnapshot |
Required | The complete snapshot object against which the document and range were resolved. Echo the published value unchanged. |
kinds |
Required | 1 discovers Code Fixes, 2 discovers refactorings and 3 discovers both. |
diagnosticIds |
Optional | Narrows Code Fix discovery to the supplied diagnostic IDs. |
limit |
Optional, default 50 |
Bounds the returned action leaves. Zero returns no items. |
For example, this request discovers Code Fixes across one document:
{
"workspace": {
"workspaceId": "11111111-1111-1111-1111-111111111111"
},
"document": {
"path": "src/Example.cs"
},
"expectedSnapshot": {
"workspaceId": "11111111-1111-1111-1111-111111111111",
"workspaceEpoch": 1,
"snapshotId": "22222222-2222-2222-2222-222222222222",
"transactionRevision": 0
},
"kinds": "CodeFixes",
"diagnosticIds": [
"IDE0003"
],
"limit": 50
}
The successful data.actions value is a bounded collection with items, hasMore and an optional totalCount. Each item contains:
actionId, an opaque temporary UUID reference;titleandkind;- the precise project-aware
location, including its document, span, line and column; - concise
diagnosticswith IDs and messages for a Code Fix; and fixAllScopeswhen the selected Code Fix supports Fix All.
Provider identities, CLR types, equivalence keys, replay details and internal policy decisions are deliberately omitted. Use the returned title, location, diagnostics and supported scopes to choose an action.
Stage one action
stage-code-action is the only Code Action mutation tool. It requires an active transaction:
{
"workspace": {
"workspaceId": "11111111-1111-1111-1111-111111111111"
},
"actionId": "33333333-3333-3333-3333-333333333333",
"expectedSnapshot": {
"workspaceId": "11111111-1111-1111-1111-111111111111",
"workspaceEpoch": 1,
"snapshotId": "22222222-2222-2222-2222-222222222222",
"transactionRevision": 0
}
}
The Host re-discovers the exact action, validates that it still has one unambiguous match, evaluates its operations, rejects unsupported effects, and stages the resulting source-only candidate through the Workspace transaction pipeline. It never writes source files directly. A successful stage consumes the reference and returns the mutation summary, compact preview and updated transaction revision.
Prepare and stage Fix All
Only use prepare-fix-all when the selected Code Fix lists the requested scope in fixAllScopes. Scope values are 0 for document, 1 for project and 2 for solution.
{
"workspace": {
"workspaceId": "11111111-1111-1111-1111-111111111111"
},
"actionId": "33333333-3333-3333-3333-333333333333",
"scope": "Document",
"maxChanges": 50,
"affectedDocumentsLimit": 20,
"expectedSnapshot": {
"workspaceId": "11111111-1111-1111-1111-111111111111",
"workspaceEpoch": 1,
"snapshotId": "22222222-2222-2222-2222-222222222222",
"transactionRevision": 0
}
}
Preparation is read-only. It revalidates the originating Code Fix, evaluates the selected scope, rejects an operation exceeding maxChanges, and records the exact normalised source operation that was approved before returning:
- a new
actionIdrepresenting the prepared Fix All operation; - the accepted
scope; affectedDiagnosticCountwhen authoritatively available; and- a bounded
affectedDocumentscollection.
Pass the new prepared actionId, not the originating action reference, to stage-code-action with the same current snapshot. The Host recreates and normalises the Fix All operation, then requires its affected projects, paths, change kinds and content checksums to match the prepared operation exactly and still satisfy maxChanges. If the provider produces a different operation, staging rejects it with MutationCandidateChanged, consumes the invalid prepared reference and instructs the caller to resolve the target again. A matching operation proceeds through preview, history, rollback and commit exactly as a single action does.
Reference and snapshot rules
list-code-actions validates the complete expectedSnapshot before resolving its document or interpreting its UTF-16 range. A range copied from a different immutable solution snapshot is therefore rejected instead of being reinterpreted against different source text, even if its epoch and transaction revision happen to match. Action references are process-local, bounded, temporary and tied to the exact Workspace snapshot from which they were created. Their lifetime defaults to five minutes and is configured with --code-action-reference-lifetime. Successful staging consumes a reference; merely listing or preparing does not change transaction state.
If a reference is unknown, expired, evicted, already consumed, or no longer matches the selected snapshot, the Host returns a structured failure such as ActionExpired, SnapshotMismatch or ActionAmbiguous with next: resolveTargetAgain. Follow that recovery action: inspect the current Workspace state, then list and select the action again. Never edit an actionId, reconstruct one from response metadata, or reuse it against a different snapshot.
Availability and exclusions
The Host composes installed Roslyn Code Fix and refactoring providers at startup, then applies an exception policy to omit actions that cannot safely use this workflow. Examples include actions requiring interactive options or external UI, package or reference installation, unsupported project-system changes, or operation shapes outside the source-only transaction contract.
An omitted action is not evidence that the provider is missing: it may be inapplicable at the selected location, filtered by the request, unavailable in the loaded project, or excluded by policy. Use server-status with detail: Full to inspect Code Action component availability and startup diagnostics. Third-party plugins cannot register Code Actions or use Host Code Action services; they add ordinary query and mutation tools through the separate plugin API.