TerseSharp 0.32.0

There is a newer version of this package available.
See the version list below for details.
dotnet tool install --global TerseSharp --version 0.32.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local TerseSharp --version 0.32.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=TerseSharp&version=0.32.0
                    
nuke :add-package TerseSharp --version 0.32.0
                    

TerseSharp

The bridge between your coding agent and your C# codebase.

A Roslyn-powered MCP server so your agent navigates, edits, refactors, builds and tests .NET semantically — instead of reading whole files and grepping for symbols. 87 tools. One install. No IDE, no licence, no language server.

CI License .NET

Install

dotnet tool install -g TerseSharp
terse install            # registers with Claude Code, Cursor, VS Code, Windsurf

That's it. Restart your agent and ask it something about your code — with no arguments the server walks up from the current directory, finds your .sln / .slnx / .slnf / .csproj and loads it.

terse install --client cursor   # not detected? pick one: claude-code | cursor | vscode | windsurf
terse install --skill --guard   # teach your agent the tools, and block Read/Grep on C# (recommended)
terse doctor                    # verify SDK, MSBuild, workspace load, client registration, per-call latency
terse call get_file_outline --workspace App.slnx --json '{"path":"src/App/Order.cs"}'

No IDE, no licence, no Node, no Python, no API key, and no network call to answer a question — the only request it ever makes is one HEAD to GitHub's releases/latest, at most once a day, to tell you an update exists. TERSE_UPDATE=0 turns that off.

Prefer to configure MCP by hand:

{
  "mcpServers": {
    "terse-sharp": {
      "command": "terse",
      "args": ["serve", "--workspace", "C:/path/to/YourApp.slnx"]
    }
  }
}

What it saves you

Question Built-in tools TerseSharp
What's on this 2,000-line type? Read~6,000 tokens get_type_outline~450 13×
Read a whole .cs file Read → the entire text read_text answers the outline unless you ask for the text
Who calls this method? Grep + follow-up reads → ~4,000 find_usages~200 20×
Where are these 8 ids? one grep/search per literal search_text queries=[…] → one pass, records tagged q1..qN 8 calls → 1
Rename it across the solution ~5,000 tokens, misses the interface rename_symbol~150, correct 30×
Why is the build red? ~8,000 tokens of MSBuild spew build~600 13×
What did I just change? git diff → the whole patch diff_symbols → the changed declarations 10×
Does this {Binding} bind? no static answer exists in WPF xaml_bindings validate=true

Asserted by a token-budget suite in CI on every commit, not estimated.

  • Semantic, never textual. Real references, not string matches — every record tagged EXACT or HEURISTIC, so you always know what you're trusting.
  • Compile-gated edits. An edit that introduces a compile error is rolled back before the agent reports it done, and undo_last_change reverses the last one. replace_symbol takes a whole batch of edits across files, so a signature change lands with the callers it breaks.
  • No silently-ignored arguments. A parameter a tool doesn't declare is refused by name, with every accepted spelling — a listing that quietly dropped your maxResults is a wrong answer the agent can't detect.
  • Always fresh. A file you just created, or an edit from your IDE, is already in the answer.
  • Never guesses. Where it can't prove an answer it says so — a false positive costs an agent more than no answer.

Make your agent actually use it

An agent that has TerseSharp installed and reaches for Read and Grep out of habit saves nothing. terse install --guard registers a Claude Code PreToolUse hook that denies the built-in and names the tool to use instead — covering .cs, .razor, .xaml, .axaml, .resx, .csproj, .sln and friends, the shell text tools (grep, cat, sed, ls, …) that name one of them, dotnet build/test/format/clean and dotnet watch build/test, and the working-tree half of git — git status and git diff, answered by changed_files and diff_symbols, plus a bare git ls-files, answered by find_files tracked=true, and only when the directory the command actually addresses sits under a .sln/.slnx/.slnf/.csproj — the -C target, or a directory operand, before the working directory. The hook is user-wide and those tools answer about the loaded workspace, so git -C ../notes status is allowed. A denied command also tells the agent not to run it in Bash again. Plain .css, .js, dotnet restore/pack/publish/run, git ls-files with any option, and git history and mutation (log, blame, show, add, commit, push) are allowed, because nothing here replaces those; malformed hook input allows the call, so a guard fault can never wedge a session; and you remove the guard by deleting the terse guard entry from Claude Code's settings.json. Pair it with --skill, which ships Claude Code the skill that teaches the swaps — on any other agent, put the same rule in AGENTS.md or .cursorrules.

A denial also returns additionalContext — the complete replacement call with the arguments filled in from the command it denied (Call this instead: get_file_outline path="src/App/Order.cs") — so the agent is routed, not merely refused. Set TERSE_GUARD_LOG=<path> to append one JSON line per decision (tool, verdict, routing, reason, cwd, session, transcript), opt-in and best-effort; a write failure never changes the verdict.

The tools

The full catalogue is attached to every request, and past a certain size that measurably costs tool-selection accuracy — so the advertised set is derived from what the solution actually contains. A tree with no .xaml/.axaml is not offered the 13 xaml_* tools, one with no .razor/.cshtml is not offered the 10 razor_*, one with no .resx/.resw is not offered the 8 resx_*; measured on a plain C# solution that is 56 tools instead of 87, 16 962 tokens instead of 22 193 (-23.6 %) on every request. Loading a second solution that does hold them re-advertises the families through notifications/tools/list_changed, and a hidden tool still answers when called by name. terse serve --tools all (or TERSE_TOOLS=all) advertises everything regardless; --tools core still narrows to a 21-tool subset. workspace_status names whatever is hidden.

