# How DesktopCommanderMCP Process Detection Identifies Running, Waiting, and Finished Processes

> DesktopCommanderMCP detects process states by analyzing stdout stderr output against predefined patterns. Learn how it identifies running waiting and finished processes.

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

---

**DesktopCommanderMCP detects process states by analyzing stdout/stderr output against predefined patterns of REPL prompts, completion indicators, and error signatures in [`src/utils/process-detection.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/process-detection.ts).**

DesktopCommanderMCP is a Model Context Protocol (MCP) server that enables AI agents to execute terminal commands and interact with REPL environments. The **DesktopCommanderMCP process detection** system determines whether a spawned process is actively running, blocked waiting for input, or has terminated by implementing a pattern-matching state machine that inspects textual output in real-time.

## Core Detection Logic in process-detection.ts

The heart of the detection system resides in **[`src/utils/process-detection.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/process-detection.ts)**, which exports the `analyzeProcessState` function. This function accepts process output and PID, then returns a `ProcessState` object indicating whether the process is running, waiting for input, or finished.

### REPL Prompt Detection

When a process enters an interactive REPL mode, it typically displays specific prompt characters. The module defines **`REPL_PROMPTS`**—a catalogue of common patterns including `>>>`, `>`, `$`, and `#`.

The `analyzeProcessState` function extracts the last line of output and checks for these prompts:

```typescript
// src/utils/process-detection.ts
const allPrompts = Object.values(REPL_PROMPTS).flat();
const detectedPrompt = allPrompts.find(p => lastLine.endsWith(p) || lastLine.includes(p));
if (detectedPrompt) {
  return { isWaitingForInput: true, isFinished: false, isRunning: true, detectedPrompt, lastOutput: output };
}

```

If a prompt is detected, the process is marked with **`isWaitingForInput: true`**, signaling that the process is blocked awaiting user interaction.

### Completion Indicator Recognition

To identify normal process termination, the system uses **`COMPLETION_INDICATORS`**—strings and regexes that typically appear when commands finish, such as `"Process finished"` or `"Exit code:"`.

The detection logic scans the entire output buffer for these patterns:

```typescript
// src/utils/process-detection.ts
const hasCompletionIndicator = COMPLETION_INDICATORS.some(p => p.test(output));
if (hasCompletionIndicator) {
  return { isWaitingForInput: false, isFinished: true, isRunning: false, lastOutput: output };
}

```

When matched, the function returns **`isFinished: true`**, indicating the process lifecycle has ended successfully.

### Error-Driven Termination Detection

Many REPLs and scripts terminate by printing error tracebacks rather than clean exit codes. The module defines **`ERROR_COMPLETION_PATTERNS`** containing regexes for `"Error:"`, `"Exception:"`, and `"Traceback"`.

If error patterns match the recent output and no REPL prompt follows, the process is marked as finished:

```typescript
// src/utils/process-detection.ts
const hasErrorCompletion = ERROR_COMPLETION_PATTERNS.some(p => p.test(lastFewLines));
if (hasErrorCompletion) {
  return detectedPrompt
    ? { /* remains waiting */ }
    : { isWaitingForInput: false, isFinished: true, isRunning: false, lastOutput: output };
}

```

This ensures crashed or errored processes are correctly identified as terminated rather than hanging indefinitely.

## Runtime Integration and State Management

The detection logic integrates with DesktopCommanderMCP's runtime through periodic scanning and event-driven checks in the terminal management layer.

### TerminalManager Periodic Checks

In **[`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts)**, the `TerminalManager` class buffers stdout/stderr data and executes a **100ms periodic check** to evaluate process state:

```typescript
// src/terminal-manager.ts (line 397)
periodicCheck = setInterval(() => {
  if (output.trim()) {
    const processState = analyzeProcessState(output, childProcess.pid);
    if (processState.isWaitingForInput) {
      session.isBlocked = true;
      resolveOnce({ pid: childProcess.pid!, output, isBlocked: true });
    }
  }
}, 100);

```

When `isWaitingForInput` becomes true, the manager marks the session as blocked and resolves the command promise early, allowing the AI agent to recognize the interactive state and send appropriate input.

### Quick-Pattern Optimization

For performance, the system implements a lightweight regex shortcut `/>>>\s*$|>\s*$|\$\s*$|#\s*$/` that catches obvious prompts instantly. This bypasses the slower `analyzeProcessState` function for clear-cut cases, immediately flagging the process as blocked without waiting for the next periodic scan.

### Improved Process Tools Integration

Higher-level command handlers in **[`src/tools/improved-process-tools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/improved-process-tools.ts)** leverage the detection system to determine session lifecycle:

```typescript
// src/tools/improved-process-tools.ts (excerpt)
const processState = analyzeProcessState(result.output, result.pid);
if (processState.isWaitingForInput) { 
  /* keep session open for REPL interaction */ 
} else { 
  /* treat as completed and close session */ 
}

```

This integration enables seamless transitions between command execution and interactive REPL sessions.

## Process State Reference

The DesktopCommanderMCP process detection system categorizes processes into three mutually exclusive states:

- **Running**: `isRunning: true`, `isWaitingForInput: false`, `isFinished: false` — The process is actively emitting output but has not encountered a prompt or completion indicator.
- **Waiting for Input**: `isWaitingForInput: true` — A REPL prompt was recognized in the output buffer; the process is paused awaiting user input.
- **Finished**: `isFinished: true` — Either a completion indicator or error pattern was detected, signaling process termination.

## Implementation Examples

### Manual State Checking

You can programmatically check process state using the detection utility:

```typescript
// Example: Manually checking a process's state
import { analyzeProcessState } from './utils/process-detection.js';

const output = `
>>> import os
>>> os.listdir('.')
>>> 
`;
const state = analyzeProcessState(output);
console.log(state.isWaitingForInput); // true

```

### Integration with TerminalManager

The following demonstrates how the detection system surfaces state information through the terminal manager API:

```typescript
// Example: How TerminalManager uses the detection
import { terminalManager } from './terminal-manager.js';

async function runPython() {
  const result = await terminalManager.executeCommand('python', 5000);
  // `result.isBlocked` will be true because the REPL prompt (>>> ) was detected.
  console.log(result.isBlocked ? 'REPL ready' : 'Command finished');
}
runPython();

```

## Summary

- **DesktopCommanderMCP process detection** operates through pattern matching in [`src/utils/process-detection.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/process-detection.ts), specifically the `analyzeProcessState` function.
- The system maintains three constant catalogues: **`REPL_PROMPTS`** for interactive input detection, **`COMPLETION_INDICATORS`** for normal termination, and **`ERROR_COMPLETION_PATTERNS`** for crash detection.
- **[`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts)** executes periodic 100ms scans to detect state changes in real-time, setting `session.isBlocked` when REPL prompts are detected.
- Quick-pattern regex optimization provides immediate detection of common prompts without full buffer analysis overhead.
- The state machine returns mutually exclusive flags (`isRunning`, `isWaitingForInput`, `isFinished`) that enable accurate lifecycle management across the MCP server.

## Frequently Asked Questions

### How does DesktopCommanderMCP distinguish between a running process and one waiting for input?

DesktopCommanderMCP scans the last line of stdout/stderr output against the **`REPL_PROMPTS`** catalogue in [`src/utils/process-detection.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/process-detection.ts). If the output ends with characters like `>>>`, `>`, `$`, or `#`, the `analyzeProcessState` function returns `isWaitingForInput: true`, distinguishing blocked REPL sessions from actively running processes.

### What happens when a process crashes or throws an exception?

The detection system checks output against **`ERROR_COMPLETION_PATTERNS`**, which includes regexes for `"Error:"`, `"Exception:"`, and `"Traceback"`. If these patterns match and no REPL prompt follows, `analyzeProcessState` marks the process as finished with `isFinished: true`, ensuring error-terminated processes are not left in a running state.

### Can the detection system handle custom or non-standard REPL prompts?

While the system ships with common prompts in **`REPL_PROMPTS`**, the pattern-based architecture in [`src/utils/process-detection.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/process-detection.ts) allows for extension. Developers can modify the `REPL_PROMPTS` constant or the quick-pattern regex `/>>>\s*$|>\s*$|\$\s*$|#\s*$/` in [`src/terminal-manager.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/terminal-manager.ts) to recognize domain-specific prompt signatures.

### How frequently does DesktopCommanderMCP check process state?

The **`TerminalManager`** implements a 100ms interval scan using `setInterval` to run `analyzeProcessState` against buffered output. Additionally, a quick-pattern regex check runs immediately on output reception to catch obvious prompts without waiting for the periodic scan cycle.