# How Remote MCP Enables Web-Based AI Clients to Access Local Resources

> Remote MCP uses Supabase to let web AI clients securely access local resources like files and shell commands on your PC without internet exposure. Learn how it works.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: how-to-guide
- Published: 2026-07-11

---

**Remote MCP bridges web-based AI clients to local machines through a persistent Supabase real-time connection, allowing cloud-based models to execute file operations and shell commands on the user's computer without exposing the filesystem to the internet.**

Remote MCP (Model Context Protocol) powers the **DesktopCommanderMCP** architecture, enabling web-based AI clients like Claude, OpenAI, or Gemini to securely invoke local tools. This system uses a three-tier design—a local device process, a Supabase real-time channel, and the core Desktop Commander server—to tunnel tool requests from the cloud to the user's machine while maintaining strict isolation between the web client and local network.

## Architecture of the Remote MCP System

The implementation relies on three tightly coupled components that coordinate through Supabase's real-time infrastructure.

### The MCP Device Process

The **MCP Device** is a lightweight Node process that runs persistently on the user's local machine. Implemented in [`src/remote-device/device.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/remote-device/device.ts), the `MCPDevice` class authenticates via Supabase, registers the device in the `mcp_devices` table, and maintains a heartbeat to signal availability. It receives tool-call payloads from the cloud and forwards them to the local Desktop Commander core for execution.

### The Remote Channel (Supabase Real-Time)

The **Remote Channel** in [`src/remote-device/remote-channel.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/remote-device/remote-channel.ts) wraps the Supabase client and manages the `device_tool_call_queue` channel. It listens for `INSERT` events on the `mcp_remote_calls` table, filtering by the authenticated user's ID to ensure isolation. The channel handles automatic reconnection, health checks to detect stuck sockets, and status updates back to the server (executing, completed, or failed).

### The Desktop Commander Server

The **Desktop Commander Server** ([`src/server.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/server.ts)) exposes the actual tool implementations—file I/O, process spawning, and system navigation. When a remote request arrives, the server invokes `DesktopCommanderIntegration.callClientTool` to run the tool locally. Telemetry captured via `captureRemote` in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) tags these calls with `remote:true` to distinguish remote usage from local MCP connections.

## Bootstrapping the Remote Connection

The entry point for activating Remote MCP is the npm script `runRemote` defined in [`src/npm-scripts/remote.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/npm-scripts/remote.ts). When a user executes `npx desktop-commander-remote` with optional flags, the system initializes the device and establishes a persistent cloud connection.

```typescript
// src/npm-scripts/remote.ts
import { MCPDevice } from '../remote-device/device.js';

export async function runRemote() {
  const persistSession = process.argv.includes('--persist-session');
  const verbose = process.argv.includes('--debug');
  
  const device = new MCPDevice({ persistSession });
  await device.start(); // Handles authentication and channel setup
}

```

### Establishing the Supabase Session

Inside `MCPDevice.start()`, the device fetches Supabase configuration from the remote MCP server endpoint `/api/mcp-info`, then initializes the `RemoteChannel`:

```typescript
// src/remote-device/device.ts (excerpt)
this.remoteChannel = new RemoteChannel();
await this.remoteChannel.initialize(supabaseUrl, anonKey);
// setSession called with access/refresh tokens from device authentication

```

The user's Supabase **user ID** becomes the anchor for all subsequent real-time events, ensuring that tool calls route only to the intended device.

### Subscribing to the Tool-Call Queue

After authentication, `MCPDevice.registerDevice()` subscribes to the specific queue for that user:

```typescript
// src/remote-device/remote-channel.ts (excerpt)
this.channel = this.client.channel('device_tool_call_queue')
  .on('postgres_changes', {
    event: 'INSERT',
    schema: 'public',
    table: 'mcp_remote_calls',
    filter: `user_id=eq.${this.user.id}`
  }, payload => {
    this.onToolCall?.(payload); // Forward to MCPDevice handler
  })
  .subscribe(/* status handling */);

```

The channel's health-check routine (`checkConnectionHealth`) automatically recreates the connection if the socket enters a stuck `joining` state.

## Executing Local Tools from the Cloud

When a web-based AI client requests a tool—such as `read_file` or `start_process`—the remote server inserts a row into the `mcp_remote_calls` table. The real-time subscription delivers this payload to `MCPDevice.handleNewToolCall()`:

```typescript
// src/remote-device/device.ts (excerpt)
async handleNewToolCall(payload) {
  const { id: call_id, tool_name, tool_args, metadata } = payload.new;
  
  await this.remoteChannel.markCallExecuting(call_id);
  
  let result;
  if (tool_name === 'ping') {
    result = { content: [{ type: 'text', text: `pong ${new Date().toISOString()}` }] };
  } else {
    // Delegate to local desktop integration
    result = await this.desktop.callClientTool(tool_name, tool_args, metadata);
  }
  
  await this.remoteChannel.updateCallResult(call_id, 'completed', result);
}

```

The flow follows three distinct phases:

1. **Status Update**: `markCallExecuting` updates the database row status to *executing*, signaling to the AI client that work has begun.
2. **Local Execution**: `DesktopCommanderIntegration.callClientTool` runs the requested tool locally—performing file reads, process spawns, or directory searches—without the cloud client ever touching the local filesystem.
3. **Result Persistence**: `updateCallResult` writes the tool output (or error details) back to the `mcp_remote_calls` row, where the AI client can poll or receive push notifications to retrieve the result.

This asynchronous but deterministic round-trip allows the AI client to continue reasoning while the local device processes long-running operations, such as generating CSV summaries or executing build scripts.

## Connection Health and Lifecycle Management

Remote MCP maintains reliability through proactive heartbeat monitoring and graceful shutdown handling.

### Heartbeat Monitoring

Every **15 seconds** (`HEARTBEAT_INTERVAL`), the device calls `RemoteChannel.updateHeartbeat()` to update the `last_seen` timestamp on the `mcp_devices` record. If the heartbeat fails or the channel health check detects a stale connection, the system forces a reconnection to ensure the remote AI client maintains access while the device remains online.

### Graceful Shutdown

When the AI client sends a `shutdown` tool call, `handleNewToolCall` triggers `MCPDevice.shutdown()`, which:

1. Stops the heartbeat interval.
2. Unsubscribes from the Supabase channel.
3. Marks the device as offline in the database via `setOffline`.
4. Invokes `DesktopCommanderIntegration.shutdown()` to release local resources.

All failure paths are captured with `captureRemote` telemetry, enabling monitoring of remote connection reliability.

## Summary

- **Remote MCP** enables web-based AI clients to execute local tools by maintaining a persistent Supabase real-time connection between the cloud and a local Node process.
- The **MCP Device** ([`src/remote-device/device.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/remote-device/device.ts)) authenticates users, manages session persistence, and dispatches tool calls to the local Desktop Commander server.
- Tool requests queue in the **Supabase** `mcp_remote_calls` table, with the **Remote Channel** ([`src/remote-device/remote-channel.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/remote-device/remote-channel.ts)) filtering events by user ID and handling automatic reconnection.
- Local execution occurs through `DesktopCommanderIntegration.callClientTool`, ensuring file contents and process outputs never traverse the internet unprotected.
- **Heartbeat intervals** and health checks maintain connection stability, while graceful shutdown ensures clean resource release.

## Frequently Asked Questions

### What is Remote MCP and how does it differ from standard local MCP?

**Remote MCP** extends the Model Context Protocol to allow web-based AI clients hosted in the cloud to access tools running on a user's local machine. Standard local MCP requires the AI client to run on the same machine as the tools, whereas Remote MCP uses a Supabase real-time channel to bridge the gap, enabling browser-based or API-based AI services to read files and execute commands on your computer without requiring local installation of the AI client itself.

### How does the system handle network interruptions or disconnections?

The **Remote Channel** implements automatic reconnection logic through `checkConnectionHealth`, which monitors the Supabase socket state. If the channel becomes stuck in a `joining` state or the connection drops, the wrapper recreates the `device_tool_call_queue` subscription. Additionally, the **MCP Device** sends a heartbeat every 15 seconds to update its `last_seen` status; if heartbeats fail, the device attempts to re-establish the session before marking itself offline.

### What security measures prevent unauthorized access to local resources?

Access control relies on **Supabase authentication** and row-level security. The `RemoteChannel` subscribes to the `mcp_remote_calls` table with a specific filter—`user_id=eq.${this.user.id}`—ensuring the device only receives tool calls intended for the authenticated user. The device must present valid access and refresh tokens obtained during the initial `MCPDevice.start()` flow, and all telemetry is tagged with `remote:true` in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) for audit purposes.

### Which local tools can web-based AI clients access through Remote MCP?

The web-based client can access the full suite of Desktop Commander tools exposed in [`src/server.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/server.ts), including **file operations** (`read_file`, `write_file`, `list_directory`), **process management** (`start_process`, `read_process_output`, `stop_process`), and **system utilities** (`search_files`, `get_file_info`). When invoked remotely, these tools execute exactly as they would for a local MCP connection, with results streamed back through the Supabase queue.