[BUG] MCP servers (java-lsp) are re-spawned on every new Claude Code session/window without reusing or cleaning up the previous instance, causing unbounded process/memory growth
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Each time a new Claude Code session/window is started against the same project directory, a brand-new java-lsp MCP server (and its child Eclipse JDT Language Server process) is spawned. The previous session's java-lsp process tree is not reused and not terminated when the new session starts or when the old session/window closes. Over a single working day this leads to multiple fully-duplicated language-server instances all indexing the exact same workspace, consuming several GB of RAM that is never reclaimed.
Process tree evidence (all pointing at the identical jdtls workspace index directory for the same project):
| Layer | PID | Parent PID | Created | RSS |
|---|---|---|---|---|
| Claude Desktop root | 32476 | (shell launcher) | 19:20:50 | — |
| Claude session child A | 35048 | 32476 | 19:24:20 | — |
| Claude session child B | 48056 | 32476 | 19:28:05 | — |
| lsp4j-mcp (session A) | 30180 | 35048 | 19:24:23 | 111 MB |
| jdtls (session A) | 21940 | 28604 (python wrapper) | 19:24:27 | 1165 MB |
| lsp4j-mcp (session B) | 9228 | 48056 | 19:28:06 | 118 MB |
| jdtls (session B) | 44864 | 27876 (python wrapper) | 19:28:08 | 968 MB |
After manually killing session A's process tree and continuing to use session B normally (verified working), restarting Claude Code produced yet another full duplicate:
| Layer | PID | Parent PID | Created | RSS |
|---|---|---|---|---|
| lsp4j-mcp (new session C) | 34436 | 32476 (root) | 19:44:38 | 192 MB |
| jdtls (new session C) | 22560 | 42936 (python wrapper) | 19:44:39 | 1228 MB |
Session B's process tree (9228/44864) was still alive and untouched at this point — confirming the new session did not detect, reuse, or replace it.
Impact:
- Each
jdtlsinstance starts with-Xms1G; three concurrent duplicates measured ~3.25 GB of resident memory for what should be a single language-server instance for one workspace. - Combined with the
lsp4j-mcpwrapper duplicates, total waste was ~3.6 GB on a 15.7 GB machine (23% of total RAM) before manual cleanup. - This directly caused unrelated local
mvnbuilds to fail withNative memory allocation (malloc) faileddue to system-wide memory pressure. - Memory is never reclaimed automatically; it accumulates indefinitely across restarts within a work day.
A new full java-lsp process tree (MCP wrapper + JDT Language Server) is spawned on every new session/restart, and previous instances are left running indefinitely as orphans, even after their owning Claude Code window has been restarted/closed.
What Should Happen?
For a given project directory, Claude Code should either:
- Reuse an already-running local-scope MCP server (e.g.
java-lsp) across sessions/windows opened against the same project path, instead of spawning a brand-new instance every time, OR - If a new MCP server instance must be spawned per session, it should terminate that server's full process tree (including child processes it launches, such as a language server) when the owning session/window closes or when Claude Code restarts.
Either approach would keep exactly one live instance of a given local-scope MCP server (and its child processes) per project, regardless of how many times a session is restarted or how many windows are opened against the same project.
Error Messages/Logs
Steps to Reproduce
- Open a Claude Code session in a Java project with
java-lspregistered as a local-scope MCP server. - Use any
java-lsptool at least once (e.g.find_symbolsordocument_symbols) to force the server to actually start, not just lazily register. - Restart Claude Code (or open a new window/session) against the same project.
- Inspect running processes (e.g. on Windows:
Get-CimInstance Win32_Process -Filter "Name='java.exe'") — observe a second fulllsp4j-mcp+jdtlsprocess tree pointing at the same workspace data directory (...\jdtls-data\<hash>), while the first tree from step 2 is still running and was never terminated. - Repeat steps 3–4 — the process count grows unbounded with each restart, and memory usage climbs accordingly (each
jdtlsinstance alone reserves-Xms1G).
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.206
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
_No response_