# How DesktopCommander Extracts Commands from `$()` and Backtick Substitutions

> DesktopCommander parses $() and backtick substitutions to extract nested commands for secure validation before execution. Learn how this command extraction works.

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

---

**DesktopCommander recursively parses command substitution syntax—both `$()` and backticks—to extract nested commands for security validation before execution.**

Command extraction in shell environments presents a significant security challenge: malicious inputs often hide prohibited commands inside substitution expressions. The `wonderwhy-er/DesktopCommanderMCP` project solves this through a character-by-character parser in the `CommandManager` class that treats command substitutions as separate parsing contexts, recursively extracting any commands they contain.

## How `extractCommands` Processes `$()` Substitution

The `$()` command substitution syntax requires careful parenthesis balancing. In [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts), the parser detects this pattern and tracks nesting depth to find the correct closing delimiter.

```typescript
// Lines 58-80 in src/command-manager.ts
if (char === '$' && i + 1 < commandString.length && commandString[i + 1] === '(') {
    const startIndex = i;
    let openParens = 1;
    let j = i + 2;                     // skip past `$(`
    while (j < commandString.length && openParens > 0) {
        if (commandString[j] === '(') openParens++;
        if (commandString[j] === ')') openParens--;
        j++;
    }
    if (j <= commandString.length && openParens === 0) {
        const subContent = commandString.substring(i + 2, j - 1);
        const subCommands = this.extractCommands(subContent);   // ← recursive call
        commands.push(...subCommands);
        i = j - 1;
        if (!inQuote) {
            continue;
        } else {
            currentCmd += commandString.substring(startIndex, j);
            continue;
        }
    }
}

```

The algorithm follows three critical steps:

- **Detection**: Identifies the `$(` sequence to trigger substitution parsing
- **Balancing**: Increments `openParens` for every `(` and decrements for every `)` until reaching zero
- **Recursion**: Passes the extracted content back through `extractCommands` to discover any nested commands

When `$()` appears inside a quoted string, the parser preserves the original characters in `currentCmd` while still extracting the nested commands for blocklist validation.

## How `extractCommands` Processes Backtick Substitution

Backtick substitution uses simpler delimiters—matching pairs of `` ` `` characters—making the parsing logic more straightforward but equally robust.

```typescript
// Lines 82-100 in src/command-manager.ts
if (char === '`') {
    const startIndex = i;
    let j = i + 1;
    while (j < commandString.length && commandString[j] !== '`') {
        j++;
    }
    if (j < commandString.length) {
        const subContent = commandString.substring(i + 1, j);
        const subCommands = this.extractCommands(subContent);   // ← recursive call
        commands.push(...subCommands);
        i = j;
        if (!inQuote) {
            continue;
        } else {
            currentCmd += commandString.substring(startIndex, j + 1);
            continue;
        }
    }
}

```

Key characteristics of backtick handling:

- **Linear scan**: Advances until the next backtick without nesting considerations
- **Same recursive treatment**: Submits enclosed content to `extractCommands` for nested command discovery
- **Quote awareness**: Maintains command string integrity when backticks appear within quoted contexts

Both substitution types ensure that **commands hidden inside shell expansions are treated as independent commands** subject to `validateCommand` checks against the configured blocklist.

## Practical Command Extraction Examples

### Basic `$()` Substitution

```typescript
const raw = "echo $(rm -rf /tmp) && ls";
const cmds = commandManager.extractCommands(raw);
// cmds => ["echo", "rm", "ls"]

```

The parser extracts `rm` from inside the `$()` even though it appears as an argument to `echo`.

### Basic Backtick Substitution

```typescript
const raw2 = "git commit -m `date +%F`";
const cmds2 = commandManager.extractCommands(raw2);
// cmds2 => ["git", "date"]

```

The `date` command inside backticks is identified separately from the outer `git` command.

### Deeply Nested Substitutions

```typescript
const raw3 = "printf \"$(echo $(whoami))\"";
const cmds3 = commandManager.extractCommands(raw3);
// cmds3 => ["printf", "echo", "whoami"]

```

The recursive design handles arbitrary nesting depth, extracting `whoami` from the inner `$()`, `echo` from the outer `$()`, and `printf` from the top level.

## Key Source Files

- **[`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts)** — Core parsing logic with `$()` and backtick extraction (lines 58-100)
- **[`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts)** — Blocked command definitions used by `validateCommand`
- **[`src/utils/capture.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts)** — Error reporting when extraction encounters malformed input

## Summary

- **Character-by-character parsing**: `extractCommands` walks input strings with full awareness of quoting, escaping, and substitution boundaries
- **Parenthesis balancing**: `$()` handling counts nested parentheses to find correct delimiters
- **Linear backtick matching**: `` ` `` syntax uses simple forward scanning to locate closing delimiters
- **Recursive extraction**: Both substitution types submit their contents back to `extractCommands`, enabling unlimited nesting depth
- **Security integration**: Extracted commands feed directly into blocklist validation, preventing circumvention through shell expansion

## Frequently Asked Questions

### Does the parser handle arbitrarily nested `$()` expressions?

Yes. The `openParens` counter increments for every `(` encountered and decrements for every `)`, ensuring proper matching regardless of nesting depth. Each completed substitution recursively calls `extractCommands` on its contents.

### What happens to backtick content if no closing backtick exists?

The parser verifies `j < commandString.length` before processing. If no closing backtick is found, the backtick character is treated as literal text and appended to the current command rather than triggering substitution extraction.

### Are commands inside substitutions validated against the blocklist?

Absolutely. The entire purpose of recursive extraction is security validation. Every command discovered—including those nested inside `$()` or backticks—passes through `validateCommand` against the blocklist defined in [`config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config-manager.ts).

### Why preserve substitution text when inside quotes?

The `inQuote` check preserves the original substitution syntax in `currentCmd` to maintain command string fidelity for execution, while still extracting the nested commands for security analysis. This dual approach ensures both accurate execution and comprehensive security coverage.