Tools Reference
Parameters and defaults for the MCP tools the Fuse server exposes to AI clients.
The Fuse MCP server exposes a loop-shaped surface of eight tools (fuse_workspace, fuse_find, fuse_context, fuse_impact, fuse_check, fuse_test, fuse_refactor, fuse_review), plus fuse_reduce as the one out-of-loop utility. Each tool is one mental act, so the loop is teachable: after an edit run fuse_check; before a signature change run fuse_impact; before done run fuse_review. MCP (Model Context Protocol) is the open protocol that lets an AI client call external tools. This page documents each tool and its parameters so an agent or its author can choose the right call and supply correct arguments.
This page is for engineers writing agent instructions and for experts who need the exact default of each parameter. For the recommended order in which to call these tools, see Context for an agent. The equivalent CLI flags are in Commands Reference. For a single table mapping each intent to MCP, CLI, and host RPC, see API surfaces.
Purpose and scope
Indexed reads, including fuse_workspace action=status, validate or build the persistent index on first use, so an explicit fuse_workspace action=index call is optional. The CLI-only fuse diagnostics command remains read-only and reports not_indexed without creating .fuse/fuse.db. The index lives in one SQLite file at the repository root: .fuse/fuse.db. Automatic index and reconcile writes modify derived data only. The sole MCP path that writes the working tree is fuse_workspace action=apply, which is a dry run unless write=true. Token budgets are honored by the plan, and secret redaction runs before any source reaches the payload.
Every operation except fuse_reduce requires a Git repository identity. Fuse walks upward from path to the nearest .git directory or file, then uses that repository root for scanning, the daemon, locks, and the database. A folder outside Git returns workspace_identity_unresolved: before any workspace operation starts. fuse_reduce remains available because it does not use the workspace index.
Choosing a tool:
- Use
fuse_reviewfor PR or change work when a git base exists. - Use
fuse_findwithkind=service|request|route|configwhen a task names wiring, orkind=taskfor an open-ended task. - Use
fuse_contextafterfuse_find, unless you want one-shot context. - Use
fuse_findwithkind=symbol|path|textfor exact lookup, orkind=neighborsto explore the callers and implementers of a symbol.
Tool tiers
Each MCP operation belongs to one of four tiers. The tier names what must be available before the operation can answer, not how fast it is.
| Tier | Tools | Needs .fuse/fuse.db |
|---|---|---|
| offline | fuse_reduce | No |
| repository | fuse_workspace action=apply; fuse_impact package-upgrade mode | No, but a Git repository identity is required |
| compiler | fuse_check, fuse_refactor, fuse_test candidate racing | No for compiler verification; the index is optional enrichment only |
| indexed | fuse_workspace (status, index, map, doctor), fuse_find, fuse_context, fuse_impact symbol mode, fuse_review, fuse_test covering-test selection | Yes (built on first use for read tools, or warm read when already present) |
fuse_workspace action=status validates or warms the index. fuse diagnostics is the no-write CLI inspection path.
Compiler-tier tools discover projects and run the toolchain first. fuse_check verifies a proposed edit before
opening the index; repair packets are attached afterward when the store is available, with a named omission note
when it is not. fuse_refactor loads the solution through Roslyn without the store. fuse_test selects covering
tests from persisted tests edges (indexed-tier); it validates or warms the index first and returns the bounded
availability header when a build or contention prevents selection.
Indexed-tier read tools use a warm read-only open when the database already exists. They acquire the writer lock only when the index must be created, reconciled, or upgraded.
Operational error prefixes
MCP tools return errors as a single prefixed string rather than throwing. Match the prefix to decide the next step:
| Prefix | Meaning | Agent retry guidance |
|---|---|---|
index_busy: | The index writer lock or SQLite database is busy on an explicit write path (action=index) or a tool that does not use the read header contract. | Retry after a short pause, or run fuse host so one shared daemon serves the root. |
index_not_built: | No completed index exists at .fuse/fuse.db. | Indexed MCP reads normally build it automatically. Retry the same call, or run fuse_workspace action=index when the client cannot keep the server alive long enough to finish. |
workspace_not_found: | The path directory does not exist. | Fix the workspace path. |
workspace_identity_unresolved: | The requested folder is not inside a Git repository, so Fuse has no canonical root for workspace-scoped tools, its daemon, lock, and index. | Use native file tools for that folder. fuse_reduce remains available for known files or raw content. |
validation_error: | The tool arguments are invalid or incomplete. | Correct the parameters and call again. |
index_rebuilding: | The store's derived data was rebuilt (version or schema mismatch, corruption, or a missing/inconsistent full-text index) and is being repopulated from source. A search against a store missing its chunk_fts table maps here, never to internal_error. | Retry after a few seconds; the next pass serves a working, searchable index. |
internal_error: | An unexpected failure (including cancellation). | Retry once; if it persists, run fuse_workspace action=doctor and check daemon or disk health. |
When a read tool cannot open the index yet (another process holds the writer mutex, SQLite is busy, or a cold build is still committing), it returns the availability header as the tool result body instead of hanging or throwing. The header always leads with index_state: and files_indexed: (when known), then the availability: line. Retry the same call after a short pause.
Availability header
Store-backed read tools (fuse_find, fuse_context, fuse_impact, fuse_review, and related resources) prepend this header to their answer, or return it alone when the read cannot proceed yet.
index_state: ready
files_indexed: 1284
availability: index mode semantic; full-text search available; tier-1 build capture configured; verify serves oracle-grade; workspace store-backed; up to date.index_state is one of:
| Value | Meaning |
|---|---|
not_indexed | No completed index is available. MCP status normally warms first; CLI fuse diagnostics can report this without writing. A completed empty repository is ready with zero files. |
building_syntax | Syntax-first cold start: the syntax tier is live and a semantic upgrade is pending. |
upgrade_pending | The index exists at syntax or partial tier and a background semantic or tier-1 upgrade is running. |
ready | The index is current for reads at its loaded tier. |
index_busy | The writer lock or SQLite blocked this read; retry shortly. |
index_rebuilding | The store failed an integrity check (missing or inconsistent full-text index, or symbols with zero chunks) and is being rebuilt; it is never reported ready in this state. |
stale_as_of | A bulk change outran per-file reconcile and a full replacement is pending. The indexed read coordinator starts that replacement automatically. |
files_indexed is omitted only when the store cannot be read (for example an exclusive SQLite lock). fuse_workspace action=status warms or validates first; fuse diagnostics reports the stored state without starting a build.
fuse_workspace
Workspace status and lifecycle: the loop's first stop and the one explicit tree-write path. Select the operation with action.
doctor: the semantic load tier, the selected solution (R24), per-project load reasons, the index integrity result (R31), the files skipped during indexing (R35: too large, unreadable), and the runningfuse hostdaemons with their served roots and versions (R28).status(default): validates or warms the repository index, then reports the index mode, verification grade, freshness, andindex_state(building_syntax,upgrade_pending,ready,index_busy,stale_as_of), plusfiles_indexedwhen known.index: build or refresh the persistent semantic index. The index mode issemanticwhen the workspace loads through MSBuild/Roslyn,partialwhen some projects fall back, andsyntaxwhen no project loads.map: the workspace map of indexed symbols, routes, and counts.doctor: the per-project semantic-load diagnosis (why a project loaded at the tier it did). The diagnosis is served from the stamp written into the index at index time (R43), so doctor is sub-second and reflects what was actually indexed - it does not re-run the full MSBuild/Roslyn load (measured tens of seconds on a large repo). The summary header uses the same fastindex_metaread asstatus. Passrefresh=trueto force a live MSBuild load instead (or when no stamp is present yet, doctor falls back to a live load automatically). The output names its source (diagnosis source: warm indexordiagnosis source: live MSBuild load).apply: write a proposed single-file edit (filepluscontent) to the working tree. This is the server's one explicit tree-write path: it is a dry run that only reports the change unlesswrite=true, and it refuses anyfilethat resolves outside the workspace root. The write is atomic (a temp file on the same volume is renamed into place, so a reader never sees a half-written file and an interrupted write leaves the original intact) and conflict-checked: passexpectedHash(the SHA-256 hex of the content the edit was derived from) and apply refuses with avalidation_error:conflict rather than clobbering when the file changed since (a concurrent edit landed, or the file was deleted). The conflict is reported even on a dry run.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
action | string | status | status, index, map, doctor, or apply |
path | string | . | Workspace directory |
detail | string | all | For map: symbols, routes, or all |
maxRows | int | 200 | For map: maximum rows per section |
file | string | required (apply) | For apply: the repo-relative file to write |
content | string | required (apply) | For apply: the full new content to write |
write | bool | false | For apply: actually write (otherwise a dry run) |
expectedHash | string | "" | For apply: the SHA-256 (hex) of the content the edit was derived from. When set, apply refuses (conflict) if the file changed since, rather than clobbering it |
refresh | bool | false | For doctor: force a live MSBuild load diagnosis instead of reporting the diagnosis stamped in the warm index (R43) |
Task localization (fuse_find kind=task)
Localize a task to ranked candidate files and symbols with fuse_find and kind=task. Returns candidates with reasons and token costs, no source bodies. The cheap first step of an iterative workflow; follow with fuse_context. Pass the task as query.
The graded response
Task localization grades each request into one of three states, computed from the candidate
score distribution with no model, and leads its output with the state (localize [confident]: ...):
- confident: a candidate or a tight cluster stands clear; the tight set is returned and precision is high.
- partial: there is signal but no clear winner; a small best-effort set is returned, flagged low-confidence, with a navigation map of refinement options.
- insufficient: no usable anchor; the engine refuses and routes, returning a navigation map (top candidate areas, entry-point files and routes, nearest symbols) and an explicit ask for a sharper input, rather than a low-precision candidate list.
The navigation map turns a refusal into a navigation step: an agent can use an area or nearby symbol as a better-anchored query. The MCP union uses best-effort mode. A partial or insufficient request can return candidates, but a no-signal title such as a merge or dependency bump abstains because ranking would return noise.
Wiring resolution (fuse_find kind=service|request|route|config)
Deterministically resolve .NET wiring with fuse_find: kind=service (to its implementation), request (to its handler), route (to its action), or config (to its options type). No source bodies. Pass the identifier as query.
fuse_context
Plan and emit context (source bodies at mixed render tiers, a semantic manifest, and per-file provenance) for a set of seeds. Feed it the file paths from fuse_find (kind=task) or the names it resolves from wiring.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
path | string | . | Workspace directory |
seeds | string[] | null | Symbol seeds |
files | string[] | null | File path seeds (for example paths returned by localize) |
services | string[] | null | Service seeds to resolve and expand |
requests | string[] | null | Request or command seeds to resolve and expand |
configs | string[] | null | Config section seeds to resolve and expand |
routes | string[] | null | Route seeds |
depth | int | 2 | Graph expansion depth |
maxTokens | int | 0 | Token budget; must-keep seeds are always included (0 means no limit) |
format | string | xml | xml, markdown, or json |
sessionId | string | null | Session id; files already sent unchanged in the session are elided |
fuse_review
Review the semantic impact of a change since a git base ref: the changed files, the blast radius (callers, DI consumers, route and request handlers, options consumers, tests), and the packed context. The first tool to reach for in PR and change work.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
path | string | . | Workspace directory |
changedSince | string | HEAD | Git base ref to diff against (branch, commit, or HEAD~N) |
maxTokens | int | 0 | Token budget; changed files are always kept (0 means no limit) |
includeTests | bool | true | Include related test files |
format | string | xml | xml, markdown, or json |
sessionId | string | null | Session id; files already sent unchanged in the session are elided |
handoff | bool | false | Produce a paste-ready PR handoff packet instead of the review context; refuses while the check session has unresolved introduced errors |
checkSession | string | "" | For handoff: the fuse_check session id to gate on |
maxChangedFiles | int | 0 | Maximum changed files before review returns a bounded partial. 0 uses FUSE_REVIEW_MAX_CHANGED_FILES or the default of 150 |
Bounded on a large diff: maxTokens bounds the output, but a huge changed-file set (a long-lived branch, an ancient base ref, or a mega-commit) would otherwise make blast-radius resolution run unbounded. When the changed-file count exceeds the cap (default 150, override with maxChangedFiles or FUSE_REVIEW_MAX_CHANGED_FILES), the review returns the changed-file list and a note ("the diff since {ref} spans N changed files, above the review cap ...; narrow the base ref") instead of resolving the graph for hundreds of files. A normal PR-sized diff is unaffected and gets the full review.
The manifest opens with a public API delta section: the public and protected members added, removed, or changed between the git base ref and the working tree, each flagged breaking (a removal, a signature change, or an accessibility reduction) or additive. A purely internal change shows no section. The surface is compared by extracting the public and protected symbols of each changed C# file on both sides (the base side read from the base ref, the current side from the working tree), so a contract break is the first thing a reviewer reads rather than something CI discovers. In the JSON format the section rides a dedicated apiDelta field so the payload stays valid JSON. Out of scope, and not flagged: binary-compatibility subtleties that are not a source-visible surface change, specifically default parameter value changes and const inlining.
The review also carries a graded claims block: the changed-file set (git-truth, so verified) and, when the surface moved, a partially verified claim that the change alters the public API. Each claim names its evidence. See claim grades for the grade table and the session ledger.
With handoff=true the tool returns a paste-ready PR body instead of the review context: the changed files, the public API delta, the compiler-gate status, and the named residual risk. It is gated, not a controller - while the checkSession still has unresolved introduced errors it refuses and returns the red summary rather than a packet, so a change that does not yet pass the compiler cannot be handed off.
fuse_find
The find union: locate what a task needs, keyed by kind. One tool for exact lookup, wiring resolution, signatures, neighbors, and task localization, so a client learns one entry point instead of five. The query carries the input for the selected kind.
- Exact lookup (
kind=symbol|path|text|all): a symbol by name, a file by path fragment, or text by full-text search. Use instead of broad grep when the name or path is known. - Wiring (
kind=service|request|route|config): resolve the query to its implementation, handler, action, or options type. kind=signatures: the query symbol's exact signature. When a resident workspace serves the root (FUSE_RESIDENT), a qualified name (a namespace-qualified type, orType.Member) resolves from the compiler's real metadata, so a referenced package's API answers from the compiler rather than the store - the hallucinated-package-API check. Without a resident workspace, or for a name it does not resolve, the store-backed signature index answers.kind=neighbors: the query symbol's callers and implementers, ranked with provenance.kind=task: rank candidate files and symbols for the query, with the graded refuse-and-route contract (see The graded response).
| Parameter | Type | Default | Meaning |
|---|---|---|---|
query | string | required | The name, path fragment, text, wiring identifier, or task |
path | string | . | Workspace directory |
kind | string | all | symbol, path, text, all, service, request, route, config, signatures, neighbors, or task |
fuse_refactor
Compiler-executed, verify-gated refactors returned as a staged diff, never touching the working tree. Select the operation with operation:
rename(default): renames a symbol and every reference through Roslyn's rename engine. Because Roslyn drives it, a same-named but unrelated symbol (a local, a different type) is not renamed, which a textual find-and-replace cannot guarantee.add-parameter: adds a trailing parameter to a method and its whole override/interface family, threading an explicit argument (theargumentvalue) into every call site.add-cancellation-token: adds aCancellationTokenparameter and threads an in-scope token into every call site that has one, listing token-less call sites as manual follow-ups so a human threads a real token there.remove-parameterandreorder-parameters: see the change-signature family above.extract-interface: generates an interface from a class's public instance methods and properties (named withnewName, elseI<Class>) and makes the class implement it, returned as the staged full new file content.move-type: moves a top-level type (symbol) into its own new file named after it, removing it from its current file; returns both the new file and the trimmed original as staged full content.apply-codefix: applies the repository's own analyzer code fix fordiagnosticIdinfile, driving that diagnostic to zero. It discovers the analyzers and their[ExportCodeFixProvider]fixes from the project's analyzer references (reflection), runs the analyzer, applies the offered fix to each occurrence, and returns the staged file only when the diagnostic reached zero with no new compile error. This turns a whole diagnostic class into one call.
The signature and type operations are verified, not just generated: after the rewrite, Fuse recompiles the solution and returns the diff only when no new diagnostic is introduced. A change the rewriter does not get exactly right (a call site it cannot resolve, a delegate conversion it breaks) makes the compile fail, so the tool abstains naming the offending sites rather than returning a mostly-right diff. Rename and these operations answer only when the whole solution loads cleanly and abstain otherwise, because a partial change is worse than none. Review the diff and re-check with fuse_check before applying.
The design-time solution load is the dominant cost (a fresh MSBuildWorkspace open, several seconds on a large repo). The daemon holds the loaded Roslyn Solution per root and reuses it across calls (R42), so the second and later refactors in a session skip that load and return in well under a second; fuse_workspace action=doctor's live load shares the same held solution. A freshness check reloads when the tracked source changed, so a reused solution produces the exact diff a cold load would. Memory is bounded by an LRU cap (FUSE_WARM_SOLUTION_CAP) and an idle window (FUSE_WARM_SOLUTION_IDLE_MINUTES).
| Parameter | Type | Default | Meaning |
|---|---|---|---|
path | string | . | Workspace directory |
symbol | string | required | The symbol to rename, or the method name for a signature operation |
newName | string | required (rename) | The new name |
operation | string | rename | rename, add-parameter, add-cancellation-token, remove-parameter, reorder-parameters, extract-interface, move-type, or apply-codefix |
containingType | string | null | The declaring type's simple name, to disambiguate a method shared across types |
parameterType | string | required (add-parameter) | The new parameter's type, as written in source |
parameterName | string | required (add-parameter) | The new parameter's name (defaults to cancellationToken for add-cancellation-token) |
argument | string | default | The argument expression added at every call site (add-parameter) |
newOrder | string | required (reorder-parameters) | The parameter names in the desired order, comma-separated |
diagnosticId | string | required (apply-codefix) | Diagnostic id to fix |
file | string | required (apply-codefix) | Repo-relative file containing the diagnostic |
Two more operations extend the family: remove-parameter drops a parameter (named by parameterName) and its argument at every call site, and reorder-parameters reorders parameters into newOrder. Both are safety-gated beyond the compile check (see the abstention table).
Abstention classes (change-signature)
The signature operations refuse rather than risk a wrong change in these shapes:
| Class | Why it abstains |
|---|---|
params tail | A trailing parameter after a params array changes call binding; refused by a pre-check. |
| Ambiguous method | The name matches more than one method (an overload set, or the same name across types); pass containingType to disambiguate. |
| Method-group / delegate conversion | The method is used as a delegate (Func<...> f = obj.M;); adding or reordering a parameter breaks the conversion, caught by the recompile gate. |
| Used parameter (remove) | The parameter is referenced in a method body; removing it would not compile, and the site is named. |
| Side-effecting dropped argument (remove) | A call site passes a non-trivial argument (a call, an object creation) whose removal could drop a side effect; a silent behavior change, so it abstains naming the site. |
| Positional call site (reorder) | A reorder is safe only when every call site names its arguments; a positional call site would silently rebind, so any positional site abstains. |
| Any residual compile error | Any call site or declaration the rewriter did not update correctly; the recompile gate names it and abstains. |
fuse_check
Typecheck a proposed single-file edit and get the compiler errors and warnings the change would produce, without writing the file. Verification never shrugs: every answer is stamped with a verification grade.
- oracle grade: a speculative in-memory typecheck against the build-captured compilation (via the out-of-process build-capture worker, configured with
FUSE_BUILD_CAPTURE_WORKER). The patch is applied to the rehydrated compilation in memory; no disk write, no second build. The worker is pooled and kept alive per captured compiler log (R48): it rehydrates the log once and answers many checks, so the second and later checks in a session skip the rehydrate (measured ~1.7s spawn-per-call versus near-instant reuse). The pooled verdict is identical to the spawn-per-call verdict, and a cold or absent worker falls back to spawn-per-call. Bounded byFUSE_CHECK_WORKER_CAPandFUSE_CHECK_WORKER_IDLE_MINUTES. - build grade: when no oracle substrate is available, Fuse runs the real
dotnet buildtoolchain scoped to the owning project and parses its diagnostics into the same shape. This is ground truth (the compiler itself answered) at the cost of build latency (tens of seconds), reported with the elapsed time. The working tree is never written: the owning project is mirrored to a temporary directory, the proposed content replaces the one file in the copy, its<ProjectReference>includes are rewritten to absolute paths pointing at the untouched originals, and the build runs there. - abstain: returned only when even the toolchain cannot run (no buildable project, or a build that exceeds the timeout), always naming the missing prerequisite.
The response opens with the grade line so a client knows the class of truth and the latency to expect before reading the verdict. When a diagnostic is an API-shape error an agent commonly hits (CS1061 a member that does not exist, CS0246 a type that could not be found), the response attaches a repair packet when the index is available for symbol lookup: the receiver type's real members with the nearest names first, or the nearest type names in the index. When the index is busy or not built, verification still runs at build or oracle grade and a named note reports that repair packets were omitted. A packet is added only where a concrete suggestion is possible, never as empty padding.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
path | string | . | Workspace directory |
file | string | required (single-file mode) | The repo-relative path of the file being changed |
content | string | required (single-file mode) | The proposed full new content of that file |
session | string | null | Delta mode: a session id (see below) |
full | bool | false | Delta mode: return the whole current diagnostic set instead of the delta |
markGreen | bool | false | Delta mode: reset the session baseline to the current diagnostics |
analyzers | bool | true | Also run the repo's configured analyzers and nullable warnings at editorconfig severities (CI parity), when a resident workspace serves the root |
Analyzer parity
By default, when a live resident workspace serves the root, the check runs the repository's configured analyzers and nullable warnings against the overlay compilation at the severities the repository's editorconfig sets, and merges them with the compiler diagnostics. This makes a green check match what CI's build step enforces, not just the raw compiler errors, so a local green is not followed by a CI red on a StyleCop or nullable warning. A rule silenced in editorconfig stays silent. Analyzers add real cost (hundreds of milliseconds on a large analyzer set), so they default on for this single-file verify but off for the hot per-edit delta path; the availability header names the setting. Without a resident workspace the setting has no effect (the build-capture and build-grade paths report their own diagnostics).
Delta mode
Pass a session id with no content and fuse_check answers the inverse question: not "would this proposed edit compile" but "what did my on-disk edits change". It returns the diagnostics introduced or resolved since the session baseline, each introduced error carrying a repair packet where one applies. The baseline is set on the first call for a session and persists to the store, so a restarted process resumes the session with its baseline intact; markGreen: true resets the baseline to the current state, and full: true returns the whole current diagnostic set instead of the delta. Delta mode never runs a build (that would defeat the point), so it reads the current whole-state diagnostics from a live resident workspace and abstains, naming the prerequisite, when none serves the root. Matching ignores the line number so an edit that shifts a diagnostic up or down the file does not read as a phantom change.
fuse_impact
Blast radius for a symbol before you edit it: the callers, implementers, consumers, and referencing types a change would touch, enumerated from the persisted semantic graph (reference edges plus wiring edges). No source bodies. The exact signature-change break set (which call sites would no longer bind) is an oracle-grade answer that needs a build capture; until one is available the tool reports it as unavailable rather than guessing, and returns the graph-grade blast radius. Reverse traversal is the store's incoming-edge query, so the result is deduped by source node. The response also lists the covering tests for the symbol: the tests that reach it through DI-resolved tests edges, called out distinctly from the blast radius so you can run just that subset with your own dotnet test --filter. The covering set is a lower bound (a test reached only by reflection has no edge and is not listed), never presented as "all the tests". The response opens with the availability header (index_state, files_indexed when known, then index mode, whether build capture is configured, and the freshness stamp) so a client can see the grade of the answer before reading it.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
symbol | string | required (blast-radius mode) | The symbol (simple or qualified name) whose blast radius to compute |
path | string | . | Workspace directory |
limit | int | 50 | Maximum impacted items to return |
package | string | null | Package-upgrade mode: the NuGet package id whose bump to analyze |
fromVersion | string | null | Package-upgrade mode: the currently referenced version |
toVersion | string | null | Package-upgrade mode: the target (upgrade) version |
session | string | "" | Append graded claims to this session ledger |
Package-upgrade mode
Pass package, fromVersion, and toVersion and fuse_impact becomes a NuGet upgrade oracle: it diffs the public API of the two package versions (resolved from the local NuGet cache) and lists the breaking public-API changes the bump would introduce (removed members, signature changes, accessibility reductions), so the anxiety of a package upgrade is answerable before the lockfile changes. It abstains with a reason when a version is not in the local cache (the offline case). It names its blind spots on every report: reflection and dynamic usage are invisible to a metadata diff, and repo call-site intersection is bounded by the reference graph, which does not track external-package call sites (so the answer is the version-to-version break set, not a repo-specific "your N call sites break" count). Recorded example: System.Text.Json 4.7.2 to 8.0.0 is flagged breaking (the public JsonClassInfo was removed), while additive-only major bumps of System.Collections.Immutable and Microsoft.Extensions.DependencyInjection.Abstractions report no break.
The response also carries a public API surface line: whether the target symbol is on the public or protected surface, so before editing you know whether the change is contract-relevant (removing it, reducing its accessibility, or reshaping its signature would break external callers). The flag is conservative to avoid training you to ignore it: a positive "public" is asserted only from the recorded public-API flag, which is reliable for types in any index mode and for members at the semantic tier; a member in syntax mode, where accessibility is not resolved, is reported undetermined rather than guessed either way.
fuse_test
Run the covering tests for a symbol: the tests that reach it through the persisted tests edges (the same selection fuse_impact reports), run scoped by filter to just those test types so the whole suite never runs. The verdicts come back per test. When no tests edge reaches the symbol the tool reports the selection-only floor with nothing to run (a test reached only by reflection or a source generator has no edge and is not selected, so the set is a lower bound). Covering selection is indexed-tier: when .fuse/fuse.db is missing the tool returns index_not_built:; when the store is contended it returns index_busy: without starting an index build. This first cut runs at build grade: it invokes the real dotnet test scoped to the covering set, so it works on any repository and any test framework (the target's own adapter runs the tests), at the cost of the build. The emit-and-run fast path (run the speculative compilation's assembly in an isolated micro-host with no build) is future work behind a flag; the response stamps the grade. A run that exceeds its budget is killed and reported as timed out, never left hanging.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
symbol | string | required for a covering-test run | The symbol whose covering tests to run |
path | string | . | Workspace directory |
limit | int | 20 | Maximum covering test types to run |
candidates | string | empty | Candidate racing: a JSON array of single-file edits to race |
maxCandidates | int | 4 | The bound on the number of candidates a race accepts (the k in the race) |
analyzers | bool | true | Whether a race also runs the repo's configured analyzers against each candidate |
Candidate racing
When an agent has more than one plausible fix for the same edit, it does not have to pick on vibes or verify them one by one across separate turns. Pass candidates, a JSON array of single-file edits, and fuse_test typechecks all of them against the live resident compilation and returns a per-candidate verdict plus a suggested winner:
[
{"id": "tuple", "file": "src/Order.cs", "content": "<full new file content>"},
{"id": "linq", "file": "src/Order.cs", "content": "<full new file content>"}
]Each candidate is the same shape a single fuse_check takes (a file and its proposed full content); the optional id labels the candidate in the output (a blank one is filled with its position). The winner is chosen by strict dominance only: a candidate that typechecks clean beats any candidate with an error, two or more clean candidates are reported as a tie (the tool will not choose one green over another green), and when no candidate is clean the tool says so rather than picking the least-bad. Nothing is written; the race returns verdicts for you to act on.
Racing needs a resident workspace (FUSE_RESIDENT=1); without one the tool abstains, because the point is to reuse one held compilation across every candidate. Each candidate forks that compilation and rebinds only its own changed file, so racing k candidates costs about k times a single warm verify, not k cold loads. The cost note is honest and measured: the candidates are evaluated one at a time, not concurrently, because Roslyn's semantic binding over forks that share a base compilation serializes on the base's internal caches (on a 20-core host, racing three candidates concurrently was within three percent of running them sequentially), so concurrency would buy no wall-clock while multiplying the live-fork memory by k. A race reports typecheck diagnostics only; running each candidate's tests over an unwritten edit needs the emit path, which is future work, so run the winner's covering tests with a covering-test call after you apply it.
Exact signatures (fuse_find kind=signatures)
Look up a symbol's exact signature (declared signature, kind, accessibility, containing type, and location) with fuse_find and kind=signatures, the compiler-shaped answer to "what is the exact shape of this member" instead of grep-and-read. A signature is recorded at the semantic tier; in syntax mode a symbol may have no recorded signature, and the tool says so rather than inventing one. Pass the symbol name as query. When a resident workspace serves the root (FUSE_RESIDENT), a qualified name resolves from the compiler's real metadata, so a referenced package's API answers from the compiler rather than the store.
The propose-verify-apply flow
The loop is direct: there is no stateful staging session. Diagnose a proposed single-file edit by passing its content to fuse_check (the speculative typecheck, oracle-grade when build capture is available). Make compiler-executed edits with fuse_refactor (each returns a verified staged diff or abstains). Select the covering tests for a changed symbol with fuse_impact (which lists them) or run them with fuse_test. When you choose to commit, write the result to the working tree with fuse_workspace action=apply (the one explicit write path, a dry run unless write=true). Nothing is written until that apply.
fuse_reduce
Compact specific files or raw content without collecting a directory. Pass files, or pass content with extension. Secret redaction remains enabled. Structural levels are context transforms: output is not promised to compile or preserve private implementation detail.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
path | string | . | Base directory for resolving relative file paths |
files | string[] | null | File paths to reduce |
content | string | null | Raw content to reduce instead of files |
extension | string | .cs | Extension that selects the reducer for content |
level | string | standard | none, standard, aggressive, skeleton, or publicApi |
maxTokens | int | 0 | Maximum tokens the reduced output may use (0 means no limit) |
A positive maxTokens can truncate the reduced result. It does not guarantee retention of every declaration.
Language Tiers
The syntax-tier index is provider-driven and language-agnostic. C# uses Roslyn syntax; the maintained Python provider handles .py, and the maintained JavaScript provider handles JavaScript and TypeScript extensions. These providers populate file language, symbols, and searchable chunks.
Typed semantic edges, compiler signatures, build capture, verification, and compiler-executed refactors are C#-only. Python and JavaScript providers do not provide a typed graph or compiler-grade answers. First-party expansion beyond their current syntax behavior is frozen pending a real compiler-service integration.