[FEATURE] Cross-surface session discovery: VS Code-launched sessions are invisible to the session-management MCP tools

Status Open
Reported on v2.1.219
Maintainer reply None cached
Activity 1 comment · opened Jul 29, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

I run several Claude Code sessions at once on one machine against one repository — some from the desktop app, at least one from the VS Code extension — using git worktrees to keep them from colliding.

The session-management MCP tools (list_sessions, get_session, send_message, search_session_transcripts) only ever show me the sessions the desktop app started. A session started by the VS Code extension is absent from list_sessions, and get_session rejects it for both id forms:

Session <uuid> not found.
Session local_<uuid> not found.

send_message resolves through the same lookup, so it cannot deliver to it either, and search_session_transcripts does not match its content.

This is easy to misdiagnose as a per-login split, and it is not. My VS Code session shared the default config directory with the desktop sessions and was still invisible. It also isn't a filtering choice: reading the shipped desktop app, the list_sessions handler filters on exactly two predicates — sessionId != self and include_archived || !isArchived. There is no entrypoint/source predicate, and no entrypoint field exists in the session records to filter on. It enumerates an in-memory map of sessions the desktop app itself spawned.

So a VS Code session is never registered, rather than registered-and-filtered. That distinction matters for the fix: no filter needs relaxing — a registration or discovery path needs to exist.

The practical cost is that the session I most need to see is the one I can't. In my case a VS Code session was working directly in the shared primary checkout — the single most collision-prone place in a worktree setup — while three desktop sessions worked in isolated worktrees. No supported tool could tell me that.

There's a second-order problem too: multi-session coordination conventions are advisory. When one participant is structurally invisible, every convention has a guaranteed defector — the session nobody can see is also the one bound by nothing.

Proposed Solution

Make local session discovery cross-surface. Concretely, any one of these would solve it, in descending order of preference:

  1. list_sessions enumerates local sessions regardless of which surface launched them. The data already exists on disk — <config-root>/sessions/<pid>.json is written by the CLI itself, contains every surface, and already carries an entrypoint field (claude-desktop / claude-vscode) that distinguishes them. Nothing needs inventing; the desktop app just doesn't read it.
  1. A supported read-only roster tool, if full parity is too invasive — enough to answer "which of my sessions are running, where, and on which surface".
  1. If messaging must stay desktop-only, fail loudly rather than silently. A session that cannot be addressed should appear in the listing marked unaddressable, instead of being missing. Right now the boundary is only discoverable by noticing an absence, which is exactly the kind of thing that gets confidently guessed at wrong.

Alternative Solutions

I wrote my own roster — roughly 200 lines of PowerShell reading <config-root>/sessions/*.json across every config root, joining to git worktrees, and verifying liveness — and wired it into a SessionStart hook so each new session opens knowing who else is live.

It works, but it depends on an undocumented private file, and two things made it harder than it should be:

  • PID reuse. The registry records carry a procStart field that appears intended to guard against exactly this, but on my machine it serialises as absent and the guard returns true when it cannot determine the value — i.e. it fails open toward "still alive". A naive liveness check therefore reports a recycled PID as a live session. I had to compute process start times myself and compare them against the recorded session start.
  • No heartbeat. Registry writes are event-driven, so recency is not a liveness signal in either direction. A "dead" verdict here can never be trusted enough to authorise a destructive action.

I also found what looks like a peer-to-peer session-messaging protocol already compiled into the CLI — named-pipe transport, a typed message envelope, peer lookup by session id — that is inert: the registry field carrying a peer's socket address is written by no code path, so peer discovery can only ever return an empty set. It fails silently, returning an empty peer list rather than an error. I mention it because it suggests much of this may already be built and switched off, which would make (1) cheaper than it looks.

Priority

High - Significant impact on productivity

Feature Category

MCP server integration

Use Case Example

  1. I open four Claude Code sessions on one repo: three from the desktop app in separate git worktrees, one from the VS Code extension.
  2. A session asks "who else is working in this repo right now, and where?" so it can avoid duplicating work or editing a file someone else is mid-change on.
  3. list_sessions returns the three desktop sessions. The VS Code session — which is editing the shared primary checkout on main — does not appear at all.
  4. That session goes ahead and works in the primary too, because nothing told it otherwise.

With cross-surface discovery, step 3 would list all four with their surface and working directory, and step 4 wouldn't happen.

Environment

  • Windows 11
  • Desktop app + VS Code extension on the same machine, same default config directory
  • CLI 2.1.219 (desktop-spawned) and 2.1.220 (VS Code-spawned)

Related

  • #82141 — documentation gap covering the same tool surface (what list_sessions scopes to, and the semantics of session-to-session messaging). This request is the behaviour change; that one is satisfied by documenting current behaviour.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