Skip to content

MCP server: "Cannot read LSP message: Stream was closed" on every request; CLI path works (v0.2.0-beta) #239

Description

@spitters

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

  1. install-beam.sh --dont-ask --toolchain leanprover/lean4:v4.30.0 --claude --claude-mcp.
  2. lean-beam doctor: bundle ready: true, daemon starts live, incidents none.
  3. CLI works: lean-beam ensure then lean-beam update <file>{"ok":true,"result":{"version":1,"changed":true}}.
  4. MCP fails: lean_update {path:<file>, workspace:{root:<project>}}internalError "Cannot read LSP message: Stream was closed".
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions