Built-in MCP server: initialize never completes — empty SSE stream after 200 (Logseq 2.0.1)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 28
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
### Environment
- Logseq: 2.0.1 (desktop, macOS arm64)
- Graph: local DB graph (`personal_knowledge`)
### What Happened
The built-in MCP server (`http://127.0.0.1:12315/mcp`, Bearer token auth) never completes the `initialize` handshake. `POST /mcp` with an `initialize` request returns `HTTP 200` + `mcp-session-id` header + `content-type: text/event-stream`, but the SSE stream never emits a single event. The connection stays open indefinitely, so `initialize` never resolves, `tools/list` is unreachable, and **every** MCP client fails to connect — including the official TypeScript SDK 1.30.0 (`StreamableHTTPClientTransport` times out on `connect`, 20s+).
### Reproduction
1. Start Logseq 2.0.1 with a graph open.
2. `POST http://127.0.0.1:12315/mcp`
- `Content-Type: application/json`
- `Accept: application/json, text/event-stream`
- `Authorization: Bearer `
- body: standard `initialize` JSON-RPC message (tried `protocolVersion` `2024-11-05` and `2025-03-26`)
3. Observe the empty SSE response:
```http
HTTP/1.1 200 OK
cache-control: no-cache
connection: keep-alive
content-type: text/event-stream
mcp-session-id:
Transfer-Encoding: chunked
```
No `data:` events ever follow (tested with curl: 16s+; official SDK client: 20s timeout → `TIMEOUT: initialize hung`).
### Expected
`initialize` should return an SSE `event: message` with the standard result (`protocolVersion`, `capabilities`, `serverInfo`), after which `tools/list` should work.
### Diagnostics
- `GET /mcp` with the session id also stays silent (no SSE events on the resumption channel).
- Malformed requests are answered correctly (e.g. `406 Not Acceptable` when `Accept` is wrong), so the HTTP adapter and auth are alive — only the response flow hangs.
- Startup log shows `[server] MCP routes initialized` and `[server] start successfully!`.
- **Control test**: a minimal local MCP server using the exact SDK version Logseq bundles (`@modelcontextprotocol/sdk` 1.29.0, from `app.asar`) with the same official client 1.30.0 connects and lists tools fine. The hang is therefore in Logseq's MCP wiring, not in the SDK or client.
### Suspected cause
Looks related to the open PR logseq/logseq#12840 "fix(electron): build a fresh MCP server per session". In Logseq 2.0.1, each session gets a fresh `StreamableHTTPServerTransport`, but a single shared `McpServer` is reused across sessions (`a.connect(h)` in the `/mcp` POST handler). The `initialize` result appears to fail to route back to the new session's SSE stream, leaving every client stuck.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the /mcp POST handler and trace how a new StreamableHTTPServerTransport is connected to the reused McpServer, comparing the behavior described in PR logseq/logseq#12840. Reproduce the initialize request with the stated headers and verify that an SSE event containing protocolVersion, capabilities, and serverInfo is emitted and that tools/list becomes reachable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100