87 tools. One record per line, workspace-relative paths, an explicit truncated/total, and a success that costs nothing — every mutating tool answers in one line per changed file, with verbose=true for the diff and dryRun=true to preview it. Any caveat prints in full.

Ten of them take a plural. read_text paths=, get_file_outline paths=, diff_text paths=, get_symbol_source symbolIds=, replace_symbol symbolIds=, search_text/search_regex queries=, run_tests projects=, write_text files= and edit_text edits= each answer in one call what used to cost one call per item — and write_text files= puts every .cs file it writes through one compile gate, so a type and the consumer it breaks land together. From the third consecutive call of the same tool the response gains one extra line naming the plural parameter to use instead — the single documented exception to "a success is one line", worth about 12 tokens, emitted only once the repetition has already proved itself and never when the call already passed the plural.

Group Tools
Workspace load_workspace · workspace_status · list_workspaces · unload_workspace · list_projects
Navigation — replaces Read/Grep search_symbols · get_symbol · get_file_outline · get_type_outline · get_symbol_source · find_usages · find_implementations · explore_symbol · impact_of
What grep can't reach find_registrations (DI: open generics, factories, Add* extensions) · list_endpoints (ASP.NET Core Map*)
Analyze & clean — replaces dotnet format analyze · format · cleanup · gate (all four in the mandated order, one verdict line) · clean · get_diagnostics
Edit — replaces Edit on a .cs replace_symbol_body · replace_symbol · add_member · delete_symbol · rename_symbol
Refactor extract_interface · move_type_to_file · move_type_to_namespace · change_signature · undo_last_change
Projects & solutions solution_projects · solution_add_project · solution_remove_project · project_create · project_properties · project_set_property · project_add_reference · project_remove_reference · package_list · package_add · package_remove
XAML — WPF · Avalonia · WinUI · MAUI xaml_outline · xaml_names · xaml_resources · xaml_resolve · xaml_styles · xaml_bindings · xaml_validate · xaml_find · xaml_codebehind · xaml_localization · xaml_set_property · xaml_add_element · xaml_remove_element
Localization (.resx/.resw) resx_files · resx_get · resx_find · resx_usages · resx_set · resx_remove · resx_rename · resx_validate
Razor / Blazor razor_outline · razor_component · razor_find · razor_bindings · razor_codebehind · razor_validate · razor_set_attribute · razor_add_element · razor_remove_element · razor_set_directive
Files — replaces Glob/ls/cat read_text · write_text · edit_text · find_files · search_text · search_regex
Git — replaces git status/git diff changed_files · diff_symbols · diff_text
Build & test — replaces dotnet build/test build · run_tests · rerun_failed · list_tests

Every read tool declares the MCP readOnlyHint annotation and every deleting tool declares destructiveHint, so a client that gates parallel dispatch on those hints — Claude Code does — can fan the reads out instead of running them one at a time. The build and test tools are deliberately left off that list: they run a build, and a build dispatched beside an edit is a race, not a saving.

Markup and localization the compiler can't check

TerseSharp holds the markup tree and the Roslyn compilation in one process, so it answers what no text tool can: xaml_bindings validate=true type-checks every {Binding} path against the real symbol (WPF has no compile-time binding check at all), razor_validate catches the attribute matching no [Parameter] that compiles clean and throws at render, resx_validate reports missing translations and placeholder mismatches across a whole family, and rename_symbol carries a rename into the markup — but only where an x:Class or x:DataType proves the reference.

Safety and freshness

  • Symbol-addressed edits — no old_string echo, no line numbers to drift, and dryRun on every mutation returns the diff and writes nothing.
  • Compile-gated — a C#, Razor or refactoring edit that introduces a new compile error is rolled back, and the C# and refactoring ones are reversible with undo_last_change. The .resx, .xaml, Razor and project/package/solution writers are surgical file writes outside undo, so preview those with dryRun. --read-only makes every mutating tool refuse and touch nothing.
  • Follows the disk — a FileSystemWatcher nominates changed paths and a content comparison decides, so a dropped OS event can delay a refresh but never corrupt one.
  • Bounded memory — four solutions stay loaded at once, and one idle for 15 minutes gives its compilations back.
  • Parallel worktrees — every answer names its worktree and branch, and an ambiguous request lists the candidates instead of guessing.

Contributing

The easiest way to help: clone the repo and run /mine-sessions in Claude Code. It reads your own session logs, measures where the tools cost you tokens or round trips, and appends the findings to IMPROVEMENTS.md. Skim the new rows — keep the ones that look real, drop anything that leaked a path or a secret — then open a PR with just that file. We work through the backlog every weekend, so your friction becomes next week's release.

License

MIT Licensed. See LICENSE.

Built on Roslyn and the MCP C# SDK.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.33.0 0 8/12/2026
0.32.0 26 8/11/2026
0.31.0 36 8/11/2026
0.30.0 54 8/10/2026
0.29.0 48 8/10/2026
0.28.0 59 8/8/2026
0.27.0 55 8/8/2026
0.26.0 58 8/8/2026
0.25.0 57 8/8/2026
0.24.0 53 8/7/2026
0.23.0 60 8/7/2026
0.22.0 58 8/6/2026
0.21.0 58 8/6/2026
0.20.0 56 8/6/2026
0.19.0 71 8/5/2026
0.18.0 97 8/4/2026
0.17.1 98 8/3/2026
0.17.0 102 8/1/2026
0.16.0 90 8/1/2026
0.15.2 99 8/1/2026
Loading failed