RoslynSense 0.3.0
dotnet tool install --global RoslynSense --version 0.3.0
dotnet new tool-manifest
dotnet tool install --local RoslynSense --version 0.3.0
#tool dotnet:?package=RoslynSense&version=0.3.0
nuke :add-package RoslynSense --version 0.3.0
RoslynSense
A Model Context Protocol (MCP) server that provides C# code analysis, navigation, refactoring, testing, and debugging capabilities using the Roslyn compiler platform. Includes extensible support for WebForms (ASPX/ASCX) and Razor (.razor/.cshtml) files.
Inspired by egorpavlikhin/roslyn-mcp.
Install
Step 1 — Install the .NET tool
dotnet tool install --global RoslynSense
Update an existing install:
dotnet tool update --global RoslynSense
Step 2 — Configure your agent
<details> <summary>Claude Code</summary>
Via the plugin marketplace (recommended):
claude plugin marketplace add GerardSmit/RoslynSense && claude plugin install roslyn-sense@roslyn-sense
Or add the MCP server directly (project-scoped):
claude mcp add RoslynSense --transport stdio -- roslyn-sense
For a global installation available in all projects, add --scope user:
claude mcp add --scope user RoslynSense --transport stdio -- roslyn-sense
</details>
<details> <summary>Cursor</summary>
Add to .cursor/mcp.json in your project root (or ~/.cursor/mcp.json for global):
{
"mcpServers": {
"RoslynSense": {
"command": "roslyn-sense"
}
}
}
</details>
<details> <summary>Windsurf</summary>
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"RoslynSense": {
"command": "roslyn-sense"
}
}
}
</details>
<details> <summary>VS Code (Cline / Continue / Copilot)</summary>
Add to .vscode/mcp.json in your project root, or open the command palette and run MCP: Open User Configuration to configure it globally:
{
"servers": {
"RoslynSense": {
"type": "stdio",
"command": "roslyn-sense"
}
}
}
</details>
<details> <summary>Visual Studio</summary>
Add to .mcp.json in your solution root (committed to source control) or %USERPROFILE%\.mcp.json for a global configuration:
{
"servers": {
"RoslynSense": {
"type": "stdio",
"command": "roslyn-sense"
}
}
}
</details>
<details> <summary>GitHub Copilot CLI</summary>
For a global installation, run /mcp add inside Copilot CLI and fill in the interactive form (stores to ~/.copilot/mcp-config.json). Select Local/STDIO as the server type and use roslyn-sense as the command.
For a project-scoped configuration, add to .mcp.json in your project root (v1.0.22+):
{
"mcpServers": {
"RoslynSense": {
"command": "roslyn-sense"
}
}
}
</details>
<details> <summary>Kiro</summary>
Add to .kiro/settings/mcp.json in your project root (or ~/.kiro/settings/mcp.json for global):
{
"mcpServers": {
"RoslynSense": {
"command": "roslyn-sense",
"args": []
}
}
}
</details>
<details> <summary>Other MCP clients</summary>
Use the following server configuration:
{
"servers": {
"RoslynSense": {
"type": "stdio",
"command": "roslyn-sense"
}
}
}
</details>
Command-Line Options
| Flag | Description |
|---|---|
--no-webforms |
Disable WebForms (ASPX/ASCX) support. |
--no-razor |
Disable Razor (.razor/.cshtml) support. |
--no-debugger |
Disable all debugger tools (see Debugging). |
--no-profiling |
Disable all profiling tools (see Profiling). |
--toon |
Use TOON (Token-Optimized Object Notation) output format instead of markdown. Reduces token usage. |
--db <alias>=<provider>:<connstr> |
Register a database connection. Repeatable. Providers: psql, mssql, sqlite. See Databases. |
--no-db |
Disable all database tools. |
--no-auto-db |
Disable auto-discovery of connection strings from web.config and appsettings*.json. See Databases. |
--no-preload |
Disable background workspace preloading on startup. |
Example with Razor disabled:
{
"servers": {
"RoslynSense": {
"type": "stdio",
"command": "roslyn-sense",
"args": ["--no-razor"]
}
}
}
Configuration file (roslynsense.json)
Drop a roslynsense.json next to your solution (or anywhere up the tree from where the server is launched) to configure RoslynSense per-project without editing every MCP client. The server walks up from the working directory and uses the nearest file found.
{
"tools": {
"webForms": true,
"razor": true,
"debugger": true,
"profiling": true,
"database": true
},
"database": {
"autoDiscovery": null,
"connections": {
"myapp": "psql:Host=localhost;Database=myapp;Username=dev;Password=dev",
"reports": {
"provider": "mssql",
"connectionString": "Server=.;Database=Reports;Integrated Security=true"
}
}
},
"tableFormat": "toon",
"preload": ["./MySolution.sln"]
}
Precedence: CLI flag > config file > default. Per-field for booleans, per-alias for connections.
<details> <summary>Field reference</summary>
| Path | Type | Default | Equivalent CLI flag |
|---|---|---|---|
tools.webForms |
bool | true |
--no-webforms forces false |
tools.razor |
bool | true |
--no-razor forces false |
tools.debugger |
bool | true |
--no-debugger forces false |
tools.profiling |
bool | true |
--no-profiling forces false |
tools.database |
bool | true |
--no-db forces false |
database.autoDiscovery |
bool? | null |
--no-auto-db forces false |
database.connections |
object | {} |
--db overrides matching alias |
tableFormat |
string? | null |
--toon forces "toon" |
preload |
string[]? | null |
--no-preload forces [] |
sharedHost |
bool? | true |
env ROSLYNMCP_SHARED_HOST=0 forces off |
hostIdleMinutes |
int? | 30 |
env ROSLYNMCP_HOST_IDLE_MINUTES |
maxWorkspaces |
int? | 4 |
env ROSLYNMCP_MAX_WORKSPACES |
preload semantics:
null(default) — auto-discovers the first.sln/.slnxin the working directory and preloads all its projects in the background on startup.["path1.sln", "path2.csproj"]— preloads exactly the listed solution and/or project files.[]— disables preloading entirely.
autoDiscovery semantics:
null(default) — auto-discovery runs only when no explicit registrations exist (CLI--dbor configconnections).true— auto-discovery always runs in addition to explicit registrations. Explicit aliases still win on conflict.false— auto-discovery skipped entirely.
</details>
<details> <summary>Connection entry formats</summary>
Two equivalent forms — pick whichever reads better. The string form mirrors --db <provider>:<connstr> shorthand.
Shorthand string:
"connections": {
"myapp": "psql:Host=localhost;Database=myapp;Username=u;Password=p"
}
Object form:
"connections": {
"reports": {
"provider": "mssql",
"connectionString": "Server=.;Database=Reports;Integrated Security=true"
}
}
The connection-string portion accepts the same xml: / json: indirection and ${gitRoot} / ${solutionRoot} / ${env:NAME} placeholders documented under Referencing connection strings from config files.
</details>
<details> <summary>Loader behavior</summary>
- Walks up from
Directory.GetCurrentDirectory()to the filesystem root, stopping at the firstroslynsense.jsonfound. - Lenient JSON: line/block comments, trailing commas, and unknown properties are accepted. Unknown properties are silently ignored for forward compatibility.
- Invalid JSON is logged to stderr; the server starts with defaults.
- Per-connection parse failures (unknown provider, empty value) are logged as warnings and the entry is skipped.
</details>
Shared host (across chats)
Each MCP client (each chat) normally spawns its own roslyn-sense process, so N chats on the same solution load that solution N times. To avoid that, RoslynSense runs a single shared host process per solution: thin client processes forward tool calls and resource reads to it over a named pipe, so the solution is loaded once and shared.
- On by default. Disable with
ROSLYNMCP_SHARED_HOST=0(or"sharedHost": false), e.g. for debugging — clients then run everything in-process. - Automatic fallback. If the host can't be reached or an IPC call fails, the client transparently runs the call in-process; a host problem never breaks a chat.
- Scope. Only applies when the working directory belongs to a multi-project solution; loose
.csprojuse stays in-process. - Lifecycle. The host shuts down after
ROSLYNMCP_HOST_IDLE_MINUTES(default 30) with no connected clients, and respawns on the next call. Logs go to%TEMP%/roslyn-mcp-daemon/<hash>/host.log.
In-process memory is also bounded independently of the host:
- One workspace per solution (not per project): opening any project of a solution opens the whole solution once.
ROSLYNMCP_MAX_WORKSPACES(default 4) caps cached solution workspaces (LRU), on top of the 10-minute idle eviction.
| Env var | Default | Effect |
|---|---|---|
ROSLYNMCP_SHARED_HOST |
1 |
0/false/off disables the shared host (pure in-process). |
ROSLYNMCP_HOST_IDLE_MINUTES |
30 |
Idle minutes before a clientless host exits. |
ROSLYNMCP_MAX_WORKSPACES |
4 |
Max cached solution workspaces (LRU bound). |
ROSLYNMCP_INDEX_IDLE_TIMEOUT_SECONDS |
600 |
Idle eviction for ASPX/Razor project-index caches. |
ROSLYNMCP_OPEN_PROJECT_TIMEOUT_SECONDS |
300 |
Ceiling on a single project/solution open. |
Debugging and running are per-chat. Debug and run tools are not forwarded to the shared host — they run in-process in each client, so every chat has its own independent debug session and its own launched applications. Multiple chats can debug the same solution at once without colliding, and a launched app is torn down with the client that started it rather than being orphaned. (Trade-off: a debug session loads its own workspace in the client process, but debugging is interactive and infrequent.)
Designer regeneration is the exception: it is a side effect on the shared source tree, so OpenSolution runs a single watcher in the host rather than one per chat.
Single host guarantee. Exactly one host serves a solution at a time: a daemon acquires an exclusive lock file before it begins listening, so a daemon that loses a startup race exits without serving; the OS releases the lock on process death, so a crash self-heals and the next call respawns.
Tools
Code Analysis
| Tool | Description |
|---|---|
| GetRoslynDiagnostics | Get diagnostics for a C# file, ASPX/ASCX file, Razor file, or entire project. Returns a compact markdown table with severity counts. Accepts a severity filter (error, warning, info, hidden, all). Supports multiple files separated by semicolons. |
| GetCodeActions | List available code fixes for a diagnostic. Optionally apply a fix by index. Also discovers refactorings (Extract Method, Introduce Variable, etc.). |
Navigation
| Tool | Description |
|---|---|
| GoToDefinition | Navigate to a symbol's definition with code context, or auto-decompile referenced assembly symbols. For type definitions, shows a members table. Works with C#, ASPX, and Razor files. |
| FindUsages | Find all references to a symbol across a project. Also searches Razor source-generated files and ASPX inline code. |
| SemanticSymbolSearch | Ranked symbol search combining name, signature, docs, and source cues. Supports phrase-style queries (e.g. "calculate tax", "user repository"). |
| FindImplementations | Find all implementations of an interface, abstract class, or virtual/abstract member. |
| GetCallHierarchy | Show callers and/or callees of a method or property. |
| GetTypeHierarchy | Show the full type hierarchy (base classes, interfaces, derived types). |
Structure
| Tool | Description |
|---|---|
| GetProjectStructure | Get an overview of a project: target framework, references, source files, and types by namespace. |
| GetFileOutline | Get a compact outline of a C#, ASPX, or Razor file with namespaces, types, members, and line ranges (start-end for multi-line members). Supports multiple files separated by semicolons. |
| ListProjects | Discover all projects loaded in the workspace. |
| ListSourceGeneratedFiles | List all source-generated files in a project, grouped by generator. |
| GetSourceGeneratedFileContent | View the content of a specific source-generated file by hint name. |
Build
| Tool | Description |
|---|---|
| BuildProject | Build a .NET project or solution and return structured errors and warnings. Warnings are grouped by code with counts. Set background: true to build in the background. |
| GetBuildWarnings | Retrieve all warnings for a specific warning code (e.g. CS0414) from the last build. Returns each warning's file, line, and message. projectPath defaults to the last built project. |
Solution Session
| Tool | Description |
|---|---|
| OpenSolution | Load a solution's projects, report each project's framework and run kind plus the .NET Framework toolchain (MSBuild, IIS Express, SqlMetal), and start watching markup so .designer.cs files regenerate on save. Omit solutionPath to auto-discover. |
| CloseSolution | Stop the designer watcher and release the session. |
| GetSolutionStatus | Report the open solution, watcher state, and recent automatic designer regenerations. |
Generated Files
Visual Studio maintains *.aspx.designer.cs, *.ascx.designer.cs, *.master.designer.cs and
*.dbml.designer.cs through custom tools an agent does not have. Rather than hand-editing those
generated files — where the edit is lost on the next regeneration — edit the markup or model and
regenerate.
| Tool | Description |
|---|---|
| RegenerateDesigner | Regenerate the .designer.cs for WebForms markup (.aspx/.ascx/.master) or a LINQ to SQL model (.dbml). Accepts a file, .csproj, .sln, or directory. Set dryRun: true to preview. |
WebForms designers are generated from the resolved control tree, so each server control with an
ID gets a correctly typed field. Controls nested in a template get no field (they are reached via
FindControl), and a control whose field is already declared by hand in the code-behind is skipped
so no duplicate member is emitted. .dbml regeneration shells out to SqlMetal.exe from the
Windows SDK.
Running Applications
Applications are per-chat: they are launched by the client that asked for them and torn down with it, so two chats never fight over one process.
| Tool | Description |
|---|---|
| RunProject | Build and run a project, leaving it running. ASP.NET Core and .NET/.NET Framework console apps launch directly; legacy ASP.NET sites launch under IIS Express using the port and virtual path from the project's WebProjectProperties. Waits for the port to accept connections and returns the URL and PID. Builds first by default, like Visual Studio; pass build: false to launch existing output. |
| StopProject | Stop by session ID, project path, or all. Kills the whole process tree. |
| ListRunningProjects | List applications started in this chat with state, PID, URL and uptime. |
| GetProjectOutput | Read captured stdout/stderr for a session. |
Refactoring
| Tool | Description |
|---|---|
| RenameSymbol | Rename a symbol and all references across the project, including ASPX/ASCX and Razor files. Supports dry-run preview and file renames. |
| ExpandVarTypes | Return a method's source with all var declarations replaced by their resolved explicit types. Use as a first step to understand what types a method works with — reveals return types, collection element types, and destructured results without chasing each call individually. Read-only; supports hintLine for overload disambiguation. |
Testing & Coverage
| Tool | Description |
|---|---|
| RunTests | Run tests in a .NET test project with optional filter expression and timeout. Set background: true to run in the background (builds first, then tests). |
| DiscoverTests | Discover all test methods in a project using static Roslyn analysis. Returns test names, frameworks, file paths, and line numbers. |
| FindTests | Find test methods that reference a symbol. Optionally uses coverage data for runtime-accurate results. |
| RunCoverage | Collect code coverage for a test project using coverlet. Caches results for querying. Set background: true for background collection. |
| GetCoverage | Query coverage by project, file, class, or method. Shows line and branch coverage with uncovered lines. |
| GetMethodCoverage | Get per-line coverage detail for a specific method. Shows every executable line with hit count and source code. Lines marked with ! have partial branch coverage. |
Debugging
Disable with --no-debugger.
The debug engine is selected automatically from the target — you never choose it:
| Target | Engine |
|---|---|
| .NET / .NET Core | netcoredbg, auto-provisioned on first use |
| .NET Framework | ICorDebug, built in |
No single engine covers both: netcoredbg speaks only to CoreCLR, and ICorDebug is the only way into
.NET Framework. DebugStartTest picks from the project's target framework; DebugAttach has no
project to consult, so it picks from the CLR the target process actually loaded — which is how
attaching to iisexpress.exe or w3wp.exe resolves to the .NET Framework engine.
.NET Framework debugging binds breakpoints through Windows PDBs, and pending breakpoints rebind as
modules load — so breakpoints land in shadow-copied bin assemblies and in the generated
App_Web_* assemblies produced from inline ASPX code.
Expression evaluation resolves arguments, locals, fields and array elements directly, and calls
into the debuggee for computed properties and parameterless methods (order.Total,
order.Describe()). DebugSetVariable-style assignment works for primitives and booleans.
Cross-architecture targets. ICorDebug cannot attach across x86/x64, so a target whose bitness differs from the server is debugged through a matching worker process running the same engine — this is what makes a 32-bit IIS Express app pool debuggable. Selection is automatic. The workers are framework-dependent, so debugging a 32-bit target needs the x86 .NET runtime installed; when it or the worker is missing, the error says so rather than failing at attach.
One current limit: DebugStartTest is not supported for .NET Framework test projects — run the
tests, then DebugAttach to the test host.
| Tool | Description |
|---|---|
| DebugStartTest | Start debugging a .NET test project. Builds, launches the test host, and attaches the debugger. |
| DebugAttach | Attach the debugger to a running .NET or .NET Framework process by PID. |
| DebugSetBreakpoint | Set a breakpoint at a file and line. Supports conditions and batch mode. |
| DebugRemoveBreakpoint | Remove a breakpoint by ID. Supports batch removal. |
| DebugContinue | Continue, step in, step over, or step out. |
| DebugRunUntil | Run until a specific location, with optional condition. |
| DebugEvaluate | Evaluate expressions in the current debug context. Supports batch evaluation with semicolons. |
| DebugStatus | Get debugger status, breakpoints, and current pause position with optional locals and stack trace. |
| DebugStop | Stop the debug session and clean up. |
Profiling
Profiling uses dotnet-trace with CPU sampling, auto-provisioned on first use. Disable with --no-profiling.
| Tool | Description |
|---|---|
| ProfileTests | Profile a test project to find CPU hotspots. Returns top methods ranked by self-time. |
| ProfileApp | Profile a .NET application for a specified duration. |
| ListProfilingSessions | List recent profiling sessions with IDs for investigation. |
| ProfileSearchMethods | Search profiled methods by name pattern. |
| ProfileCallers | Show which methods called a given method and how much time was spent. |
| ProfileCallees | Show which methods a given method calls and how much time was spent. |
| ProfileHotPaths | Show the hottest call paths through a method. |
Background Tasks
| Tool | Description |
|---|---|
| GetBackgroundTaskResult | Check status and results of a background task by task ID. |
| ListBackgroundTasks | List all background tasks with their statuses. |
Databases
Query configured databases directly from the LLM without needing psql, sqlcmd, or sqlite3 installed. Connections are registered at server startup via --db (see Command-Line Options). Connections are writable by default.
| Tool | Description |
|---|---|
| DbQuery | Run a SELECT query on a configured connection. Returns results as a table. Supports parameterized queries via a JSON object. |
| DbExecute | Run a non-query SQL statement (INSERT/UPDATE/DELETE/DDL). Returns affected rows. |
| DbListConnections | List all configured database connections. |
| DbListTables | List tables and views, optionally filtered by schema. |
| DbDescribeTable | Show columns, types, nullability, and defaults for a table. |
Example configuration with all three providers:
{
"servers": {
"RoslynSense": {
"type": "stdio",
"command": "roslyn-sense",
"args": [
"--db", "prod=psql:Host=db.example.com;Database=app;Username=app;Password=s3cr3t",
"--db", "local=sqlite:C:\\dev\\app.db",
"--db", "reports=mssql:Server=(local);Database=Reporting;Integrated Security=true"
]
}
}
}
Provider tokens: psql / postgres / postgresql, mssql / sqlserver / sql, sqlite. Alias prefix is optional (defaults to the canonical provider name).
SQL Server: TrustServerCertificate
SQL Server connection strings get TrustServerCertificate=True unless they already specify it.
This exists because the same connection string behaves differently in the two SqlClients. A
.NET Framework app's System.Data.SqlClient defaults to Encrypt=false, so a web.config string
pointing at a development server with a self-signed certificate works. Microsoft.Data.SqlClient,
which this server uses, has defaulted to Encrypt=true since v4.0 — so the identical string fails
with a certificate-trust error here while the application it was copied from connects fine.
Note that this does weaken transport security: the connection is still encrypted, but an
unvalidated certificate offers no protection against interception. It is a development-time default.
To opt back into validation — for a production server, say — state it explicitly, and it is
respected (the spaced synonym Trust Server Certificate works too):
--db prod=mssql:Server=db.example.com;Database=App;TrustServerCertificate=False
Referencing connection strings from config files
The connection-string portion can be a raw ADO.NET string or a reference to an existing config file so the LLM does not need the secret baked into the MCP config.
"args": [
"--db", "legacy=mssql:xml:./src/WebApp/web.config#SiteSqlServer",
"--db", "core=mssql:json:./src/CoreApp/appsettings.json#Default",
"--db", "custom=psql:json:./secrets.json#$.Databases.Primary.ConnStr"
]
<details> <summary>Reference forms and path placeholders</summary>
| Form | Meaning |
|---|---|
xml:<path>#<name> |
.NET Framework shorthand — /configuration/connectionStrings/add[@name='<name>']/@connectionString |
xml:<path>#<xpath> |
Full XPath starting with / or //. Returns attribute value or element text. |
json:<path>#<name> |
.NET Core shorthand — $.ConnectionStrings.<name> |
json:<path>#$.a.b.c |
Dotted JSON path. |
The delimiter between path and query is always #. Paths support the following placeholders so config-file references stay portable across machines / CI / committed .mcp.json:
| Placeholder | Resolves to |
|---|---|
${gitRoot} |
Nearest ancestor directory containing .git. |
${solutionRoot} |
Nearest ancestor directory containing *.sln or *.slnx. |
${env:NAME} |
Environment variable NAME. |
Example committed to Git:
"args": [
"--db", "legacy=mssql:xml:${gitRoot}/src/WebApp/web.config#SiteSqlServer",
"--db", "core=mssql:json:${solutionRoot}/src/CoreApp/appsettings.json#Default"
]
Plain relative paths (no placeholder) resolve in this order: CWD → solutionRoot → gitRoot. First existing file wins. This lets a committed .mcp.json work on any contributor's machine regardless of where Claude was launched, without requiring a placeholder.
</details>
Auto-discovery from project config files
At startup the server scans the working directory tree for web.config, app.config, and appsettings*.json files and registers any connection strings it finds. The alias is ProjectName_ConnectionStringName (project name comes from the nearest *.csproj walking up; non-alphanumerics are replaced with _). Explicit --db flags and roslynsense.json connections always win over auto-discovered aliases with the same name.
Disable the scan entirely with --no-auto-db (or database.autoDiscovery: false in roslynsense.json), or disable the database tools altogether with --no-db.
<details> <summary>Development-first merge order and skipped files</summary>
Development-first by design. RoslynSense is a development-time tool, so giving an LLM easy access to a production database is the wrong default. The merge order is:
- Base file (
appsettings.json,web.config,app.config) — applied first. - Other environment-specific files — override the base.
- Development-flavored files (
appsettings.Development.json,appsettings.Local.json,web.Debug.config,app.Debug.config) — applied last, overriding everything else.
Production-flavored env names are not loaded at all: Production, Prod, Live, Staging, Stage, Release, Publish. (Release is the MSBuild configuration name applied by dotnet publish -c Release, almost always to inject prod settings — same risk as Production.) If you really need to register prod credentials, do it explicitly with --db or roslynsense.json.
web.<env>.config / app.<env>.config are XDT transform files but commonly carry the only real local-dev connection string, so they are parsed alongside the base. The xdt: namespace is ignored on attribute reads; xdt:Transform="Remove" / RemoveAll on either an <add> entry or the <connectionStrings> section is honored.
Files and entries that are skipped with a stderr warning:
appsettings.{template,example,sample,dist}.jsonandweb.{template,example,sample,dist}.config— non-runtime templates committed without secrets.appsettings.Production.json,web.Production.config, etc. — production env names (see above).<connectionStrings configProtectionProvider="…">— encrypted viaaspnet_regiis -pe; the ciphertext is unusable at runtime.<add xdt:Transform="Remove"/>and<connectionStrings xdt:Transform="RemoveAll"/>inside transform files.- Empty values and unfilled placeholders:
${VAR},$(VAR),{{VAR}},#{VAR},%VAR%,<your connection string>.
bin, obj, node_modules, .git, .vs, .idea, packages, TestResults, and other dotted directories are skipped.
</details>
<details> <summary>Provider resolution order</summary>
The provider for each connection string is resolved in this order — first match wins:
providerNameattribute on<add>(web.config) — e.g.System.Data.SqlClient,Npgsql,System.Data.SQLite.- Connection-string content —
Host=/Port=→psql;:memory:/Filename=/Data Source=*.db→sqlite;Server=/Integrated Security=→mssql. - Connection-string name hint — anything containing
postgres/npgsql/psql→psql;sqlite→sqlite;sqlserver/mssql→mssql(e.g.SiteSqlServer). - Project's referenced NuGet packages — a single
Npgsql*,*.Sqlite, or*.SqlClient/*.SqlServerpackage on the nearest.csprojresolves the provider. web.configdefault —mssql. (.NET Framework ships SqlClient in the BCL, so historically untyped<connectionStrings>entries meant SQL Server.)- Otherwise the entry is skipped and a warning is logged on stderr.
</details>
Resources
| Resource | URI Pattern | Description |
|---|---|---|
| project-structure | roslyn://project-structure/{filePath} |
Project file/folder structure grouped by directory. |
| file-outline | roslyn://file-outline/{filePath} |
Structural outline of a C# file (same as GetFileOutline tool). |
Prompts
| Prompt | Description |
|---|---|
| validate-after-edit | Step-by-step instructions to validate a C# file after editing. |
| investigate-symbol | Multi-step investigation workflow for a symbol. |
Skill
Installing via the Claude Code plugin also installs a csharp skill (skills/csharp/SKILL.md).
Claude loads it automatically when working in a C# project; you can also invoke it explicitly as
/roslyn-sense:csharp.
It carries the C#/.NET conventions plus guidance on driving these tools — which tool to reach for instead of grep or a shell build, when to regenerate designer files rather than editing them, and how to run and debug an app on either runtime.
Skills are a Claude Code feature. On other MCP clients, point your agent at that file directly — it is plain Markdown with no Claude-Code-specific syntax in the body.
Keeping the tool up to date
The plugin declares the MCP server as roslyn-sense, which is the .NET global tool —
installing the plugin does not install the tool.
The server checks NuGet for a newer version itself and mentions one in OpenSolution's output. The
check costs nothing at session start: it runs on a background task, caches the answer for 24 hours,
and makes no request at all when that cache is fresh. Updating is left to you, since a running
server holds its own binary and cannot replace it in place.
Deliberately not a SessionStart hook running dotnet tool update: that takes about five seconds
even when there is nothing to update, on every single session.
| Env var | Effect |
|---|---|
ROSLYNMCP_NO_UPDATE_CHECK |
1/true/on disables the version check entirely. |
If the tool is missing altogether, the skill tells the agent to install it and ask for a restart.
Markup Snippet Convention
Many tools use a markupSnippet parameter with [| |] delimiters to identify a target symbol:
var x = [|Foo|].Bar(); // targets Foo
public interface [|IService|] // targets IService
void [|ProcessData|](int x) // targets ProcessData
The snippet is matched against the file content. Whitespace differences are tolerated.
| Product | Versions 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. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.0 | 88 | 7/27/2026 |
| 0.2.0 | 91 | 7/27/2026 |
| 0.1.31 | 85 | 7/27/2026 |
| 0.1.30 | 85 | 7/27/2026 |
| 0.1.29 | 88 | 7/27/2026 |
| 0.1.28 | 113 | 5/29/2026 |
| 0.1.27 | 118 | 5/28/2026 |
| 0.1.26 | 113 | 5/16/2026 |
| 0.1.25 | 122 | 4/29/2026 |
| 0.1.24 | 114 | 4/28/2026 |
| 0.1.23 | 110 | 4/28/2026 |
| 0.1.22 | 106 | 4/28/2026 |
| 0.1.21 | 106 | 4/28/2026 |
| 0.1.20 | 107 | 4/24/2026 |
| 0.1.19 | 110 | 4/20/2026 |
| 0.1.18 | 106 | 4/18/2026 |
| 0.1.17 | 115 | 4/15/2026 |
| 0.1.16 | 109 | 4/14/2026 |
| 0.1.15 | 110 | 4/13/2026 |
| 0.1.14 | 107 | 4/10/2026 |