# How Desktop Commander MCP Telemetry Collection Works: Privacy-First Implementation

> Understand Desktop Commander MCP telemetry collection. Learn how its privacy-first, opt-in system sanitizes data like file paths and user identifiers before transmission.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: internals
- Published: 2026-07-13

---

**Desktop Commander MCP collects anonymous usage telemetry through an opt-in system that automatically sanitizes all sensitive data—including file paths, user identifiers, and error stack traces—before transmission to a secure endpoint.**

The `wonderwhy-er/DesktopCommanderMCP` repository implements a privacy-preserving telemetry collection system designed to gather usage insights without compromising user security. This TypeScript-based MCP server uses a multi-stage pipeline to capture, sanitize, and transmit event data, ensuring that no personally identifiable information ever leaves the local environment. Understanding how this telemetry collection mechanism operates helps developers audit the data flow and configure the system according to their privacy requirements.

## How Telemetry Collection Works

The telemetry collection system in Desktop Commander MCP follows a seven-step pipeline that begins with user consent and ends with secure transmission. Each stage is designed to minimize data exposure while maintaining diagnostic utility.

### Opt-in Configuration

Telemetry collection is controlled by the boolean configuration field `telemetryEnabled`, defined in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) (lines 26-30), which defaults to **true**. Users can disable telemetry at runtime by setting the environment variable **`DESKTOP_COMMANDER_DISABLE_TELEMETRY`** to any of the following values: `1`, `true`, `yes`, or `on`. This dual-layer control ensures that system administrators can enforce telemetry policies without modifying configuration files.

### Event Capture API

Throughout the codebase, developers invoke `await capture('event_name', { … })` or `await captureRemote('event_name', { … })` to record actions. The `capture()` function, implemented in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 82-87), first checks the execution context—specifically filtering out calls originating from widget UI contexts, which are **silently ignored**. Valid events proceed to the telemetry pipeline for processing.

### Building Standard Event Properties

The `buildEventProperties()` function in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 28-41) constructs a base payload containing **non-personal** metadata:

- **timestamp**: ISO 8601 formatted date
- **platform**: Operating system identifier from `os.platform()`
- **container metadata**: Detection flags including `isContainer`, `containerType`, `orchestrator`, and sanitized versions of `containerName` and `containerImage`
- **runtime source**: Classification as `smithery-runtime`, `npx-runtime`, or `direct-runtime`
- **isDXT flag**: Boolean indicating whether installed via DXT
- **app_version**: Current Desktop Commander version
- **client context**: `client_name` and `client_version` strings
- **saw_onboarding_page**: User onboarding completion flag

### Data Sanitization Pipeline

Before merging caller-provided properties, the system performs aggressive sanitization in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 57-69). The process **deep-copies** all properties and applies these filters:

- **Error sanitization**: Strips stack traces from any `error` object, retaining only the `message` and optional `code` fields
- **Path removal**: Deletes any keys resembling file paths (`path`, `filePath`, `directory`, etc.), replacing values with `[PATH]` placeholders, except for `fileExtension` which is preserved
- **Identity stripping**: For remote telemetry, removes identity keys including `deviceId`, `userId`, and `email`

### Payload Transmission

The `sendToTelemetryProxy()` function in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 25-33) assembles the final JSON payload and POSTs it to `https://telemetry.desktopcommander.app/mp/collect`. If the primary endpoint fails, the system implements a **single retry** against a Cloud Run fallback URL. All network errors are silently caught to ensure that telemetry failures never interrupt core application functionality.

### Opt-out Handling

When users disable telemetry via `configManager.setValue('telemetryEnabled', false)`, the code in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (lines 44-66) emits a single `server_telemetry_opt_out` event **before** persisting the new configuration value. This allows the development team to measure opt-out rates accurately while respecting the user's decision to cease further data collection.

## What Data Is Captured by Desktop Commander MCP

The final telemetry payload contains only generic, non-identifying information. The system explicitly excludes file contents, absolute paths, user emails, device IDs, and personally identifiable data. A typical transmitted event appears as follows:

```json
{
  "client_id": "<generated-uuid>",
  "timestamp_micros": 1720971234567890,
  "events": [
    {
      "name": "event_name",
      "params": {
        "timestamp": "2024-07-13T12:34:56.789Z",
        "platform": "darwin",
        "isContainer": "false",
        "containerType": "none",
        "orchestrator": "none",
        "containerName": "none",
        "containerImage": "none",
        "runtimeSource": "direct-runtime",
        "isDXT": "false",
        "app_version": "1.2.3",
        "client_name": "desktop-commander-cli",
        "client_version": "1.2.3",
        "saw_onboarding_page": true
      }
    }
  ]
}

```

All potentially sensitive keys are replaced with placeholders or removed entirely before transmission.

## Implementing Telemetry in Your Code

The following examples demonstrate how to properly instrument code using the Desktop Commander MCP telemetry collection utilities:

```typescript
import { capture, captureRemote } from './utils/capture.js';

// Simple telemetry event for tool execution
await capture('tool_executed', {
  tool_name: 'edit',
  file_extension: 'ts',
  user_action: 'replace',
  // File paths are automatically filtered out
  filePath: '/home/user/sensitive/path'  // Will be replaced with [PATH]
});

// Remote-device telemetry with identity stripping
await captureRemote('remote_tool_call', {
  tool_name: 'search',
  query: 'TODO comments',
  userId: '12345'   // Automatically removed before transmission
});

```

To disable telemetry collection programmatically:

```typescript
import { configManager } from './config-manager.js';

// Emit opt-out event and disable future collection
await configManager.setValue('telemetryEnabled', false);

```

Or disable via environment variable for a single execution:

```bash
DESKTOP_COMMANDER_DISABLE_TELEMETRY=1 npx desktop-commander-mcp

```

## Summary

- **Desktop Commander MCP** implements telemetry collection through a privacy-first pipeline defined in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) that defaults to enabled but supports both configuration-based and environment-based opt-out.
- **All sensitive data**—including file paths, error stack traces, and user identifiers—is automatically sanitized or removed before transmission, ensuring no PII leaves the system.
- **Two capture functions** exist: `capture()` for local operations and `captureRemote()` for remote devices, with the latter applying additional identity stripping.
- **Transmission** occurs via POST request to `https://telemetry.desktopcommander.app/mp/collect` with automatic retry logic and silent failure handling.
- **Opt-out events** are tracked via `server_telemetry_opt_out` in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) to measure privacy preference trends without violating user consent.

## Frequently Asked Questions

### Does Desktop Commander MCP collect personal data or file contents?

No. According to the source code in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts), the telemetry collection system explicitly removes any keys resembling file paths (replacing them with `[PATH]` placeholders), strips error stack traces, and filters out identity fields like `userId` and `email`. The system only captures generic metadata such as platform type, container environment, and runtime source.

### How can I completely disable telemetry collection?

You have two methods to disable telemetry collection. First, set the environment variable `DESKTOP_COMMANDER_DISABLE_TELEMETRY` to `1`, `true`, `yes`, or `on` before starting the application. Alternatively, programmatically call `configManager.setValue('telemetryEnabled', false)` from [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts), which will emit a final opt-out event and persist the disabled state.

### What happens if the telemetry endpoint is unreachable?

The `sendToTelemetryProxy()` function in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) implements graceful degradation. If the primary endpoint at `telemetry.desktopcommander.app` fails, the system attempts one retry against a Cloud Run fallback URL. All network errors are silently caught and ignored, ensuring that telemetry transmission failures never impact core MCP functionality or user experience.

### What is the difference between `capture()` and `captureRemote()`?

The `capture()` function handles standard local telemetry events while filtering out widget UI contexts. The `captureRemote()` function, also defined in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts), adds a `remote: "true"` flag to the payload and applies additional sanitization specifically designed for remote device scenarios, ensuring that any identity markers from remote environments are thoroughly stripped before transmission.