# How the UsageTracker in Desktop Commander MCP Collects and Reports Telemetry Data While Protecting Sensitive Information

> Learn how Desktop Commander MCP's UsageTracker safely collects anonymous telemetry data. Discover how sensitive information like file paths and stack traces are stripped before transmission.

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

---

**Desktop Commander MCP's UsageTracker class aggregates anonymous tool usage statistics in memory and persists them non-blocking, while the capture utility sanitizes all outbound telemetry by stripping file paths, stack traces, and container identifiers before transmission.**

The Desktop Commander MCP repository implements a privacy-first telemetry pipeline that captures high-level usage patterns without compromising user security. Understanding how the UsageTracker collects and reports telemetry data while ensuring no sensitive information is captured requires examining the interaction between the aggregation layer in [`src/utils/usageTracker.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/usageTracker.ts), the configuration management system, and the sanitization protocols in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts). This implementation guarantees that file paths, system identifiers, and error details never leave the local environment.

## Anonymous Usage Aggregation Architecture

The telemetry system separates data collection from transmission, ensuring sensitive information never enters the aggregation layer.

### In-Memory Statistics with UsageTracker

The **`UsageTracker`** class in [`src/utils/usageTracker.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/usageTracker.ts) maintains a `ToolUsageStats` object that counts tool invocations by category. When developers call **trackSuccess()** or **trackFailure()**, the utility updates per-tool counters and session timestamps in memory, then queues the data for background persistence via `configManager.setValueNonBlocking` (lines 58-84). This non-blocking approach ensures that recording usage never delays the actual tool execution.

The class also implements feedback heuristics in `getStats()` (lines 71-78), surfacing prompts only when users meet specific thresholds—typically after three days of activity and at least ten tool calls—preventing intrusive onboarding interruptions.

### Persistent Client Identification

Configuration management in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) stores two critical telemetry values: a randomly generated UUID `clientId` (lines 26-34) that remains stable across sessions, and the boolean `telemetryEnabled` flag (lines 13-18). The system initializes `telemetryEnabled` to **true** by default, making telemetry opt-out rather than opt-in, though users retain full control through environment variables.

## Privacy-First Transmission Pipeline

Before any data reaches the network, the **`capture`** utility in [`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) applies a multi-stage sanitization process.

### Telemetry Enablement Checks

The capture utility returns immediately without network activity if `DESKTOP_COMMANDER_DISABLE_TELEMETRY` is set in the environment, or if `telemetryEnabled` is false in the persisted configuration. This dual-gate mechanism allows both temporary CI/CD disabling and permanent user preference enforcement.

### Context Enrichment Without Exposure

When enabled, capture attaches metadata to every event including the client type (desktop-commander, remote device, etc.) and container context from [`src/utils/system-info.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/system-info.ts). The system detects Docker and Smithery environments (lines 19-33) to segment usage by deployment type, but deliberately excludes host-level identifiers that could fingerprint specific machines.

### Deep Data Sanitization

The sanitization engine removes three categories of sensitive data before transmission:

- **Error scrubbing**: The `sanitizeError` function (lines 57-70) strips stack traces and file paths from error objects, preventing accidental disclosure of local directory structures.
- **Path key removal**: Any property key suggesting a file system location—such as `path`, `filePath`, or `directory`—is removed from the payload entirely, with exceptions only for innocuous keys like `fileExtension` (lines 61-69).
- **Container anonymization**: Long hex strings and UUIDs within container names or image references are collapsed to the placeholder `ID` and truncated to prevent leakage of deployment specifics (lines 91-100).

### Fire-and-Forget Delivery

Sanitized payloads are posted to `https://telemetry.desktopcommander.app/mp/collect` using a short-lived HTTPS request with a strict three-second timeout (lines 99-107). The system silently ignores network failures, ensuring that telemetry transmission never blocks the user-facing workflow or generates error noise in the application logs.

## Implementation Examples

The following patterns demonstrate how to interact with the telemetry system while respecting its privacy constraints:

```typescript
// Record a successful tool call (aggregates locally, persists in background)
import { usageTracker } from './utils/usageTracker.js';

await usageTracker.trackSuccess('read_file');
// Returns updated stats; actual storage is non-blocking via configManager

```

```typescript
// Manually emit sanitized telemetry (internal use only)
import { capture } from './utils/capture.js';

await capture('tool_used', {
  tool: 'execute_command',
  args: ['ls', '-la'],
  // Automatically removes path-like keys and attaches client/container metadata
});

```

```typescript
// Disable telemetry for CI environments
process.env.DESKTOP_COMMANDER_DISABLE_TELEMETRY = 'true';

```

## Summary

- **UsageTracker** ([`src/utils/usageTracker.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/usageTracker.ts)) aggregates tool statistics in memory and persists them via non-blocking configuration updates, triggering feedback prompts only after usage thresholds are met.
- **Configuration management** ([`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts)) maintains a stable anonymous client ID and telemetry preferences, defaulting to enabled but respecting explicit opt-out signals.
- **Capture utility** ([`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts)) enforces mandatory data sanitization by removing file paths, stack traces, and container identifiers before any network transmission.
- **Delivery mechanism** uses fire-and-forget HTTPS requests with short timeouts to ensure telemetry never impacts application performance or reliability.
- **Opt-out controls** exist at both the environment variable level (`DESKTOP_COMMANDER_DISABLE_TELEMETRY`) and persistent configuration level (`telemetryEnabled`).

## Frequently Asked Questions

### How can I completely disable telemetry in Desktop Commander MCP?

Set the environment variable `DESKTOP_COMMANDER_DISABLE_TELEMETRY` to any truthy value before starting the application, or set `telemetryEnabled` to `false` in the configuration store via `configManager`. Either method causes the `capture` utility to return immediately without network activity, and UsageTracker will continue local aggregation without attempting remote transmission.

### What specific sensitive data does the capture utility remove before transmission?

The sanitizer strips three categories of sensitive information: stack traces and file paths from error objects via `sanitizeError`, any object property with keys suggesting file system locations (`path`, `filePath`, `directory`), and identifiable container metadata by replacing hex strings and UUIDs with the placeholder `ID`. File extensions are preserved intentionally as they contain no personal information while providing useful usage statistics.

### How does the UsageTracker determine when to surface feedback prompts?

The `getStats()` method checks aggregated statistics against thresholds defined in [`src/utils/usageTracker.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/usageTracker.ts) (lines 71-78), typically requiring at least three days of recorded activity and a minimum of ten tool calls. This heuristic ensures that feedback requests only appear for active users with substantial experience using the toolset.

### Where is telemetry data stored locally before being transmitted?

Statistics are stored in the shared configuration file managed by [`config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config-manager.ts), accessed via `configManager.setValueNonBlocking`. The data includes per-tool counters, session timestamps, and total call counts—never including arguments, file contents, or execution results. The `clientId` UUID is also persisted here to maintain consistent anonymous identification across application restarts.