MCP server: "Cannot read LSP message: Stream was closed" on every request; CLI path works
Summary
The lean-beam-mcp server fails on the first workspace-bound request for any file with
internalError "Cannot read LSP message: Stream was closed". The identical operation via the
lean-beam CLI on the same workspace/file succeeds. So the daemon, plugin, and v4.30.0 bundle
are functional; only the MCP-server code path cannot hold its Lean LSP connection.
Root cause signal (from beam_feedback_report collected stats)
stats.byBackend.lean: requestCount: 5, errorCount: 5, successCount: 0, sessionStarts: 0, sessionRestarts: 0, workerExitedCount: 0; openFiles.sessions.lean.active: false.
The Lean backend session never starts (sessionStarts: 0, no worker ever exits) — so every
workspace-bound request hits an absent/closed stream. The MCP broker's session-start path is
broken, whereas the CLI daemon does start a Lean session. .beam/beam-daemon-startup.log is empty
(no spawn diagnostic captured).
Reproduction
install-beam.sh --dont-ask --toolchain leanprover/lean4:v4.30.0 --claude --claude-mcp.
lean-beam doctor: bundle ready: true, daemon starts live, incidents none.
- CLI works:
lean-beam ensure then lean-beam update <file> → {"ok":true,"result":{"version":1,"changed":true}}.
- MCP fails:
lean_update {path:<file>, workspace:{root:<project>}} → internalError "Cannot read LSP message: Stream was closed".
- Reproduced with no MCP client via the wrapper:
lean-beam-mcp --self-check <file> → same error (its internal lean_sync).
Ruled out as causes: file weight (fails on a trivial 3-line no-import file and on a large
import-closure file alike); root/daemon contention (fails with the CLI daemon shut down, root clean);
environment (fails under the MCP client env and under a login shell with elan/lean on PATH); daemon
liveness (fails whether or not lean-beam ensure ran first). beam_version/beam_stats succeed
(no workspace binding), so the MCP transport is up; only workspace-bound requests that must drive the
Lean LSP fail.
Expected
lean_update / lean_sync return a document version (as the CLI lean-beam update does).
Impact
The MCP surface — the agent/tool-facing half — is unusable; only the CLI works. Agents drive Lean
through the MCP tools, so Beam cannot be adopted for the intended agent workflow until this is fixed.
Workaround
Use the lean-beam CLI (update/goals/hover), which starts and holds the Lean session; the MCP
path does not.
MCP server: "Cannot read LSP message: Stream was closed" on every request; CLI path works
lean-beam-mcp 0.2.0-beta(commit0bc94e6d9af2), MCP protocol2026-07-28leanprover/lean4:v4.30.0(exact-validated), bundle readySummary
The
lean-beam-mcpserver fails on the first workspace-bound request for any file withinternalError "Cannot read LSP message: Stream was closed". The identical operation via thelean-beamCLI on the same workspace/file succeeds. So the daemon, plugin, and v4.30.0 bundleare functional; only the MCP-server code path cannot hold its Lean LSP connection.
Root cause signal (from
beam_feedback_reportcollected stats)stats.byBackend.lean:requestCount: 5, errorCount: 5, successCount: 0, sessionStarts: 0, sessionRestarts: 0, workerExitedCount: 0;openFiles.sessions.lean.active: false.The Lean backend session never starts (
sessionStarts: 0, no worker ever exits) — so everyworkspace-bound request hits an absent/closed stream. The MCP broker's session-start path is
broken, whereas the CLI daemon does start a Lean session.
.beam/beam-daemon-startup.logis empty(no spawn diagnostic captured).
Reproduction
install-beam.sh --dont-ask --toolchain leanprover/lean4:v4.30.0 --claude --claude-mcp.lean-beam doctor: bundle ready: true, daemon starts live, incidents none.lean-beam ensurethenlean-beam update <file>→{"ok":true,"result":{"version":1,"changed":true}}.lean_update {path:<file>, workspace:{root:<project>}}→internalError "Cannot read LSP message: Stream was closed".lean-beam-mcp --self-check <file>→ same error (its internallean_sync).Ruled out as causes: file weight (fails on a trivial 3-line no-import file and on a large
import-closure file alike); root/daemon contention (fails with the CLI daemon shut down, root clean);
environment (fails under the MCP client env and under a login shell with elan/lean on PATH); daemon
liveness (fails whether or not
lean-beam ensureran first).beam_version/beam_statssucceed(no workspace binding), so the MCP transport is up; only workspace-bound requests that must drive the
Lean LSP fail.
Expected
lean_update/lean_syncreturn a document version (as the CLIlean-beam updatedoes).Impact
The MCP surface — the agent/tool-facing half — is unusable; only the CLI works. Agents drive Lean
through the MCP tools, so Beam cannot be adopted for the intended agent workflow until this is fixed.
Workaround
Use the
lean-beamCLI (update/goals/hover), which starts and holds the Lean session; the MCPpath does not.