# Desktop Commander MCP Allowed Directories vs Terminal Commands: Understanding Access Control Differences

> Understand Desktop Commander MCP allowedDirectories vs terminal commands. Learn how file operation and command access controls differ for enhanced security.

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

---

**`allowedDirectories` in Desktop Commander MCP restricts filesystem operations directly, while terminal commands are controlled separately via `blockedCommands` with filesystem paths validated later by the same allowed directories check.**

Desktop Commander MCP implements a two-layer security model that distinguishes between **where files can be accessed** and **what commands can be executed**. This design gives administrators granular control over filesystem boundaries without limiting terminal flexibility. The primary keyword—**allowed directories restrictions for file operations vs terminal commands**—reflects this architectural separation.

## How Allowed Directories Restrict Filesystem Operations

All filesystem operations in Desktop Commander MCP enforce `allowedDirectories` at the point of access. This includes reading, writing, moving, copying, and listing files through the `filesystem` tool.

### The Enforcement Logic in filesystem.ts

In [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) (lines 172-210), every filesystem path undergoes validation before any operation proceeds:

```typescript
// src/tools/filesystem.ts
const allowedDirectories = await getAllowedDirs();
if (allowedDirectories.includes('/') || allowedDirectories.length === 0) {
  // unrestricted – allow any path
}
const isAllowed = allowedDirectories.some(dir => {
  const normDir = normalizePath(dir);
  // exact match
  if (normPath === normDir) return true;
  // sub‑directory match
  return normPath.startsWith(normDir + '/');
});
if (!isAllowed) {
  throw new Error(`Path not allowed: ${requestedPath}`);
}

```

**Key behaviors:**
- If `allowedDirectories` contains "/" or is empty, **all paths are permitted**
- Otherwise, the requested path must exactly match or be a subdirectory of an allowed directory
- The check uses normalized paths with trailing-slash-aware matching to prevent traversal attacks

This validation runs for every file-touching operation regardless of whether the request originates from an API call, UI interaction, or tool invocation.

## How Terminal Commands Bypass Allowed Directories (Initially)

Terminal commands follow a completely different validation path. In [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) (lines 29-52), commands are checked against `blockedCommands` only—**`allowedDirectories` is not consulted**:

```typescript
// src/command-manager.ts
const blocked = config.blockedCommands || [];
const baseCmd = this.getBaseCommand(command);
if (blocked.includes(baseCmd)) {
  return false; // command blocked
}
return true; // command allowed (file paths will be checked later)

```

This means:
- A command like `cp /etc/passwd /tmp/backup` is **allowed to execute** if `cp` is not in `blockedCommands`
- The **file paths within the command** (`/etc/passwd`, `/tmp/backup`) are only validated when the filesystem layer processes them

### The Critical Interaction Layer

When a terminal command actually performs file operations, those operations flow through the same [`filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/filesystem.ts) validation shown above. A command can start but will fail if it attempts to access forbidden paths. This creates two possible outcomes:

| Scenario | Result |
|----------|--------|
| Command has no file arguments (e.g., `ls`, `date`) | Executes freely if not blocked |
| Command has file arguments in allowed directories | Executes and succeeds |
| Command has file arguments outside allowed directories | Command starts but filesystem operations throw "Path not allowed" errors |

## Configuration Structure

Both restrictions are defined in the same configuration but operate independently:

```json
{
  "allowedDirectories": ["/home/user/documents", "/var/www"],
  "blockedCommands": ["rm", "shutdown", "reboot"]
}

```

**`allowedDirectories`** — array of absolute paths defining filesystem boundaries
**`blockedCommands`** — array of command names that cannot be executed regardless of directory context

## File-Level Responsibilities

| File | Security Function |
|------|-------------------|
| [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) | Defines configuration schema for both fields |
| [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts) | Enforces `allowedDirectories` on every file operation |
| [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) | Validates terminal commands against `blockedCommands` only |
| [`src/server.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/server.ts) | Documents configuration fields in API descriptions |

## Practical Security Implications

This separation enables useful security patterns that would be impossible with a unified model:

- **Permit terminal exploration while restricting file damage**: Allow `ls /` to browse the filesystem tree, but block writes outside approved directories
- **Block dangerous commands globally**: Prevent `rm`, `mkfs`, or `dd` from executing even within allowed directories
- **Allow safe commands anywhere**: Permit `grep`, `awk`, or `cat` to process files without directory restrictions, trusting that write operations will still be gated

The `blockedCommands` check is **pre-execution**—it prevents process spawn. The `allowedDirectories` check is **per-operation**—it gates actual file descriptor access.

## Summary

- **`allowedDirectories`** restricts **filesystem operations** at the point of path access in [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts)
- **`blockedCommands`** restricts **terminal command execution** during parsing in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts)
- Terminal commands are validated against `blockedCommands`, not `allowedDirectories`, but any file paths they use are later checked by the filesystem layer
- Empty or root-only `allowedDirectories` grants full filesystem access; empty `blockedCommands` allows all command names

## Frequently Asked Questions

### Does allowedDirectories prevent terminal commands from running in restricted directories?

No. `allowedDirectories` does not block command execution based on working directory. A terminal command can **start** in any directory, but any **file operations** it performs will be rejected if they target paths outside the allowed list.

### What happens if a terminal command tries to access a blocked file path?

The command process launches, but the specific filesystem operation fails with a "Path not allowed" error thrown from [`src/tools/filesystem.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/filesystem.ts). The command may continue executing if it handles errors, or may terminate depending on its implementation.

### Can blockedCommands include full command paths like /usr/bin/rm?

The `getBaseCommand()` method in [`src/command-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/command-manager.ts) extracts the base command name from the full command string, so `/usr/bin/rm` would be evaluated as `rm`. The blocked list should contain bare command names without paths.

### Why are these restrictions separated instead of unified?

Separating **command execution control** from **filesystem access control** allows flexible security policies. Administrators can permit read-only exploration of the filesystem tree while strictly limiting where changes can be written, or block destructive commands globally without restricting directory navigation.