Skip to content

Fix MCP connection errors, slow stepping, and stale debug state#96

Open
ksa-real wants to merge 2 commits into
microsoft:mainfrom
ksa-real:fix/reliability-and-perf
Open

Fix MCP connection errors, slow stepping, and stale debug state#96
ksa-real wants to merge 2 commits into
microsoft:mainfrom
ksa-real:fix/reliability-and-perf

Conversation

@ksa-real

Copy link
Copy Markdown

Summary

Three reliability/perf fixes to the extension, with regression tests:

  • Connection "errored" badge. Run StreamableHTTPServerTransport in stateful session mode so GET /mcp opens a real server→client SSE stream, and register the GET/DELETE /mcp routes at startup (they were previously nested inside the POST error handler, so GET returned a bare 404). Cursor's MCP client treated the failed SSE open as a fatal transport error and tombstoned the connection as "errored" even though POST tool calls were working.
  • Slow stepping (~1s/step). Replace the 1s blind-poll waitForStateChange with an event-driven wait on vscode.debug.onDidChangeActiveStackItem / onDidTerminateDebugSession, cutting per-step latency from ~1s to milliseconds.
  • Stale state reports. Derive the current file/line from the DAP top stack frame instead of scraping the active editor, fixing stale "paused at line N" reports.

Tests

  • debugMCPServer.security.test.ts — a "Streamable-HTTP session lifecycle" suite driving the real handshake: initialize over POST mints an mcp-session-id, GET /mcp with that id returns a live text/event-stream (the regression that flagged the server "errored"), and GET /mcp with a missing/unknown session is rejected with 400.
  • debuggingHandler.test.tswaitForStateChange tests (via handleStepOver) asserting the fast-path resolves in ms when the new line is already observable or the session ended, and that a bounded timeout (not a blind 1s sleep) governs the no-change case.

No version bump or package.json change; this is implementation + tests only.

ksa-real added 2 commits June 21, 2026 03:16
Three reliability/perf fixes to the extension:

- Server: run StreamableHTTPServerTransport in stateful session mode so
  GET /mcp opens a real server->client SSE stream. Register GET/DELETE
  /mcp at startup (previously nested in the POST error handler, so GET
  returned a bare 404). Cursor's client treated the failed SSE open as a
  fatal transport error and tombstoned the connection as "errored" even
  though POST tool calls worked.

- Stepping: replace the 1s blind-poll waitForStateChange with an
  event-driven wait on vscode.debug.onDidChangeActiveStackItem /
  onDidTerminateDebugSession, cutting per-step latency from ~1s to ms.

- State: derive current file/line from the DAP top stack frame instead
  of scraping the active editor, fixing stale "paused at line N" reports.
Cover the three reliability/perf fixes that the existing suite missed:

- debugMCPServer.security.test.ts: a "Streamable-HTTP session lifecycle"
  suite that drives the real handshake — initialize over POST mints an
  mcp-session-id, GET /mcp with that id returns a live text/event-stream
  (the regression that left Cursor flagging the server "errored"), and
  GET /mcp with a missing/unknown session is rejected with 400.

- debuggingHandler.test.ts: waitForStateChange tests (via handleStepOver)
  asserting the fast-path resolves in ms when the new line is already
  observable or the session ended, and that the bounded timeout (not a
  blind 1s sleep) governs the no-change case.
@ksa-real

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@matx-sergei

Copy link
Copy Markdown

@ozzafar Do you take contributions? I see a bunch of PRs are hanging for a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants