LSP tool not recognizing custom LSP server configuration (metals/Scala)
Bug Description
The LSP tool returns \"No LSP server available for file type: .scala\" despite having a correctly configured custom LSP server in ~/.claude/settings.json. The LSP server (metals) is never invoked, even after session restarts.
Environment
- Claude Code Version: 2.1.168
- Platform: macOS (Darwin 24.6.0)
- LSP Server: metals 1.6.7 (installed via Coursier)
- Project Type: Gradle-based Scala project
Configuration
~/.claude/settings.json:
{
"env": {
"ENABLE_LSP_TOOL": "1"
},
"lsp": {
"servers": {
"scala": {
"command": "metals",
"args": [],
"rootPatterns": [
"build.sbt",
"build.sc",
".scalafmt.conf",
"build.gradle",
"build.gradle.kts"
],
"extensions": [
".scala",
".sbt",
".sc"
]
}
},
"debug": true
}
}
Steps to Reproduce
- Install metals LSP server (
cs install metals) - Add LSP configuration to
~/.claude/settings.jsonas shown above - Restart Claude Code session
- Navigate to a Scala project with
build.gradleat root - Run:
LSP documentSymbol on file.scala
Expected Behavior
- Claude Code should detect the
.scalafile extension - Start the metals LSP server
- Return document symbols from the file
Actual Behavior
LSP tool result: "No LSP server available for file type: .scala"
Debugging Performed
- ✅ Verified
metalscommand is in PATH and executable - ✅ Confirmed
ENABLE_LSP_TOOL=1is set in environment - ✅ Validated JSON syntax of settings.json
- ✅ Restarted Claude Code session multiple times
- ✅ Tried both
.scalaandscalain extensions field - ✅ Created wrapper script to detect if metals is invoked - wrapper was never called
- ✅ Added multiple rootPatterns including
build.gradle,.scalafmt.conf - ✅ Tried creating plugin structure similar to rust-analyzer
- ✅ Enabled debug mode (
"debug": true)
Key finding: The metals command is never invoked by Claude Code, suggesting the LSP configuration isn't being loaded or recognized at all.
Additional Context
- The
rust-analyzerLSP works (configured as a plugin at~/.claude/plugins/cache/claude-plugins-official/rust-analyzer-lsp) - CloudFormation LSP servers are running (observed in process list)
- No LSP-related errors in
~/.claude/daemon.log - Wrapper script test confirmed metals binary works when invoked directly
Comparison with Working LSP
The only LSP that works is rust-analyzer, which:
- Has a plugin directory structure at
~/.claude/plugins/cache/claude-plugins-official/rust-analyzer-lsp/ - Is enabled in settings:
"enabledPlugins": {"rust-analyzer-lsp@claude-plugins-official": true} - Has the same structure in settings.json
lsp.serverssection
This suggests custom LSP configurations might require plugin infrastructure, or there's a registration step missing for non-plugin LSP servers.
Questions
- Are custom LSP server configurations in
settings.jsonsupposed to work without plugin infrastructure? - Is there a registration or initialization step required beyond adding to
lsp.servers? - Are there any logs that would show why the LSP configuration isn't being loaded?
Impact
Users cannot add custom LSP servers (like metals, kotlin-lsp, etc.) using only settings.json configuration, limiting LSP support to pre-packaged plugins.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