# How to Configure Blocked Commands in Desktop Commander MCP to Prevent Dangerous Shell Execution

> Secure your Desktop Commander MCP by configuring blockedCommands. Learn how to prevent dangerous shell command execution and safeguard your system with this essential guide.

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

---

**Desktop Commander MCP prevents accidental execution of dangerous shell commands through a user-editable `blockedCommands` configuration array that is checked against every submitted command before execution.**

The Desktop Commander MCP server provides a robust safety mechanism that protects users from destructive or malicious shell operations. By maintaining a configurable blocklist of prohibited commands, the system intercepts risky inputs before they reach the operating system. This guide explains how to customize the `blockedCommands` setting in Desktop Commander MCP using both programmatic APIs and the built-in settings interface.

## Where the Blocklist Is Defined and Stored

The blocked commands configuration resides in a JSON file managed by `ConfigManager` in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (line 63). The configuration field itself is formally declared in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) (lines 11-15), which exposes it to the settings UI as the **Blocked Commands** field.

When Desktop Commander MCP initializes, `ConfigManager.init()` loads this file and merges it with default values. Changes are persisted via `saveConfig()` (lines 70-101), ensuring your safety preferences survive restarts.

## How Command Blocking Works at Runtime

The enforcement mechanism lives in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) (lines 231-247). Here's the execution flow:

1. **Command parsing**: `CommandManager.extractCommands()` parses the submitted command string to identify base commands
2. **Blocklist check**: Each extracted command is tested against `config.blockedCommands` using `blockedCommands.includes()`
3. **Rejection or execution**: If any match is found, the command is rejected with a "blocked by configuration" error; otherwise, execution proceeds

This check occurs before any shell subprocess is spawned, providing fail-safe protection.

## Default Blocked Commands in Desktop Commander MCP

The `ConfigManager.getDefaultConfig()` method (lines 25-69) ships with a comprehensive safety blocklist including:

- **Privilege escalation**: `sudo`, `su`
- **Data destruction**: `dd`, `rm`, `mkfs`, `fdisk`
- **System control**: `shutdown`, `reboot`, `poweroff`, `halt`
- **Network security**: `iptables`, `ufw`
- **Process management**: `kill`, `killall`, `pkill`

These defaults represent high-risk operations that could damage data or compromise system stability.

## Method 1: Edit Blocked Commands Programmatically

For automation or integration scenarios, modify the blocklist directly through the `ConfigManager` API:

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

// Initialize the configuration system
await configManager.init();

// Retrieve current blocked commands
const currentBlocklist = configManager.getValue('blockedCommands') as string[];

// Add custom dangerous command (e.g., database wipe utility)
const updatedBlocklist = [...new Set([...currentBlocklist, 'dropdb', 'redis-cli'])];

// Persist to configuration file
await configManager.setValue('blockedCommands', updatedBlocklist);

```

**Key implementation details:**
- `getValue('blockedCommands')` retrieves the string array from merged config (defaults + user overrides)
- `setValue()` triggers `saveConfig()` to write to the JSON file
- The `Set` deduplication prevents redundant entries

## Method 2: Configure Blocked Commands via Settings UI

For manual configuration without code:

1. Open Desktop Commander MCP's **Settings** panel
2. Locate the **Blocked Commands** field (labeled "Blocked Commands" with description referencing "personal safety blocklist")
3. Edit the comma-separated or line-delimited list of commands
4. Click **Save** — the UI writes through the same `ConfigManager` interface

The UI field definition in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) ensures type safety: the input is validated as a string array before persistence.

## Method 3: Direct Configuration File Editing

The underlying storage location depends on your environment. Inspect or modify directly:

```bash

# Default location (verify with your CONFIG_FILE path)

CONFIG_PATH="$HOME/.desktop-commander/config.json"

# View current blocklist

jq '.blockedCommands' "$CONFIG_PATH"

# Add entry with in-place editing

jq '.blockedCommands += ["systemctl"]' "$CONFIG_PATH" > tmp.json && mv tmp.json "$CONFIG_PATH"

```

## Verifying Blocked Command Enforcement

Test that your configuration is active using the `CommandManager` interface:

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

await configManager.init();
await configManager.setValue('blockedCommands', ['rm', 'curl', 'wget']);

// This will be rejected
const result = await commandManager.runCommand('rm -rf /important/data');
console.log(result.blocked);      // → true
console.log(result.blockReason);  // → "blocked by configuration"

// This will proceed (unless also blocked)
const safeResult = await commandManager.runCommand('ls -la /tmp');
console.log(safeResult.blocked);  // → false

```

The `blocked` boolean and `blockReason` string in the result object provide clear feedback for logging or UI presentation.

## Best Practices for Blocked Commands Configuration

- **Start restrictive, then relax**: Begin with the default blocklist and remove entries only when specific workflows require them
- **Block command bases, not arguments**: The parser checks `rm` in `rm -rf /`, not the full string — blocking `rm` catches all variants
- **Version-control your config**: Track [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) changes to audit safety policy evolution
- **Test in isolation**: Verify blocklist changes with non-destructive commands before relying on protection

## Summary

- Desktop Commander MCP's `blockedCommands` array in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) provides configurable shell command protection
- Default dangerous commands are defined in `getDefaultConfig()` (lines 25-69) and enforced in `CommandManager` (lines 231-247)
- Modify the blocklist via `ConfigManager.setValue()`, the Settings UI, or direct JSON editing
- All changes persist through `saveConfig()` and load automatically on server restart
- The `blocked` property in command results confirms when protection has activated

## Frequently Asked Questions

### How do I remove a command from the blocked list if I need it for my workflow?

Edit the configuration through any of the three methods: use `configManager.setValue('blockedCommands', updatedArray)` to filter out the specific command, delete it from the Settings UI textarea, or modify the JSON file directly. Restart Desktop Commander MCP if you edited the file outside the running process.

### Does blocking `sudo` prevent all privilege escalation?

Blocking `sudo` catches the common case, but determined users could bypass with `su`, `doas`, or direct `/bin/su` paths. Extend your blocklist to include all privilege elevation binaries relevant to your system. The default configuration includes both `sudo` and `su` for this reason.

### Where is the configuration file located on disk?

The path is determined by the `CONFIG_FILE` constant in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (line 63), typically resolving to `~/.desktop-commander/config.json`. Verify your specific path by logging `configManager.configPath` after initialization, as it may vary by operating system or environment variables.

### Can I block specific command arguments rather than entire commands?

No — Desktop Commander MCP's protection operates on the base command name extracted by `extractCommands()` in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts). This design choice prevents circumvention through path variations (`/bin/rm` vs `rm`) but means you cannot block `rm -rf /` while allowing `rm /tmp/safe`. Use broader system-level controls for argument-level restrictions.