claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

LSP servers from plugins not registered - LSP manager initializes before plugin load

Open ghost opened this issue 1 day ago • 1 comments

Description

LSP servers defined in plugin marketplace.json via lspServers configuration are never registered with the LSP manager. The LSP manager initializes and registers 0 servers before plugins are loaded, and never re-checks for LSP servers after plugin initialization completes.

Steps to Reproduce

  1. Create a local marketplace with an LSP plugin (e.g., kotlin-lsp):
// ~/.claude/plugins/local-marketplace/.claude-plugin/marketplace.json
{
  "plugins": [
    {
      "name": "kotlin-lsp",
      "source": "./kotlin-lsp",
      "lspServers": {
        "kotlin": {
          "command": "kotlin-lsp",
          "args": ["--stdio"],
          "extensionToLanguage": {
            ".kt": "kotlin",
            ".kts": "kotlin"
          }
        }
      }
    }
  ]
}
  1. Install the plugin: claude plugin install kotlin-lsp@local-marketplace
  2. Enable the plugin (confirm it shows enabled in /plugins)
  3. Update the marketplace: claude plugin marketplace update local-marketplace
  4. Restart Claude Code with debug mode: claude -d
  5. Check debug logs

Expected Behavior

LSP server should be registered:

LSP notification handlers registered successfully for all 1 server(s)

Actual Behavior

Debug logs show:

[LSP MANAGER] initializeLspServerManager() called
[LSP MANAGER] Created manager instance, state=pending
[LSP MANAGER] Starting async initialization (generation 1)
LSP server manager initialized successfully
LSP notification handlers registered successfully for all 0 server(s)   <-- 0 servers
Loading plugin kotlin-lsp from source: "./kotlin-lsp"                    <-- Plugin loads AFTER
Using manifest version for kotlin-lsp@local-marketplace: 1.0.0
Plugin kotlin-lsp@local-marketplace version 1.0.0 already cached

The LSP manager initializes with 0 servers, then plugins load afterward, but the LSP manager never picks up the lspServers configuration from the loaded plugins.

Environment

  • Claude Code version: 2.0.76
  • OS: macOS (Darwin 24.6.0)
  • Plugin properly shows as enabled in settings.json:
    "enabledPlugins": {
      "kotlin-lsp@local-marketplace": true
    }
    

Additional Context

  • The official pyright-lsp@claude-plugins-official plugin has the same lspServers structure in marketplace.json
  • The plugin IS being loaded (confirmed in debug logs)
  • The marketplace IS being refreshed (after manual claude plugin marketplace update)
  • The LSP binary exists and is functional (/opt/homebrew/bin/kotlin-lsp)

Suggested Fix

The LSP manager should either:

  1. Initialize after plugins are loaded, OR
  2. Re-scan for lspServers configurations after plugin initialization completes

ghost avatar Dec 29 '25 22:12 ghost