# How the VS Code Companion Extension Synchronizes IDE State with the Qwen Code Agent

> Learn how the VS Code companion extension synchronizes IDE state using an MCP HTTP server to send real-time context updates to the Qwen Code agent via JSON RPC.

- Repository: [Qwen/qwen-code](https://github.com/qwenlm/qwen-code)
- Tags: internals
- Published: 2026-02-19

---

**The VS Code companion extension runs a local MCP HTTP server that watches UI events via `OpenFilesManager` and broadcasts real-time IDE context updates to the Qwen Code agent through JSON-RPC notifications.**

The Qwen Code project provides a VS Code companion extension that bridges your editor with the Qwen Code agent, enabling AI-assisted coding with full awareness of your workspace. To maintain this awareness, the extension must continuously synchronize the IDE state—including open files, cursor positions, and workspace trust status—with the agent. This synchronization is achieved through a local Model-Context-Protocol (MCP) server that captures UI events and streams context updates in real time.

## Architecture Overview

### The Model-Context-Protocol (MCP) Server

At the heart of the synchronization mechanism is the `IDEServer` class defined in [`packages/vscode-ide-companion/src/ide-server.ts`](https://github.com/QwenLM/qwen-code/blob/main/packages/vscode-ide-companion/src/ide-server.ts). This component starts an Express HTTP server on a random local port and implements the **Model-Context-Protocol (MCP)** to communicate with the Qwen Code agent. During initialization, the server generates a UUID authentication token and writes the port number, workspace paths, and token to a lock file, making them available to the agent via environment variables.

### OpenFilesManager Event Tracking

To capture the dynamic state of the IDE, the extension uses the `OpenFilesManager` class from [`packages/vscode-ide-companion/src/open-files-manager.ts`](https://github.com/QwenLM/qwen-code/blob/main/packages/vscode-ide-companion/src/open-files-manager.ts). This manager subscribes to critical VS Code UI events including `onDidChangeActiveTextEditor`, `onDidChangeTextEditorSelection`, notebook focus changes, and file creation or deletion events. Each event handler updates an internal `openFiles` array and triggers `fireWithDebounce()` to emit a change notification, ensuring the agent receives updates without excessive noise.

## Step-by-Step Synchronization Flow

### Extension Activation and Server Initialization

When the VS Code extension activates via the `activate` function in [`packages/vscode-ide-companion/src/extension.ts`](https://github.com/QwenLM/qwen-code/blob/main/packages/vscode-ide-companion/src/extension.ts), it creates a `ReadonlyFileSystemProvider` and `DiffManager`, then instantiates `IDEServer`. The `server.start(context)` method generates authentication credentials, binds to a random port, and writes the connection details to a lock file. This establishes the communication channel that the Qwen Code agent uses to connect via MCP.

### Capturing IDE State Changes

As the user interacts with VS Code, the `OpenFilesManager` continuously builds an `IdeContext` object. This object contains `workspaceState.openFiles`—a snapshot of currently open files with their cursor positions and selections—and the workspace trust status. When any tracked event fires, the manager calls `fireWithDebounce()` to emit an `onDidChange` event, signaling that the IDE state has evolved.

### Broadcasting Updates to the Agent

The `IDEServer` registers a listener on `OpenFilesManager.onDidChange` that invokes `broadcastIdeContextUpdate()`. This method iterates over all active MCP transports and sends a JSON-RPC notification with the method `ide/contextUpdate`. The payload follows the `IdeContextNotificationSchema` defined in `@qwen-code/qwen-code-core/src/ide/types.js`, ensuring the agent receives a structured snapshot of the current workspace state in real time.

## Key Implementation Details

### Authentication and Lock File Management

Security is enforced through a UUID-based authentication token generated in `IDEServer.start()`. The server writes this token along with the port and workspace information to a lock file using `writePortAndWorkspace()`. The Qwen Code agent reads these values from environment variables to establish an authenticated MCP connection, preventing unauthorized access to the IDE state.

### Handling Workspace Changes

When workspace folders are added or removed, or when trust status changes, `IDEServer.syncEnvVars()` rewrites the lock file and triggers a fresh broadcast of the IDE context. This ensures the agent always operates with accurate workspace boundaries and security context, even as the user modifies their VS Code environment.

## Code Example: Triggering a Manual Sync

Developers can force an immediate synchronization by invoking the available API directly. The following TypeScript snippet demonstrates how to trigger a manual environment variable sync and context broadcast from within a VS Code command:

```typescript
// Inside any VS Code command implementation
import * as vscode from 'vscode';
import { IDEServer } from './ide-server';

// Assume `ideserver` is the instance created in activate()
async function forceSync() {
  // Force a write of the lock file (port, workspace, token)
  await ideserver.syncEnvVars();
  // Explicitly broadcast the latest IDE state
  ideserver.broadcastIdeContextUpdate();
}
vscode.commands.registerCommand('qwen.forceSync', forceSync);

```

This pattern is useful for debugging synchronization issues or ensuring the agent has the latest state before executing critical operations.

## Summary

- The VS Code companion extension synchronizes IDE state through a local MCP HTTP server implemented by the `IDEServer` class.
- The `OpenFilesManager` watches VS Code UI events and maintains an `IdeContext` snapshot containing open files, cursor positions, and workspace trust status.
- Changes are broadcast to the Qwen Code agent via JSON-RPC notifications using the `ide/contextUpdate` method.
- Authentication is secured through UUID tokens and lock files, with automatic resynchronization when workspace folders or trust status changes.

## Frequently Asked Questions

### What protocol does the VS Code companion extension use to communicate with the Qwen Code agent?

The extension implements the **Model-Context-Protocol (MCP)** over HTTP, using JSON-RPC notifications to stream IDE state updates to the agent in real time.

### How does the extension handle rapid UI changes without overwhelming the agent?

The `OpenFilesManager` uses a debounced event emitter (`fireWithDebounce`) that batches rapid successive changes into single notification events, preventing network congestion while maintaining near-real-time synchronization.

### What security measures protect the IDE state communication?

The `IDEServer` generates a UUID authentication token during startup and writes it to a lock file alongside the server port. The agent must present this token to establish an MCP connection, ensuring only authorized processes can access the IDE state.

### Does the extension support manual synchronization triggers?

Yes. Developers can call `ideserver.syncEnvVars()` to rewrite the lock file and `ideserver.broadcastIdeContextUpdate()` to force an immediate context broadcast, useful for debugging or ensuring state consistency before critical operations.