fix(dotnet): add Claude Code-shaped .lsp.json so LSP loads in Claude Code#598
fix(dotnet): add Claude Code-shaped .lsp.json so LSP loads in Claude Code#598romanglogowski-volue wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a Claude Code–compatible LSP configuration for the dotnet plugin so Roslyn registers correctly in Claude Code without changing the existing Copilot CLI LSP setup.
Changes:
- Introduces
plugins/dotnet/.lsp.jsonusing Claude Code’s.lsp.jsonschema (server map at root +extensionToLanguage). - Keeps the existing
plugins/dotnet/lsp.json(Copilot CLI schema withlspServerswrapper +fileExtensions) unchanged.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@dotnet-policy-service agree company="Volue" |
Claude Code auto-discovers `.lsp.json` at plugin root and expects a schema that differs from Copilot CLI's `lsp.json`: - No outer `lspServers` wrapper in the external file (the wrapper is only used when defining LSP servers inline in `plugin.json`). - Required field is `extensionToLanguage`, not `fileExtensions`. Without this file, Claude Code silently rejects the existing `lsp.json` (Copilot CLI shape) and the Roslyn language server is never registered — `/reload-plugins` reports `0 plugin LSP servers`. After adding `.lsp.json`, the count becomes `1 plugin LSP server` and `findReferences`, `goToImplementation`, etc. work end-to-end. The existing `lsp.json` is left untouched so Copilot CLI continues to work; the two hosts read different filenames and never see each other's config. References: - https://code.claude.com/docs/en/plugins-reference (lspServers, external `.lsp.json` format, required fields) - https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers (Copilot CLI uses `lsp.json` with `lspServers` wrapper and `fileExtensions`) Signed-off-by: Roman Głogowski <roman.glogowski@volue.com>
88d4cd9 to
e03f2f2
Compare
|
Ping :) |
|
Tagging @JoeRobich and @dibarbet to help with review. Related #607 |
|
✅ Automated diff scan completed for This is an automated static analysis of the PR diff. Note 🔒 Integrity filter blocked 84 itemsThe following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
|
✅ Automated diff scan completed for This is an automated static analysis of the PR diff. Note 🔒 Integrity filter blocked 47 itemsThe following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
|
✅ Automated diff scan completed for This is an automated static analysis of the PR diff. Note 🔒 Integrity filter blocked 42 itemsThe following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
|
✅ Automated diff scan completed for This is an automated static analysis of the PR diff. Note 🔒 Integrity filter blocked 35 itemsThe following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
|
✅ Automated diff scan completed for This is an automated static analysis of the PR diff. Note 🔒 Integrity filter blocked 83 itemsThe following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
|
✅ Automated diff scan completed for This is an automated static analysis of the PR diff. Note 🔒 Integrity filter blocked 14 itemsThe following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
Co-authored-by: Joey Robichaud <joseph.robichaud@microsoft.com>
Summary
Claude Code silently rejects the existing
plugins/dotnet/lsp.jsonand the Roslyn language server is never registered (/reload-pluginsreports0 plugin LSP servers). This adds a siblingplugins/dotnet/.lsp.jsonshaped for Claude Code's documented LSP schema. Copilot CLI continues to read the existinglsp.jsonunchanged — the two hosts read different filenames.Why two files?
Claude Code and Copilot CLI document different LSP plugin schemas:
lsp.json.lsp.json(auto-discovered at plugin root)lspServers: { … }requiredfileExtensionsextensionToLanguageSources:
The existing
lsp.jsonis correctly shaped for Copilot CLI, but applying it as-is in Claude Code fails parse on both fronts (lspServerswrapper + missingextensionToLanguage). Adding a second file shaped for Claude Code is the smallest portable fix.Verification
Locally (Windows 11, Claude Code Opus 4.7, .NET 10 SDK,
roslyn-language-serverinstalled viadotnet tool install -g):Before:
After (with
.lsp.jsonin place):findReferencesandgoToImplementationagainst a real interface symbol work end-to-end through Claude Code's LSP tool.Scope
Only
plugins/dotnet/. Other plugins in this repo (dotnet-data,dotnet-test,dotnet-aspnet, …) don't currently ship LSP configs, so nothing else needs the same change.Test plan
/plugin install dotnet@dotnet-agent-skillsin Claude Code →/reload-pluginsreports1 plugin LSP serverfor thedotnetpluginlsp.jsonis still picked up (no regression).csfile →goToDefinition/findReferenceswork via Roslyn