# How Shell Selection Works in Desktop Commander MCP: defaultShell Configuration Guide

> Learn how Desktop Commander MCP selects your default shell, including automatic detection and how to configure defaultShell for custom shell usage.

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

---

**Desktop Commander MCP determines which shell to use by first detecting a platform-specific default in [`src/utils/system-info.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/system-info.ts) (PowerShell for Windows, Zsh for macOS, Bash for Linux), then allowing users to override this value via the `defaultShell` configuration field defined in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) and applied at runtime in [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) and [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts).**

The Desktop Commander MCP server provides cross-platform command execution through the Model Context Protocol (MCP), requiring robust shell selection to handle Windows, macOS, and Linux environments gracefully. Understanding how `defaultShell` is configured and resolved ensures your commands execute in the correct interpreter, whether you rely on system defaults or require a specific shell like PowerShell Core or a custom Bash installation.

## Platform-Based Shell Detection in system-info.ts

When the application initializes, it detects the operating system and sets an appropriate default shell before any user configuration is loaded.

### How the Operating System Determines the Default

In [`src/utils/system-info.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/system-info.ts), the application gathers OS information and assigns platform-specific defaults:

- **Windows**: `powershell.exe`
- **macOS**: `zsh`
- **Linux and Unix-like systems**: `bash`

This detected value is stored in `SystemInfo.defaultShell` and surfaced in the system guidance string displayed to users. If no custom configuration exists, this platform-derived value serves as the fallback for all command executions.

```typescript
import { getSystemInfo } from './utils/system-info';

const sysInfo = await getSystemInfo();
console.log('Platform default shell:', sysInfo.defaultShell); 
// Outputs: "powershell.exe" on Windows, "zsh" on macOS, "bash" on Linux

```

## Configuring defaultShell in Desktop Commander

Users can permanently override the platform default by setting the `defaultShell` field in the application configuration.

### The Configuration Schema

The configurable field is declared in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts), allowing the application to recognize and validate user-specified shell paths. When set, this value takes precedence over the system detection logic.

### UI Selection in the Settings Panel

The configuration 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 562-566) provides a dropdown selection of common shells combined with a custom text input:

```typescript
// From config-editor/src/app.ts - UI component rendering
<select class="setting-inline-select" data-action="shell-select">
  <option value="powershell.exe">powershell.exe</option>
  <option value="pwsh.exe">PowerShell Core</option>
  <option value="cmd.exe">cmd.exe</option>
  <option value="bash">bash</option>
  <option value="zsh">zsh</option>
</select>
<input class="setting-shell-custom" 
       type="text" 
       placeholder="Custom shell path (e.g., /usr/local/bin/fish)" />

```

When a user selects a value or enters a custom path, the application writes it to the configuration store via [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts).

## Applying Shell Selection at Runtime

When executing commands, Desktop Commander MCP resolves the final shell by checking for user configuration first, then falling back to the platform default.

### Terminal Manager Implementation

In [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) (line 183), the terminal session initialization uses a nullish coalescing pattern to select the appropriate shell:

```typescript
import { config } from './config-manager';
import { getSystemInfo } from './utils/system-info';

// Runtime shell resolution
const sysInfo = await getSystemInfo();
const shellToUse = config.defaultShell || sysInfo.defaultShell;

// Used to spawn the terminal process
const terminal = spawn(shellToUse, [], { /* options */ });

```

This ensures that a user-configured `defaultShell` in `config/defaultShell` always overrides the automatic OS detection.

### Process Tools Integration

The improved process tools in [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) (lines 157-158) implement the same resolution logic when spawning non-interactive command processes:

```typescript
import { spawn } from 'child_process';
import { config } from '../config-manager.js';
import { getSystemInfo } from '../utils/system-info.js';

async function executeCommand(command: string) {
  const systemInfo = await getSystemInfo();
  
  // Consistent with terminal-manager.ts logic
  const shell = config.defaultShell ?? systemInfo.defaultShell;
  
  const child = spawn(shell, ['-c', command], { 
    stdio: ['pipe', 'pipe', 'pipe'] 
  });
  
  return child;
}

```

This dual implementation ensures consistency whether the user is opening an interactive terminal session or running background commands through the MCP tools.

## Summary

- **Platform Detection**: [`src/utils/system-info.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/system-info.ts) automatically selects `powershell.exe` (Windows), `zsh` (macOS), or `bash` (Linux) on startup.
- **User Override**: The `defaultShell` field in [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) allows permanent customization through the settings UI or configuration file.
- **Runtime Resolution**: Both [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) (line 183) and [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) (lines 157-158) use `config.defaultShell || systemInfo.defaultShell` to determine the executable.
- **UI Support**: The configuration editor in [`src/ui/config-editor/src/app.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/config-editor/src/app.ts) provides dropdown presets and custom path inputs for shell selection.

## Frequently Asked Questions

### What is the default shell on Windows in Desktop Commander?

On Windows systems, Desktop Commander MCP defaults to `powershell.exe` as detected in [`src/utils/system-info.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/system-info.ts). This provides modern PowerShell capabilities without requiring additional configuration, though users can override this with `cmd.exe`, `pwsh.exe` (PowerShell Core), or any other shell executable through the `defaultShell` setting.

### How do I set a custom shell path in Desktop Commander MCP?

You can specify a custom shell by setting the `defaultShell` configuration value to the absolute path of your shell executable, such as `/opt/homebrew/bin/fish` or `C:\Program Files\Git\bin\bash.exe`. This can be done through the Settings UI in the configuration editor (using the custom text input field) or by directly editing the configuration file stored by [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts).

### Where does Desktop Commander store the defaultShell configuration?

The `defaultShell` value is defined in the configuration schema at [`src/config-field-definitions.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-field-definitions.ts) and persisted through [`src/config-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts). The configuration is typically stored in the application's settings directory and loaded at runtime, making it available to both [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) and [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) when resolving shell paths.

### Does Desktop Commander fall back to system defaults if defaultShell is not set?

Yes. If the `defaultShell` configuration field is null or undefined, the application falls back to the platform-specific default detected in [`src/utils/system-info.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/system-info.ts). This fallback is implemented via the logical OR operator (`||`) in [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) (line 183) and the nullish coalescing operator (`??`) in [`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts) (lines 157-158), ensuring a valid shell is always available even without explicit user configuration.