Skip to content

Code Action workflows

Roslyn Workbench exposes Roslyn Code Fixes and refactorings through three Host-owned MCP tools:

  • list-code-actions discovers applicable actions and returns temporary opaque references;
  • prepare-fix-all evaluates one supported Fix All scope without staging changes; and
  • stage-code-action stages 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:

  1. Open a fully trusted workspace and check workspace-status.
  2. Start a transaction with transaction-start.
  3. Call list-code-actions against the transaction's current revision.
  4. Select one result using its title, precise location and diagnostic context where present.
  5. Pass its actionId and the current expectedSnapshot to stage-code-action.
  6. Inspect the result and call transaction-preview in transactional or autonomous-trusted mode, or transaction-review in approval-required mode.
  7. Commit the final revision with transaction-commit, supplying the review receipt when approval-required mode requests it, or discard it with transaction-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.
includeProvenance Optional, default false Includes a response-local provider reference on each returned action and a response-level provider identity dictionary.
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;
  • title and kind;
  • the precise project-aware location, including its document, span, line and column;
  • concise diagnostics with IDs and messages for a Code Fix; and
  • fixAllScopes when the selected Code Fix supports Fix All; and
  • providerId only when includeProvenance is true, referencing an entry in the response-level providers object. Each dictionary entry contains the provider type, assembly simple name and assembly version captured from the loaded runtime component.

Provider provenance is opt-in because it is intended for operator diagnostics and audit correlation, not routine action selection. The providers object deduplicates identities across the response; its keys are opaque response-local references and clients must resolve them by key rather than object order or compare them across responses. Equivalence keys, replay details, assembly paths, inferred package names and internal policy decisions are never added to discovery responses. 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 actionId representing the prepared Fix All operation;
  • the accepted scope;
  • affectedDiagnosticCount when authoritatively available; and
  • a bounded affectedDocuments collection.

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.

Preparation does not repeat provider provenance in its response. After staging, transaction-preview or transaction-review includes response-local providerId and optional fixAllProviderId references alongside each active Code Action revision, with the deduplicated identities in the response-level providers object. The Host also records structured local information events after successful Fix All preparation and successful Workspace staging; these events add diagnostic IDs, equivalence key and Fix All scope for operator correlation without placing them in the agent response. Provenance is informational and does not introduce an additional elicitation or approval step.

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.