# How to Customize the Command Blocklist in Desktop Commander MCP to Prevent Accidental Execution

> Customize the command blocklist in Desktop Commander MCP to block dangerous commands. Prevent accidental execution with this guide. Learn how to configure your blockedCommands array.

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

---

**Desktop Commander MCP prevents accidental execution of dangerous commands by validating every instruction against a user-configurable `blockedCommands` array that analyzes command basenames case-insensitively, including those hidden inside Bash substitutions and subshells.**

Desktop Commander MCP, an open-source tool from the `wonderwhy-er/DesktopCommanderMCP` repository, implements a robust safety layer through its **command blocklist** feature. This system intercepts potentially destructive operations by analyzing command strings before execution. Understanding how to customize this blocklist allows you to tailor security policies to your specific workflow while maintaining protection against shell injection attacks.

## Understanding the Blocklist Architecture

The blocklist system operates through three coordinated components defined in the source code.

### Configuration Schema Definition

The `blockedCommands` field is formally declared in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) within the `CONFIG_FIELD_DEFINITIONS` structure. This configuration field accepts an array of command names (strings) that the system will refuse to execute. At runtime, the `configManager` retrieves these values to enforce security policies across all command operations.

### Command Extraction and Parsing

Before validation occurs, `CommandManager.extractCommands` (located in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts)) parses the complete command string to identify every executable component. This function handles complex Bash syntax including command separators, subshells, process substitutions (`$()`), and backtick substitutions (`` ` ` ``). It returns a deduplicated list of base commands—extracting only the basename from full paths (converting `/usr/bin/sudo` to `sudo`).

### Validation Logic

The `CommandManager.validateCommand` method (lines 29-53 in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts)) orchestrates the security check. It retrieves the current blocklist from the configuration, invokes `extractCommands` to identify all commands within the input string, and rejects the operation if any extracted command appears in the blocklist.

## How the Blocklist Prevents Bypass Attacks

Traditional blocklists often fail when users embed dangerous commands inside shell substitutions. Desktop Commander MCP mitigates this by recursively analyzing command strings.

When you input a command like `echo $(rm -rf /)`, the `extractCommands` function identifies both `echo` and `rm` as separate base commands. If `rm` resides in your blocklist, the validation fails regardless of how deeply nested the command appears. This protection extends to backtick substitutions and chained commands separated by semicolons or logical operators.

The matching algorithm operates **case-insensitively** and compares only command basenames, ensuring that `/bin/RM` and `rm` receive identical treatment.

## Methods to Customize the Blocklist

You can modify the `blockedCommands` array through three primary methods depending on your integration needs.

### Direct Configuration File Editing

The simplest approach involves editing the JSON configuration file directly. The configuration typically resides at `~/.desktop-commander/config.json` (location may vary by installation).

```json
{
  "blockedCommands": [
    "rm",
    "dd",
    "shutdown",
    "reboot",
    "mkfs"
  ],
  "allowedDirectories": [],
  "defaultShell": "/bin/bash",
  "telemetryEnabled": true,
  "fileReadLineLimit": 1000,
  "fileWriteLineLimit": 500
}

```

Add or remove command names from the `blockedCommands` array, then restart the application to apply changes.

### Programmatic Configuration Updates

For dynamic environments, use the `configManager` API to update the blocklist without manual file editing:

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

async function addToBlocklist(cmd: string) {
  const cfg = await configManager.getConfig();
  cfg.blockedCommands = Array.from(
    new Set([...(cfg.blockedCommands ?? []), cmd.toLowerCase()])
  );
  await configManager.saveConfig(cfg);
}

// Block destructive commands
await addToBlocklist('rm');
await addToBlocklist('dd');

```

This approach ensures case consistency by converting inputs to lowercase before storage.

### UI-Based Configuration

Desktop Commander MCP also exposes the **Blocked Commands** setting through its user interface. Access this panel to add command names through form fields without touching raw JSON or code.

## Pre-Execution Validation

You can manually verify whether a command passes blocklist restrictions before attempting execution by using the `validateCommand` method directly:

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

async function canRun(command: string): Promise<boolean> {
  return await commandManager.validateCommand(command);
}

// Validation examples
console.log(await canRun('ls -la'));           // true (not blocked)
console.log(await canRun('rm -rf /tmp/*'));    // false if "rm" is blocked
console.log(await canRun('echo $(dd if=/dev/zero)')); // false if "dd" is blocked

```

This technique proves useful when building custom workflows that require explicit security checks before shell invocation.

## Summary

- The blocklist is defined in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) and stored in the `blockedCommands` configuration field
- `CommandManager.extractCommands` parses complex Bash syntax including `$()` and backticks to identify all executable components
- `CommandManager.validateCommand` (lines 29-53 of [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts)) performs case-insensitive basename matching against the blocklist
- The system prevents bypass attacks by analyzing commands inside substitutions and subshells
- Customize the blocklist via JSON configuration files, programmatic API calls, or the application UI

## Frequently Asked Questions

### What file stores the blocklist configuration in Desktop Commander MCP?

The blocklist is stored in the application's JSON configuration file, typically located at `~/.desktop-commander/config.json`. This file contains the `blockedCommands` array alongside other settings like `allowedDirectories` and `defaultShell`. You can edit this file directly or modify it through the `configManager` API.

### How does Desktop Commander MCP handle commands inside subshells or substitutions?

The `extractCommands` method in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) recursively parses command strings to detect commands within process substitutions (`$()`), backticks (`` ` ` ``), and subshells. It extracts the base command names from these nested structures and validates them against the blocklist, preventing attempts to bypass restrictions using shell tricks.

### Can I block specific command arguments or only command names?

The blocklist matches only command **basenames** (e.g., `rm` rather than `rm -rf`). You cannot block specific arguments or flags directly through the `blockedCommands` array. To restrict particular usage patterns, you would need to implement additional validation logic outside the standard blocklist mechanism.

### Is the blocklist case-sensitive?

No. Desktop Commander MCP treats the blocklist as case-insensitive. Whether you specify `RM`, `rm`, or `/usr/bin/RM`, the system normalizes all commands to lowercase before comparison. When adding commands programmatically, the code example demonstrates converting inputs to lowercase to maintain consistency.