ClaudeCodeRoslynLspProxy
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Basarisiz
- rm -rf — Recursive force deletion command in .github/workflows/release.yml
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Thin LSP proxy that injects Roslyn's solution/open into Claude Code's LSP client so findReferences, goToDefinition, hover, callHierarchy work solution-wide for C#.
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 likerename,codeAction, orformatting— even thoughroslyn-language-serverimplements 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, pruningbin,obj,node_modules,.git, etc. - Sends
solution/opento the server with the discovered URI. - Falls back to
project/openover all.csprojif 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
dotnettools:dotnet tool install --global roslyn-language-server --prerelease dotnet tool install --global ClaudeCodeRoslynLspProxyroslyn-language-serveris Microsoft's officialMicrosoft.CodeAnalysis.LanguageServer(ownersMicrosoft/RoslynTeamon NuGet; source dotnet/roslyn). Microsoft only ships pre-release versions, so--prereleaseis required.Make sure the global-tools directory is on
PATH. Both tools install to%USERPROFILE%\.dotnet\toolson Windows or$HOME/.dotnet/toolson Linux/macOS. The .NET SDK installer usually adds this to your userPATH, 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 findClaudeCodeRoslynLspProxyand 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 -lRestart Claude Code after updating
PATHso the new value is inherited by the harness.Launch Claude Code.
Add the marketplace:
/plugin marketplace add unsafePtr/ClaudeCodeRoslynLspProxyInstall the plugin:
/plugin install roslyn-lsp@claude-roslyn-lspRestart Claude Code to load the plugin. No config prompt — the proxy invokes
roslyn-language-server --stdio --autoLoadProjects --logLevel Informationand lets Roslyn use its own telemetry default (silent). Fork the manifest if you need different values; the plugin intentionally does not expose auserConfigprompt because${user_config.*}substitution fails silently when the prompt is dismissed or its values fail to persist, which leaves the LSP unable to start.Verify with
/plugin—roslyn-lsp@claude-roslyn-lspshould be listed as enabled.Update later (on demand):
dotnet tool update --global roslyn-language-server --prerelease dotnet tool update --global ClaudeCodeRoslynLspProxy/plugin update roslyn-lsp@claude-roslyn-lsp
Verify
In a C# project ask Claude to "find references to X". Then:
# Windows
Get-Content $env:TEMP\roslyn-lsp-logs\proxy.log -Tail 5
# Linux
tail -5 /tmp/roslyn-lsp-logs/proxy.log
# macOS — Path.GetTempPath() resolves to $TMPDIR (/var/folders/.../T/), not /tmp
tail -5 "${TMPDIR:-/tmp}/roslyn-lsp-logs/proxy.log"
The log directory is wherever .NET's Path.GetTempPath() resolves on the host:%TEMP% on Windows, /tmp on Linux, $TMPDIR on macOS.
Expected last line: [proxy] open notification sent: solution/open (file:///.../YourSolution.slnx). First call after a cold start takes 10–30 s while Roslyn indexes; subsequent calls are sub-second.
Building from source
git clone https://github.com/unsafePtr/ClaudeCodeRoslynLspProxy
cd ClaudeCodeRoslynLspProxy
dotnet pack src/ClaudeCodeRoslynLspProxy/ClaudeCodeRoslynLspProxy.csproj -c Release -o ./artifacts
dotnet tool install --global --add-source ./artifacts ClaudeCodeRoslynLspProxy
For local plugin work: claude plugin marketplace add C:/path/to/ClaudeCodeRoslynLspProxy.
Troubleshooting
Proxy never runs even though plugin shows enabled. Claude Code launches LSP servers lazily — only when you invoke the LSP tool or open a .cs/.csx/.cshtml file. Until then no process exists and proxy.log is silent.
findReferences returns 0–1 results on a large solution. Roslyn indexes in the background; the first call after solution/open can hit before indexing finishes. Wait 10–60 s and retry.
solution/open was not sent. Check proxy.log. Possible last lines:
solution/open (file:///.../*.slnx)— happy path.project/open (N projects)— no.slnx/.slnfound, fell back to.csproj.(none — transparent pipe)— no solution or projects found; per-document mode. Open Claude Code at the directory containing your solution, or pass--solution <path>via custom plugin config.
Schema validation error on .lsp.json (Unrecognized key: "csharp"). You wrote { "lspServers": { "csharp": { ... } } } — that's the plugin.json inline shape. In .lsp.json drop the lspServers wrapper.
Updating the proxy binary. Fully restart Claude Code — /reload-plugins does not respawn already-running LSP processes.
CLI reference
ClaudeCodeRoslynLspProxy --server <path-to-roslyn-language-server[.cmd]>
[--solution <path>] # explicit .sln/.slnx — overrides discovery
[--log <path>] # default: <temp>/roslyn-lsp-logs/proxy.log
-- <args forwarded to roslyn-language-server>
--server resolves bare names against PATH (auto-appending .cmd/.exe on Windows).
Tests
dotnet run --project tests/ClaudeCodeRoslynLspProxy.Tests
dotnet run --project tests/ClaudeCodeRoslynLspProxy.Tests -- -class "*DiscoveryTests"
Coverage: LSP framing, URI conversion, solution/project discovery, initialize-message inspection, server-path resolution, and end-to-end PumpAsync wiring against in-memory pipes. CI also runs an integration smoke against a real roslyn-language-server install.
Roadmap
--mode=mcp— MCP companion exposingtextDocument/rename,codeAction, andformattingas MCP tools, filling the edit-side gap in Claude Code's LSP surface. (Today, pair with SharpToolsMCP for those operations.)- Real
workspaceSymbolonce Claude Code passes a query-string parameter.
Acknowledgments
- Anthropic — built with the help of Claude Code; roughly 50% Claude's contribution, 50% vibe-coded.
dotnet/roslyn— the language server and protocol handlers this proxy wires up.dotnet/vscode-csharp—roslynProtocol.tsconfirmed thesolution/open/project/openwire format.Piebald-AI/claude-code-lsps— reference for the Claude Code LSP plugin manifest shape (.lsp.jsonschema).Agasper/CSharpLspAdapter— independent proxy targetingcsharp-language-server; surfaced the same class of problem on a different upstream LSP.SofusA/csharp-language-server(deprecated) andanomalyco/opencodePR #14463 — prior art on the proxy approach and thecsharp-ls→roslyn-language-servermigration.
License
MIT — see LICENSE.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi