# MCP Security Boundary for Allowed Directories and Terminal Commands in Desktop Commander MCP

> Learn about the MCP security boundary for directories and terminal commands in Desktop Commander MCP. Understand how allowedDirectories and blockedCommands protect your system and prevent unauthorized access.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: security-best-practices
- Published: 2026-07-12

---

**The Desktop Commander MCP server implements a dual-layer security boundary using `allowedDirectories` and `blockedCommands` whitelists—empty `allowedDirectories` grants full filesystem access, while `blockedCommands` prevents specific shell commands from executing.**

Desktop Commander MCP is a Model Context Protocol server that exposes filesystem and terminal operations to AI agents. To prevent unauthorized access, the codebase implements a configurable security boundary that restricts which directories can be accessed and which terminal commands can be executed. This article examines the implementation across [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts), [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts), [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts), and [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) to show how whitelist validation works at runtime.

## How the Security Boundary Works in Desktop Commander MCP

The security model relies on two independent whitelists defined in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts). The `allowedDirectories` array controls filesystem access, while `blockedCommands` filters shell execution. Both are stored in a centralized configuration managed by [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) and enforced at the tool level.

| Whitelist | Purpose | Default Behavior |
|-----------|---------|----------------|
| **`allowedDirectories`** | Paths that MCP may read, write, or manipulate | Empty array grants full filesystem access |
| **`blockedCommands`** | Shell commands that MCP will refuse to execute | Empty array means no commands are blocked |

## Configuring Allowed Directories in MCP

### Configuration Schema in config-field-definitions.ts

The whitelist structure is defined in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) lines 16-19. The `allowedDirectories` field is typed as an array with a descriptive label warning users about the empty array behavior.

```ts
// src/config-field-definitions.ts
export const CONFIG_FIELD_DEFINITIONS = {
  allowedDirectories: {
    label: 'Allowed Folders',
    description: 'These are the folders Desktop Commander is allowed to read and edit. … If this list is empty, Desktop Commander can access your entire filesystem.',
    valueType: 'array',
  },
  // ...
} as const;

```

### Default Configuration and Runtime Storage

In [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) line 172, the default configuration initializes `allowedDirectories` as an empty array. This empty state serves as the fallback that grants unrestricted access.

```ts
// src/config-manager.ts
export interface Config {
  allowedDirectories?: string[];
  // ...
}

export const defaultConfig: Config = {
  allowedDirectories: [],   // empty → full access
  // ...
};

```

### Loading and Caching the Whitelist

When the filesystem tools initialize in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) lines 110-119, the configuration is read and cached. If the array is missing or invalid, it falls back to an empty array.

```ts
// src/tools/filesystem.ts (excerpt)
let allowedDirectories: string[];
if (config.allowedDirectories && Array.isArray(config.allowedDirectories)) {
  allowedDirectories = config.allowedDirectories;
} else {
  allowedDirectories = [];               // fallback → unrestricted
}
await configManager.setValue('allowedDirectories', allowedDirectories);

```

## Path Validation with isPathAllowed in filesystem.ts

### The isPathAllowed Implementation

Every filesystem operation calls `isPathAllowed` (lines 172-209 in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts)) before executing. This function normalizes paths and checks against the whitelist.

```ts
// src/tools/filesystem.ts
export async function isPathAllowed(requestedPath: string): Promise<boolean> {
  const allowedDirs = await getAllowedDirs();

  // Root allowed → everything allowed
  if (allowedDirs.includes('/') || allowedDirs.length === 0) return true;

  // Normalise & check each whitelist entry
  return allowedDirs.some(dir => {
    const normalized = normalizePath(dir);
    if (requestedPath === normalized) return true;                     // exact match
    if (requestedPath.startsWith(normalized + '/')) return true;      // sub‑folder
    // Windows drive root handling …
    return false;
  });
}

```

### Error Handling for Unauthorized Paths

When validation fails at lines 298-303, the user receives a descriptive error:

```

Path not allowed: /secret/file.txt. Must be within one of these directories: /home/user/project, /tmp

```

This error bubbles up through all filesystem endpoints including `readFile`, `writeFile`, and `copyFile`.

## Blocking Terminal Commands with blockedCommands

### Command Validation in improved-process-tools.ts

Terminal security is enforced in [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) at line 123. Before spawning any process, the requested command is checked against the `blockedCommands` array.

