How to Interact with a Running Process in Desktop Commander MCP: Session Management Guide

Desktop Commander MCP exposes a session-based architecture that lets you spawn child processes, stream input and output, and terminate them through dedicated MCP tools like start_process, interact_with_process, and read_process_output.

Desktop Commander MCP, maintained in the wonderwhy-er/DesktopCommanderMCP repository, treats running command-line programs as persistent sessions that you can control programmatically via the Model Context Protocol. Unlike simple command execution, this architecture allows you to start an interactive REPL, feed ongoing input to a long-running script, and read buffered output before eventually terminating the process cleanly.

Understanding the Process Lifecycle Architecture

When you interact with a running process in Desktop Commander MCP, the server spawns child processes using Node’s child_process.exec (for simple commands) or spawn (for interactive sessions). Each spawned session is tracked by the Terminal Manager (src/terminal-manager.ts), which maintains an in-memory map of session IDs to process handles. This design allows the server to route subsequent tool calls to the correct process without ambiguity.

The public-facing MCP tools wrap these low-level Node APIs and translate results into the standard ServerResult shape expected by MCP clients. Request dispatching originates in src/server.ts, which delegates to specialized handlers based on the tool being invoked.

Core MCP Tools for Process Interaction

Starting and Managing Interactive Sessions

The interactive session toolsstart_process, interact_with_process, read_process_output, and force_terminate—are routed through src/handlers/terminal-handlers.ts. These handlers forward requests to the Terminal Manager, which manages the actual child process I/O streams and session lifecycle.

  • start_process: Spawns a new process with a specified command, arguments, and working directory, returning a unique sessionId for subsequent operations.
  • interact_with_process: Sends input strings (including newlines) to the stdin of a running session.
  • read_process_output: Retrieves buffered stdout/stderr content from a specific offset, allowing you to poll for new data incrementally.
  • force_terminate: Immediately kills a session managed by the Terminal Manager.

System-Level Process Utilities

For operating-system-level process management, the server exposes list_processes and kill_process. The request handling logic resides in src/handlers/process-handlers.ts, where functions like handleKillProcess validate incoming arguments using Zod schemas defined in src/tools/schemas.ts before invoking the underlying tool implementations.

The actual system integration lives in src/tools/process.ts:

  • listProcesses(): Enumerates OS-level processes using ps aux on Unix or tasklist on Windows.
  • killProcess(): Terminates a process by PID using Node’s process.kill.

Configuration and Safety Controls

Runtime behavior is governed by src/config.ts, which exposes settings for defaultShell, blockedCommands, and execution timeouts that affect how processes are spawned. When running the server in automated environments where prompts might interfere with long-running sessions, use the --no-onboarding CLI flag to disable interactive onboarding flows.

Practical Implementation Examples

Below are concrete MCP tool calls you can use from Claude Desktop or any MCP-compatible client.

Start an interactive Node.js REPL:

{
  "tool": "start_process",
  "arguments": {
    "command": "node",
    "args": [],
    "cwd": "/Users/me/projects"
  }
}

Send a line of JavaScript code to the running session:

{
  "tool": "interact_with_process",
  "arguments": {
    "sessionId": "abc123",
    "input": "console.log('Hello from MCP');\n"
  }
}

Read accumulated output from the process buffer:

{
  "tool": "read_process_output",
  "arguments": {
    "sessionId": "abc123",
    "offset": 0,
    "length": 500
  }
}

List operating system processes for debugging:

{
  "tool": "list_processes",
  "arguments": {}
}

Terminate a stray process by PID:

{
  "tool": "kill_process",
  "arguments": {
    "pid": 9876
  }
}

Summary

  • Desktop Commander MCP uses a session-based architecture to manage long-running processes, with the Terminal Manager (src/terminal-manager.ts) tracking active sessions in memory.
  • Interactive I/O is handled through start_process, interact_with_process, and read_process_output, routed via src/handlers/terminal-handlers.ts.
  • System-level process operations (list_processes, kill_process) are implemented in src/tools/process.ts and validated through src/handlers/process-handlers.ts using Zod schemas.
  • Configuration options in src/config.ts allow you to specify default shells, block dangerous commands, and disable onboarding with the --no-onboarding flag.

Frequently Asked Questions

How do I start an interactive session in Desktop Commander MCP?

Use the start_process tool with your desired command and working directory. The server returns a sessionId that you must preserve for subsequent calls to interact_with_process or read_process_output. This session is managed by the Terminal Manager until you explicitly terminate it or the process exits.

What is the difference between kill_process and force_terminate?

kill_process operates at the OS level using process.kill to terminate any process by its PID, regardless of whether it was started by the MCP server. In contrast, force_terminate specifically targets sessions managed by the Terminal Manager, cleaning up the internal session map and killing the associated child process handle.

How does the Terminal Manager track running processes?

The Terminal Manager maintains an in-memory Map that associates session IDs (generated when you call start_process) to the child process handles created by Node’s child_process.spawn. This allows the server to route input to the correct stdin stream and buffer output for specific sessions, as implemented in src/terminal-manager.ts.

Where can I configure blocked commands or default shells?

Runtime configuration is centralized in src/config.ts. You can define blockedCommands to prevent execution of dangerous utilities, set defaultShell to specify which shell binary spawns new processes, and adjust timeouts that affect how long the server waits for process output before returning control to the client.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →