# MCP Telemetry Collection and Data Pseudonymization: How DesktopCommanderMCP Protects User Privacy

> Learn how DesktopCommanderMCP's privacy-first telemetry pseudonymizes user data with random UUIDs, protecting PII while offering transparent opt-out. Explore MCP telemetry collection and data pseudonymization.

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

---

**DesktopCommanderMCP implements privacy-first telemetry that pseudonymizes every event using a randomly generated UUID, ensuring no personally identifiable information links usage data to individual users while maintaining transparent opt-out controls.**

DesktopCommanderMCP is an open-source MCP (Model Context Protocol) server that handles file system operations and command execution. Understanding its approach to MCP telemetry collection and data pseudonymization reveals how the project balances product analytics with strict privacy protections. The implementation uses a proxy-based architecture, opaque identifiers, and explicit user consent mechanisms to ensure data minimization.

## Core Telemetry Architecture

### The Telemetry Proxy Pattern

Rather than connecting directly to analytics backends, DesktopCommanderMCP routes all events through a lightweight proxy. In [[`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts), the primary endpoint `https://telemetry.desktopcommander.app/mp/collect` handles ingestion, while a fallback URL ensures redundancy. This proxy strips request-origin metadata before forwarding to BigQuery, preventing the analytics store from receiving raw client IP addresses or direct connection details.

### Client Identifier and Pseudonymization

The pseudonymization layer centers on a **randomly generated UUID** stored as `clientId` in the user's configuration. Defined in the `ServerConfig` interface in [[`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (line 16), this identifier persists across sessions but never correlates to email addresses, usernames, or OS-level identifiers. The UUID lives in the standard config directory (`~/.config/desktop-commander/config.json` by default), ensuring that every telemetry event remains anonymous.

### Opt-Out Controls via telemetryEnabled

User agency is enforced through the `telemetryEnabled` boolean flag, located in the same `ServerConfig` interface at line 13 of [[`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts). Defaulting to enabled for first-run experience, this setting is respected by every telemetry call through the `isTelemetryDisabledValue` helper (lines 43-45), which normalizes string values like `"false"` or `"FALSE"` to boolean equivalents.

### Graceful Fallback Mechanisms

The system implements **silent failure** principles to prevent telemetry from impacting core functionality. If the primary proxy fails, the code automatically retries `TELEMETRY_PROXY_FALLBACK_URL`, and all network calls are wrapped in `try/catch` blocks. Guard clauses in [[`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 106-115) ensure that disabled telemetry returns early without throwing errors.

## Data Pseudonymization Implementation

### The clientId UUID Strategy

Every telemetry payload includes four core fields: `event` (string name), `clientId` (UUID), `version` (application version), and `timestamp`. The `clientId` is the sole identification mechanism—an opaque string generated during initial configuration that contains no encoded personal data. This approach ensures that event streams cannot be reverse-engineered to reveal user identities while still allowing aggregate analysis of usage patterns.

### Transmission Security

Events transmit over HTTPS to the proxy endpoint, where TLS encryption protects data in transit. The proxy architecture adds a sanitization layer between the DesktopCommanderMCP client and the analytics warehouse, ensuring that backend storage never receives direct client fingerprints or network metadata.

### Absence of Personal Data

The telemetry system explicitly excludes personal identifiers. When [[`track-installation.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js) captures installation events, it only records the `clientId`, operating system type, and timestamp—never capturing home directory paths, environment variables containing usernames, or machine hostnames.

## Telemetry Lifecycle in Practice

### The capture() Function Implementation

The [`capture()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) function in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 92-110) serves as the central emission point. It constructs payloads by merging the event name with configuration values retrieved through `configManager.getValue()`:

```typescript
// src/utils/capture.ts – simplified flow
export async function capture(eventName: string, payload: any) {
  const telemetryEnabled = await configManager.getValue('telemetryEnabled');
  if (isTelemetryDisabledValue(telemetryEnabled)) return;   // respect opt-out

  const clientId = await configManager.getValue('clientId');
  const body = {
    event: eventName,
    clientId,
    version: VERSION,
    timestamp: Date.now(),
    ...payload,
  };
  
  try {
    await fetch(TELEMETRY_PROXY_URL, { 
      method: 'POST', 
      body: JSON.stringify(body),
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (e) {
    // Fail silently; retry with fallback URL if implemented
  }
}

```

### Installation Tracking Example

Real-world usage appears in [[`track-installation.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js), which builds an installation payload and calls `capture('install', payload)`. This demonstrates how the system records adoption metrics without exposing sensitive system information.

## Managing Telemetry Preferences

### Programmatic Opt-Out

Users can disable telemetry without editing configuration files manually. The `configManager.updateConfig()` method provides a clean API for toggling the `telemetryEnabled` flag:

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

async function disableTelemetry() {
  await configManager.updateConfig({ telemetryEnabled: false });
  console.log('Telemetry disabled successfully');
}

disableTelemetry();

```

When set to `false`, all subsequent `capture()` calls return at the guard clause, guaranteeing zero network traffic to analytics endpoints.

### Checking Current Settings

Verify your current telemetry status and pseudonymized ID using the configuration manager:

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

async function checkTelemetryStatus() {
  const enabled = await configManager.getValue('telemetryEnabled');
  const clientId = await configManager.getValue('clientId');
  
  console.log(`Telemetry enabled: ${enabled}`);
  console.log(`Pseudonymous client ID: ${clientId}`);
}

checkTelemetryStatus();

```

## Code Examples for Developers

### Sending Custom Events

Extend the telemetry system for custom monitoring while maintaining the same privacy protections:

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

async function reportCustomAction(action: string, details: Record<string, any>) {
  await capture('custom_action', { action, ...details });
}

// Usage
await reportCustomAction('batch_rename', { fileCount: 150 });

```

### Reading the Pseudonymized Client ID

Access the anonymous identifier for debugging or correlation purposes:

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

async function getClientId() {
  const id = await configManager.getValue('clientId');
  console.log('Your pseudonymous client ID:', id);
  // Example output: 550e8400-e29b-41d4-a716-446655440000
}

getClientId();

```

## Summary

- **Proxy Architecture**: DesktopCommanderMCP routes telemetry through `https://telemetry.desktopcommander.app/mp/collect` via the `capture()` function in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts), adding a privacy layer between clients and analytics storage.
- **Pseudonymization**: The `clientId` UUID in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) provides the only identification, containing no personal data and persisting in `~/.config/desktop-commander/config.json`.
- **Opt-Out Control**: The `telemetryEnabled` flag in `ServerConfig` allows immediate cessation of data collection, respected by guard clauses in every telemetry call.
- **Silent Operation**: All telemetry failures are caught and ignored, with fallback URL support ensuring that network issues never block core functionality.
- **Transparency**: Installation tracking in [`track-installation.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js) demonstrates real-world usage limited to system type and timestamp, excluding sensitive path or identity information.

## Frequently Asked Questions

### What data does DesktopCommanderMCP collect through its telemetry system?

DesktopCommanderMCP collects event data including the action type (e.g., "install"), a pseudonymized `clientId` UUID, application version, operating system type, and timestamp. As implemented in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts), the system explicitly excludes file paths, usernames, environment variables, and other personally identifiable information from every payload.

### How does the pseudonymization mechanism protect my identity?

The system generates a random UUID stored as `clientId` in your configuration file during first run. This identifier, defined in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts), contains no encoded personal information and never links to your email, username, or hardware identifiers. When combined with the proxy architecture that strips request metadata, this ensures that telemetry events cannot be traced back to individual users.

### Can I completely disable telemetry collection?

Yes. Set `telemetryEnabled` to `false` using the configuration API, which updates your [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) file. The `isTelemetryDisabledValue` helper in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) ensures that once disabled, the `capture()` function returns immediately without emitting network requests, guaranteeing zero data transmission to the proxy endpoints.

### Where is my configuration and client ID stored?

The `clientId` and `telemetryEnabled` settings persist in a JSON configuration file located at `~/.config/desktop-commander/config.json` by default, as defined in [`src/config.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config.ts). This standard directory location keeps sensitive configuration separate from application code while remaining accessible for user inspection or modification.