```ts
// src/tools/improved-process-tools.ts
if (config.blockedCommands?.includes(parsed.data.command)) {
  return {
    type: "error",
    content: [{ type: "text", text: `Error: Command not allowed: ${parsed.data.command}` }],
  };
}

```

### Default Behavior and Security Implications

By default, `blockedCommands` is empty, meaning no commands are restricted unless explicitly added. This provides a defense-in-depth layer: even if an AI prompt requests a dangerous command like `rm -rf /`, the execution will be blocked if that command appears in the whitelist.

## API Exposure and UI Integration

### Server-Side Documentation in server.ts

The HTTP API in [`src/server.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/server.ts) (lines 335-340) explicitly documents the security boundary in its OpenAPI description, warning that an empty `allowedDirectories` array removes all restrictions.

```ts
// src/server.ts (excerpt)
// - allowedDirectories (array of paths)
// IMPORTANT: Setting allowedDirectories to an empty array ([]) allows full access

```

### Configuration UI in app.ts

The web interface in [`src/ui/config-editor/src/app.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/config-editor/src/app.ts) (lines 310-327) displays the current count of allowed folders and blocked commands, enabling users to modify the security boundary without editing configuration files directly.

## Practical Implementation Examples

### Querying Current Whitelist Settings

```ts
import { get_config } from "./config-manager";

async function showWhitelists() {
  const cfg = await get_config();
  console.log("Allowed directories:", cfg.allowedDirectories ?? []);
  console.log("Blocked commands:", cfg.blockedCommands ?? []);
}
showWhitelists();

```

### Reading Files with Directory Validation

```ts
import { readFile } from "./tools/filesystem";

async function safeRead(path: string) {
  try {
    const content = await readFile(path);
    console.log(content);
  } catch (e) {
    console.error("Access denied:", e.message);
  }
}
safeRead("/home/user/project/notes.md");   // succeeds if folder is whitelisted
safeRead("/etc/passwd");                  // throws if not whitelisted

```

### Attempting Blocked Command Execution

```ts
import { runProcess } from "./tools/improved-process-tools";

async function tryRun(cmd: string) {
  const result = await runProcess({ command: cmd, args: [] });
  console.log(result);
}
tryRun("rm -rf /");   // returns error if "rm" is in blockedCommands

```

### Programmatically Adding Allowed Directories

```ts
import { configManager } from "./config-manager";

async function addAllowedDir(dir: string) {
  const cfg = await configManager.getConfig();
  const dirs = cfg.allowedDirectories ?? [];
  dirs.push(dir);
  await configManager.setValue("allowedDirectories", dirs);
}
addAllowedDir("/home/user/documents");

```

## Summary

- **`allowedDirectories`** in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) and [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) defines which filesystem paths are accessible—empty array means full access.
- **`isPathAllowed`** in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) (lines 172-209) validates every path before filesystem operations, with clear error messages at lines 298-303.
- **`blockedCommands`** in [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) (line 123) prevents specific shell commands from executing, providing a secondary security layer.
- The default configuration grants unrestricted access, requiring explicit user configuration to enable sandboxing.
- All endpoints in [`src/server.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/server.ts) and the UI in [`src/ui/config-editor/src/app.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/config-editor/src/app.ts) expose these settings for runtime adjustment.

## Frequently Asked Questions

### What happens if allowedDirectories is empty in Desktop Commander MCP?

When `allowedDirectories` is an empty array, Desktop Commander MCP grants **full filesystem access**. This default is set in [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) line 172 and enforced by `isPathAllowed` in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts), which returns `true` for any path when the whitelist is empty.

### How does Desktop Commander MCP block dangerous terminal commands?

The `blockedCommands` array in the configuration defines which shell commands are prohibited. In [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) line 123, the code checks if the requested command exists in this array before spawning the process, returning an error if matched.

### Can subdirectories access parent directories if only the parent is whitelisted?

No. The `isPathAllowed` function in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) uses `startsWith(normalized + '/')` to validate that requested paths are either exact matches or children of whitelisted directories. Accessing sibling or parent directories of a whitelisted folder is denied.

### Where is the security boundary configured in the Desktop Commander MCP codebase?

The security boundary is configured across multiple files: [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) defines the schema, [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) stores the values, [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) enforces directory restrictions, and [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) handles command blocking. The UI in [`src/ui/config-editor/src/app.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/config-editor/src/app.ts) provides a user-friendly interface for modifications.