# How Desktop Commander MCP Configuration Persistence Works and Where config.json Is Stored

> Learn how Desktop Commander MCP config persistence works. Discover where config.json is stored and how the ConfigManager class manages your settings automatically.

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

---

**Desktop Commander MCP stores user settings in [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) inside the platform-specific user data directory, managed by the `ConfigManager` class in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) which handles automatic loading, merging with defaults, and saving.**

The Desktop Commander MCP application provides a robust configuration persistence system that ensures user preferences survive across application restarts and updates. According to the wonderwhy-er/DesktopCommanderMCP source code, this system centers on a single JSON file ([`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json)) and a dedicated manager class that abstracts all read and write operations.

## Where config.json Is Stored on Each Platform

The configuration file location varies by operating system. The `getConfigPath()` helper in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) resolves this path using Electron's `app.getPath('userData')` (or `os.homedir()` when running outside Electron).

| Platform | Full Path to [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) |
|----------|---------------------------|
| **Windows** | `%APPDATA%\DesktopCommanderMCP\config.json` |
| **macOS** | `$HOME/Library/Application Support/DesktopCommanderMCP/config.json` |
| **Linux** | `$HOME/.config/DesktopCommanderMCP/config.json` |

This directory choice follows platform conventions: `%APPDATA%` on Windows, `Application Support` on macOS, and `.config` on Linux. The file persists across application updates because it lives outside the application bundle.

## How ConfigManager Handles Persistence

The **`ConfigManager`** class in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) implements the complete persistence lifecycle. It never exposes raw file operations; instead, it provides typed getters/setters and emits events when values change.

### Initialization and Loading

When instantiated, `ConfigManager` immediately loads existing settings or creates [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) with defaults:

```typescript
// src/config-manager.ts – core loading logic
import { app } from 'electron';
import * as fs from 'fs';
import * as path from 'path';
import { defaultConfig } from './config-field-definitions';

const CONFIG_PATH = path.join(app.getPath('userData'), 'config.json');

export class ConfigManager {
  private config = { ...defaultConfig };

  constructor() {
    this.loadConfig();
  }

  private loadConfig() {
    if (fs.existsSync(CONFIG_PATH)) {
      const raw = fs.readFileSync(CONFIG_PATH, 'utf-8');
      this.config = { ...defaultConfig, ...JSON.parse(raw) };
    } else {
      this.saveConfig(); // creates file with defaults on first run
    }
  }
}

```

Key behaviors during initialization:
- **Default merging**: Missing fields in the existing file are filled from [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts), ensuring forward compatibility when new settings are added.
- **Automatic creation**: If [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) does not exist, it is created immediately with all default values.

### Saving Configuration Changes

The **`saveConfig()`** method handles serialization and write operations:

```typescript
// src/config-manager.ts – persistence method
public saveConfig() {
  const data = JSON.stringify(this.config, null, 2);
  fs.writeFileSync(CONFIG_PATH, data, 'utf-8');
  this.emit('config-updated', this.config);
}

```

This method:
1. Formats JSON with 2-space indentation for human readability
2. Performs a **synchronous write** to ensure durability before returning
3. Emits **`config-updated`** so other modules can react to changes immediately

## Configuration Data Model

The configuration structure is defined in two files that work together:

| File | Purpose |
|------|---------|
| [`src/config.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config.ts) | TypeScript `interface Config` describing all available settings |
| [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) | Runtime default values and field metadata |

This separation allows the `ConfigManager` to validate loaded data against the interface while using concrete default values for missing fields.

## How the UI Triggers Persistence

The **Config Editor** component in `src/ui/config-editor/` provides the user-facing interface. When users modify settings, the UI updates the `ConfigManager` instance and explicitly calls `saveConfig()`:

```typescript
// src/ui/config-editor/src/app.ts – UI integration
import { ConfigManager } from '../../../../../config-manager';

const mgr = new ConfigManager();

function onToggleCaffeinate(enabled: boolean) {
  mgr.config.caffeinateWhenInactive = enabled;
  mgr.saveConfig(); // immediate persistence
}

```

The synchronous `saveConfig()` call ensures that users can quit the application immediately after changing settings without data loss.

## Reading Configuration in Other Modules

Tools and features access configuration through the same `ConfigManager` class:

```typescript
// src/tools/usage.ts – example consumer
import { ConfigManager } from '../config-manager';

export function isFeatureEnabled(flag: keyof Config) {
  const mgr = new ConfigManager();
  return Boolean(mgr.config[flag]);
}

```

Modules like [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) also read terminal-specific settings (font size, shell path) from this central source.

## Summary

- **[`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json)** lives in the platform-specific user data directory (`%APPDATA%`, `~/Library/Application Support/`, or `~/.config/`)
- **`ConfigManager`** in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) provides the exclusive API for all configuration operations
- **Default merging** ensures backward and forward compatibility when the schema evolves
- **Synchronous file I/O** guarantees immediate persistence; the `config-updated` event enables reactive UI updates
- **Human-readable JSON** with 2-space indentation allows manual editing when needed

## Frequently Asked Questions

### How do I manually edit Desktop Commander MCP configuration?

Close the application, then open [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) in your platform's user data directory using any text editor. Modify values as needed—the configuration will be validated and merged with defaults on next launch. Invalid JSON will be replaced with default values.

### Will my settings persist when updating Desktop Commander MCP?

Yes. Because [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) resides in the user data directory outside the application bundle, it survives updates, reinstalls, and application version changes. Only deleting the user data directory will remove your settings.

### What happens if I delete config.json?

The application will regenerate [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) with all default values from [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) on the next start. No error is thrown; the `ConfigManager` treats missing files as a first-run scenario.

### Can multiple Desktop Commander MCP instances share configuration?

On the same user account, yes—all instances read from and write to the same `CONFIG_PATH`. Simultaneous modifications from different processes could cause race conditions, though typical single-user usage avoids this. `fs.writeFileSync` provides atomic writes at the system call level for individual save operations.