ClaudeCodeRoslynLspProxy

A thin LSP proxy that makes Microsoft's Roslyn Language Server (Microsoft.CodeAnalysis.LanguageServer) work as a solution-aware C# language server inside Claude Code by injecting the Roslyn-specific solution/open notification that Claude Code's built-in LSP client does not send.
⚠️ Claude Code's LSP tool is read-only / navigation-only. It exposes 9 query operations (findReferences, goToDefinition, goToImplementation, hover, documentSymbol, prepareCallHierarchy, incomingCalls, outgoingCalls, workspaceSymbol) and does not expose edit operations like rename, codeAction, or formatting — even though roslyn-language-server implements them server-side. This proxy makes the read-only operations work solution-wide; it cannot add capabilities Claude Code does not surface.

How it works
Claude Code ←─ stdin/stdout ─→ ClaudeCodeRoslynLspProxy ←─ stdin/stdout ─→ Microsoft.CodeAnalysis.LanguageServer
The proxy passes everything through transparently. After the client's initialized, it:
- Scans the workspace folder for
.slnx (preferred) or .sln, pruning bin, obj, node_modules, .git, etc.
- Sends
solution/open to the server with the discovered URI.
- Falls back to
project/open over all .csproj if no solution file is found, or to a transparent passthrough if neither.
Roslyn LSP needs this Microsoft-specific notification to load the workspace as a unified Solution graph — without it, cross-file operations return empty or file-scoped results. Wire format verified against dotnet/roslyn and dotnet/vscode-csharp.
Installation
🚀 Plugin - Claude Code
Prereqs: .NET 10 SDK; Claude Code 2.1.50+; ENABLE_LSP_TOOL=1 in your ~/.claude/settings.json env block (the LSP tool is currently gated behind this undocumented env var).
-
Install the two dotnet tools:
dotnet tool install --global roslyn-language-server --prerelease
dotnet tool install --global ClaudeCodeRoslynLspProxy
roslyn-language-server is Microsoft's official Microsoft.CodeAnalysis.LanguageServer (owners Microsoft / RoslynTeam on NuGet; source dotnet/roslyn). Microsoft only ships pre-release versions, so --prerelease is required.
Make sure the global-tools directory is on PATH. Both tools install to %USERPROFILE%\.dotnet\tools on Windows or $HOME/.dotnet/tools on Linux/macOS. The .NET SDK installer usually adds this to your user PATH, but if it didn't (manual SDK install, side-by-side preview, or a shell that started before the SDK was installed), Claude Code won't find ClaudeCodeRoslynLspProxy and the LSP will silently fail to spawn.
Verify with where.exe ClaudeCodeRoslynLspProxy (Windows) / which ClaudeCodeRoslynLspProxy (Linux/macOS). If empty, add the directory:
Windows (PowerShell) — persists in the User registry, no terminal restart needed:
$tools = Join-Path $env:USERPROFILE '.dotnet\tools'
[Environment]::SetEnvironmentVariable(
'Path',
((([Environment]::GetEnvironmentVariable('Path', 'User') -split ';') + $tools | Where-Object { $_ } | Select-Object -Unique) -join ';'),
'User')
$env:Path = "$env:Path;$tools"
Linux / macOS — pick the rc file your login shell reads:
echo 'export PATH="$PATH:$HOME/.dotnet/tools"' >> ~/.profile # or ~/.bashrc / ~/.zshrc
exec $SHELL -l
Restart Claude Code after updating PATH so the new value is inherited by the harness.
-
Launch Claude Code.
-
Add the marketplace:
/plugin marketplace add unsafePtr/ClaudeCodeRoslynLspProxy
-
Install the plugin:
/plugin install roslyn-lsp@claude-roslyn-lsp