Skip to content

VS Code companion drops initial IDE context during MCP connect #2650

Description

@acoliver

Summary

A freshly built and installed LLxprt Code Companion can accept an authenticated MCP connection from LLxprt, but the CLI never receives the editor context that already exists when it connects. The client reports connected while the shared IDE context remains null, so the first model turn has no active file, selection, or open-file context.

This was reproduced with a fully automated real VS Code extension-host/integrated-terminal test, not mocks.

Environment

  • OS: Windows 11 Pro 64-bit, build 26200
  • VS Code: 1.126.0 x64
  • Bun: 1.3.14
  • Repository commit: a25965779a4cff6241ae8ade6d5d3c7036440dfa
  • Companion: locally built from that commit, vybestack.llxprt-code-vscode-ide-companion@0.10.0
  • CLI: repository scripts/start.ts
  • Profile: gpt56high (codex / gpt-5.6-sol); profile authentication independently verified with IDE mode disabled

Reproduction

  1. Build the current companion:
    npm run build:vscode
    
  2. Install the generated VSIX:
    code --install-extension packages/vscode-ide-companion/llxprt-code-vscode-ide-companion-0.10.0.vsix --force
    
  3. Open the repository in VS Code.
  4. Open README.md and select the text LLxprt Code.
  5. Create a new integrated-terminal process after the companion has activated.
  6. Confirm the terminal environment contains all expected companion values:
    • TERM_PROGRAM=vscode
    • numeric LLXPRT_CODE_IDE_SERVER_PORT
    • LLXPRT_CODE_IDE_WORKSPACE_PATH equals the open repository
    • LLXPRT_CODE_IDE_AUTH_TOKEN is present
  7. From that terminal, connect directly and inspect context:
    import {
      IdeClient,
      ideContext,
    } from '@vybestack/llxprt-code-ide-integration';
    
    const client = await IdeClient.getInstance();
    await client.connect();
    await Bun.sleep(1000);
    console.log({
      connection: client.getConnectionStatus(),
      detectedIde: client.getDetectedIdeDisplayName(),
      context: ideContext.getIdeContext(),
    });

Actual direct diagnostic result:

{
  "connection": { "status": "connected" },
  "detectedIde": "VS Code",
  "context": null
}

The same behavior is visible end-to-end:

bun scripts/start.ts --profile-load gpt56high --ide-mode enable --output-format json "Using only the IDE context supplied by the connected VS Code companion, reply with exactly IDE_OK|README.md|LLxprt Code if the active file is README.md and the selected text is LLxprt Code. Otherwise reply with exactly IDE_FAIL followed by a brief reason. Do not use tools to read files; rely only on IDE context."

Actual model response:

IDE_FAIL|No connected VS Code companion context is available.

A baseline run with --ide-mode disable and the same profile successfully returned PROFILE_OK, ruling out profile/provider/authentication failure.

Expected behavior

Immediately after IdeClient.connect() resolves, the initial active editor/open files/selection should be available through ideContext.getIdeContext(). The first model turn should receive the selected README.md context without requiring a subsequent editor event.

Diagnosis

The likely cause is an initial-notification race between the MCP client and companion server:

  • packages/ide-integration/src/ide/ide-client.ts calls await this.client.connect(transport) before this.registerClientHandlers().
  • packages/vscode-ide-companion/src/ide-server.ts sends ide/contextUpdate as a one-time initial notification during the MCP session handshake/request flow, then records that the session has received its initial notification.
  • If the server's initial notification arrives while Client.connect() is still completing, no IdeContextNotificationSchema handler exists yet. The update is dropped, while the transport still becomes connected.
  • With no later editor change, the companion does not broadcast another context update, leaving ideContext undefined for the first model turn.

The current unit tests do not appear to exercise a real initial-context notification arriving during connection setup.

Suggested fix / test

  • Register notification/error/close handlers immediately after constructing Client and before awaiting client.connect(transport), or introduce an explicit post-connect request/ack for the current editor state.
  • Add a behavioral test that starts with an already-active file and selection, connects a real client/server pair, and asserts the initial context is available as soon as connect() completes without a later editor event.

Additional notes

  • The extension itself activates successfully.
  • Its MCP server port, workspace path, and auth token propagate into the integrated terminal correctly.
  • The direct client is authenticated and reports connected; this is specifically loss of initial editor context, not server discovery or authorization failure.
  • No token values or credentials are included in this report.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions