Command Blocklist in DesktopCommanderMCP: Purpose, Configuration, and Security Best Practices

The command blocklist in DesktopCommanderMCP prevents execution of high-risk shell commands like sudo, iptables, and rm by validating parsed command tokens against a configurable array of blocked names before execution.

DesktopCommanderMCP enables remote execution of shell commands on a host device, which creates inherent security risks. The command blocklist serves as a critical safeguard against accidental damage or malicious exploitation. This article explains how the blocklist works, where it's configured, and how to customize it for your security requirements.

How the Command Blocklist Works

The blocklist enforcement happens in two stages within the command manager: parsing and validation.

Command Parsing with extractCommands()

When a raw command string arrives, commandManager.extractCommands() in dist/command-manager.js performs several normalizations:

  • Resolves absolute paths to command names
  • Expands command substitutions ($() and backticks)
  • Strips variable tokens ($VAR)

This parsing ensures that attempts to bypass the blocklist using obfuscation techniques are caught before validation.

Validation with validateCommand()

The parsed command tokens are then checked against the blocklist:

// dist/command-manager.js (simplified structure)
export const commandManager = {
  extractCommands(raw) {
    // Normalizes paths, expands substitutions, strips variables
    return parsedTokens; // e.g., ['sudo', 'ls']
  },

  async validateCommand(raw) {
    const cmds = this.extractCommands(raw);
    const blocklist = this.config.commandBlocklist;
    for (const cmd of cmds) {
      if (blocklist.includes(cmd)) {
        throw new Error(`Command "${cmd}" is blocked`);
      }
    }
    return true;
  }
};

The test suite in test/test-blocklist-bypass.js verifies that these normalizations correctly prevent bypass attempts through absolute paths, command substitutions, and backticks.

Configuring the Command Blocklist

The blocklist is defined as a JSON array in the DesktopCommanderMCP configuration file.

Configuration File Location

  • Global config: config.json or .desktopcommanderrc in the application directory
  • Project-specific config: .desktopcommanderrc in the project root (takes precedence)

Blocklist Format

{
  "commandBlocklist": ["sudo", "iptables", "rm", "dd", "chmod"]
}

Modifying the Blocklist

  • Add a command: Append the command name to the array
  • Remove a command: Delete the entry from the array
  • Project override: Define commandBlocklist in a local config file; this merges with or overrides the global list

Runtime Behavior

  • The blocklist loads when the command manager initializes
  • Configuration changes require a restart of DesktopCommanderMCP or a configuration reload via the UI
  • Only exact command names are blocked; the parsing stage ensures aliases and wrappers invoking blocked commands are still caught

Testing Blocklist Enforcement

The repository includes comprehensive tests demonstrating expected behavior:

// test/test-blocked-commands.js
import { commandManager } from '../dist/command-manager.js';

// Blocked commands are rejected
await assert.rejects(
  commandManager.validateCommand('sudo reboot now'),
  /blocked/
);

// Allowed commands pass through
await assert.doesNotReject(
  commandManager.validateCommand('ls -la')
);

The test/test-blocklist-bypass.js file specifically validates that normalization prevents evasion attempts:

  • /usr/bin/sudo reboot → parsed as sudo → blocked
  • $(which sudo) reboot → parsed as sudo → blocked
  • `which sudo` reboot → parsed as sudo → blocked

Common Commands to Block

Command Category Examples Risk
Privilege escalation sudo, su Unauthorized root access
Network manipulation iptables, ufw Firewall bypass or lockout
Data destruction rm, dd, mkfs Irreversible data loss
Permission changes chmod, chown Security policy violations
System control shutdown, reboot Denial of service

Summary

  • The command blocklist in DesktopCommanderMCP prevents execution of dangerous shell commands by validating normalized tokens against a configurable array
  • Configuration occurs in config.json or .desktopcommanderrc via the commandBlocklist array
  • Parsing normalization in extractCommands() prevents bypass attempts through paths, substitutions, or variables
  • Changes require restart to take effect, and project-specific configs can override global settings
  • Test suites in test/test-blocked-commands.js and test/test-blocklist-bypass.js verify enforcement behavior

Frequently Asked Questions

Where is the command blocklist defined in DesktopCommanderMCP?

The blocklist is defined in the commandBlocklist array within the configuration file—typically config.json or .desktopcommanderrc at the application or project root. The array contains command names as strings that should be prohibited from execution.

How does DesktopCommanderMCP prevent blocklist bypass attempts?

The commandManager.extractCommands() function normalizes command strings before validation by resolving absolute paths, expanding command substitutions ($() and backticks), and stripping variable references. This ensures that /usr/bin/sudo, $(which sudo), and similar obfuscations are all identified as the blocked command sudo.

Can I set different blocklists for different projects?

Yes. Create a .desktopcommanderrc file in a project directory with a commandBlocklist entry. DesktopCommanderMCP merges project-specific configurations with global settings, giving precedence to local definitions when conflicts occur.

Do blocklist changes take effect immediately?

No. The blocklist loads during command manager initialization. After modifying the configuration file, you must restart DesktopCommanderMCP or trigger a configuration reload through the UI for changes to become active.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →