# How Desktop Commander MCP Manages BlockedCommands Configuration and Security

> Desktop Commander MCP secures users against shell command risks using a dynamic blocklist and fail-closed security, ensuring no dangerous commands execute.

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

---

**Desktop Commander MCP protects users from dangerous shell commands by maintaining a configurable blocklist that is validated at runtime against every command token, with fail-closed defaults that prevent execution if validation fails.**

Desktop Commander MCP is a Model Context Protocol (MCP) server that enables AI assistants to execute shell commands safely on local machines. The **Desktop Commander MCP blockedCommands configuration** provides a robust security layer that prevents unintentional execution of destructive system commands through a user-managed blocklist enforced at multiple levels of the application stack.

## Configuration Schema Definition

The blocklist architecture begins with a strict schema definition in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts). The `CONFIG_FIELD_DEFINITIONS` object declares the `blockedCommands` field as an array type with explicit UI labeling:

```typescript
blockedCommands: {
  label: 'Blocked Commands',
  description: 'This is your personal safety blocklist. If a command appears here, Desktop Commander will refuse to run it even if a prompt asks for it. …',
  valueType: 'array',
},

```

This schema serves as the single source of truth for both the data structure and the user interface. The UI layer in [`src/ui/config-editor/src/app.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/config-editor/src/app.ts) consumes this definition to render the configuration editor and display the current block count:

```typescript
if (entry.key === 'blockedCommands') {
  return `${count} command${count === 1 ? '' : 's'} blocked`;
}

```

## Default Blocklist Initialization and Persistence

When the application initializes, `ConfigManager.init()` in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (lines 13-60) checks for the existence of [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json). If the configuration file is missing, the manager generates a default blocklist containing high-risk system commands. According to the source code, the default blocked commands include `sudo`, `dd`, `shutdown`, `iptables`, and other destructive operations (lines 115-159).

The persistence layer ensures thread-safe updates through a serialized write chain. Every modification to the blocklist is immediately written to disk, preventing race conditions between the UI, API, and file system. The configuration path is defined in [`src/config.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config.ts) and consumed by the manager to locate the JSON store.

## Runtime Command Validation

The security enforcement occurs in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) through the `validateCommand` method (lines 29-61). This function acts as the runtime gatekeeper, executing a four-stage validation pipeline:

1. **Load current configuration** via `configManager.getConfig()`
2. **Extract command tokens** using the `extractCommands` utility, which parses pipelines, subshells (`$()`), and path prefixes
3. **Check against blocklist** by comparing each extracted base command against the `blockedCommands` array
4. **Return boolean result** indicating execution safety

### Command Tokenization and Parsing

The validation logic handles complex shell constructs by decomposing command strings into individual executable tokens. The `extractCommands` function strips path prefixes to identify base command names, ensuring that `/usr/bin/sudo` matches the `sudo` entry in the blocklist. This parsing handles pipelines and command substitution to prevent circumvention through shell syntax.

### Fail-Closed Security Behavior

The validation mechanism implements a fail-closed design. If `validateCommand` encounters any exception during configuration reading or command parsing, it logs the error and returns `false`, thereby blocking execution rather than risking a privilege escalation:

```typescript
for (const cmd of allCommands) {
  if (blockedCommands.includes(cmd)) {
    return false; // Command is blocked
  }
}
return true; // No blocked command found

```

## Security Guarantees and Defense-in-Depth

Desktop Commander MCP implements defense-in-depth by enforcing the blocklist at multiple architectural layers. The UI prevents users from configuring blocked commands through the settings editor, while the runtime validation in `CommandManager` blocks any backdoor execution attempts that might bypass the interface.

The system maintains user control over the security policy. Administrators can extend or shrink the blocklist through manual [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) edits or the graphical configuration interface. However, the default blocklist provides immediate protection against common destructive commands across Linux, macOS, and Windows environments.

## Practical Implementation Examples

### Extending the Blocklist Programmatically

To add a custom blocked command such as `rm` (recursive deletion), interact with the `ConfigManager` singleton:

```typescript
// Assuming you have a reference to the config manager
const cfg = await configManager.getConfig();
cfg.blockedCommands = [...(cfg.blockedCommands ?? []), 'rm'];
await configManager.saveConfig(); // Persists to disk

```

### Pre-Execution Validation

Always validate user-supplied strings before passing them to the execution engine:

```typescript
import { commandManager } from './command-manager';

async function runIfSafe(userCmd: string) {
  const safe = await commandManager.validateCommand(userCmd);
  if (!safe) {
    console.error('Refused to run a blocked command:', userCmd);
    return;
  }
  // Proceed with execution…
}

```

### UI Integration

Display the current security status in custom interfaces by querying the configuration:

```typescript
import { CONFIG_FIELD_DEFINITIONS } from '../../config-field-definitions';

const count = (await configManager.getConfig()).blockedCommands?.length ?? 0;
return <span>{count} command{count !== 1 ? 's' : ''} blocked</span>;

```

## Summary

- **Desktop Commander MCP blockedCommands configuration** is defined in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) and enforced through a unified schema that drives both data validation and UI rendering.
- The default blocklist in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (lines 115-159) includes dangerous commands like `sudo`, `dd`, and `shutdown`, initialized automatically when no configuration exists.
- Runtime validation in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) (lines 29-61) extracts command tokens from complex shell strings and checks them against the blocklist using a fail-closed policy.
- The architecture provides defense-in-depth by blocking commands in both the configuration UI and the execution runtime, with user-configurable policies that persist to [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json).

## Frequently Asked Questions

### How does Desktop Commander MCP handle blockedCommands configuration updates?

Configuration changes are persisted immediately through the `ConfigManager.saveConfig()` method, which writes to [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) using a serialized write chain to prevent race conditions. Updates take effect on the next command validation cycle, as `commandManager.validateCommand()` calls `configManager.getConfig()` to fetch the current blocklist at runtime.

### What happens if a blocked command is detected in a pipeline or subshell?

The `extractCommands` utility parses the command string to identify tokens within pipelines (`|`) and command substitution (`$()`). Each extracted base command is validated independently against the blocklist. If any token matches a blocked entry, the entire validation returns `false` and execution is prevented.

### Which commands are included in the default Desktop Commander MCP blockedCommands list?

According to the source code in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (lines 115-159), the default blocklist includes system-level destructive commands such as `sudo`, `dd`, `shutdown`, `iptables`, `mkfs`, and `rm` (with specific flags). This list covers common Unix/Linux commands capable of data destruction, privilege escalation, or system shutdown.

### Can users completely disable the blockedCommands security feature?

While users can modify or empty the `blockedCommands` array through the configuration UI or by editing [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) directly, the validation infrastructure in `CommandManager.validateCommand()` always executes if the tool is invoked through the standard API. The security layer cannot be fully disabled without modifying the source code, ensuring that a baseline protection remains active even with an empty blocklist.