CommandLineExecutor Server
Overview
CommandLineExecutor provides shell command execution capabilities for launching applications and running system commands.
Server Type: Action
Deployment: Local (in-process)
Agent: HostAgent, AppAgent
LLM-Selectable: ✅ Yes
Server Information
| Property | Value |
|---|---|
| Namespace | CommandLineExecutor |
| Server Name | UFO CLI MCP Server |
| Platform | Cross-platform (Windows, Linux, macOS) |
| Tool Type | action |
Tools
run_shell
Execute a shell command to launch applications or perform system operations.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bash_command |
str |
✅ Yes | Command to execute in shell |
Returns
None - Command is launched asynchronously (5-second wait after execution)
Example
# Launch Notepad
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
tool_name="run_shell",
parameters={"bash_command": "notepad.exe"}
)
])
# Launch application with arguments
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
tool_name="run_shell",
parameters={"bash_command": "python script.py --arg value"}
)
])
# Create directory (Windows)
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
tool_name="run_shell",
parameters={"bash_command": "mkdir C:\\temp\\newfolder"}
)
])
Error Handling
Raises ToolError if:
- Command is empty
- Execution fails
# Error: Empty command
ToolError("Bash command cannot be empty.")
# Error: Execution failed
ToolError("Failed to launch application: {error_details}")
Implementation Details
- Uses
subprocess.Popenwithshell=True - Waits 5 seconds after launch for application to start
- Non-blocking: Returns immediately after launch
Security Warning
Arbitrary command execution risk! Always validate commands before execution.
Dangerous examples:
- rm -rf / (Linux)
- del /F /S /Q C:\* (Windows)
- shutdown /s /t 0
Best Practice: Implement command whitelist or validation.
Configuration
HostAgent:
default:
action:
- namespace: HostUIExecutor
type: local
- namespace: CommandLineExecutor
type: local # Enable shell execution
AppAgent:
default:
action:
- namespace: AppUIExecutor
type: local
- namespace: CommandLineExecutor
type: local # Enable if app needs to launch child processes
Best Practices
1. Validate Commands
def safe_run_shell(command: str):
"""Whitelist-based command validation"""
allowed_commands = [
"notepad.exe",
"calc.exe",
"mspaint.exe",
"code", # VS Code
]
cmd_base = command.split()[0]
if cmd_base not in allowed_commands:
raise ValueError(f"Command not allowed: {cmd_base}")
return MCPToolCall(
tool_key="action::run_shell",
tool_name="run_shell",
parameters={"bash_command": command}
)
# Usage
await computer.run_actions([safe_run_shell("notepad.exe test.txt")])
2. Wait for Application Launch
# Launch application
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "notepad.exe"}
)
])
# Wait for launch (5 seconds built-in + extra)
await asyncio.sleep(2)
# Get window list
windows = await computer.run_actions([
MCPToolCall(tool_key="data_collection::get_desktop_app_info", ...)
])
# Find Notepad window
notepad_windows = [w for w in windows[0].data if "Notepad" in w["name"]]
3. Platform-Specific Commands
import platform
def get_platform_command(app_name: str) -> str:
"""Get platform-specific command"""
if platform.system() == "Windows":
commands = {
"notepad": "notepad.exe",
"terminal": "cmd.exe",
"browser": "start msedge"
}
elif platform.system() == "Darwin": # macOS
commands = {
"notepad": "open -a TextEdit",
"terminal": "open -a Terminal",
"browser": "open -a Safari"
}
else: # Linux
commands = {
"notepad": "gedit",
"terminal": "gnome-terminal",
"browser": "firefox"
}
return commands.get(app_name, app_name)
# Usage
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": get_platform_command("notepad")}
)
])
4. Handle Launch Failures
try:
result = await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "nonexistent.exe"}
)
])
if result[0].is_error:
logger.error(f"Failed to launch: {result[0].content}")
# Retry with alternative command
except Exception as e:
logger.error(f"Command execution exception: {e}")
Use Cases
1. Application Launching
# Launch text editor
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "notepad.exe"}
)
])
# Launch browser with URL
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "start https://www.example.com"}
)
])
2. File Operations
# Create directory
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "mkdir C:\\temp\\workspace"}
)
])
# Copy file
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "copy source.txt dest.txt"}
)
])
3. Script Execution
# Run Python script
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "python automation_script.py --mode batch"}
)
])
# Run PowerShell script
await computer.run_actions([
MCPToolCall(
tool_key="action::run_shell",
parameters={"bash_command": "powershell -File script.ps1"}
)
])
Limitations
- No output capture: Command output (stdout/stderr) is not returned
- No exit code: Cannot determine if command succeeded
- Async execution: No way to know when command completes
- Security risk: Arbitrary command execution
Tip: For Linux systems with output capture and better control, use BashExecutor server instead.
Related Documentation
- BashExecutor - Linux command execution with output
- Action Servers - Action server concepts
- HostAgent - HostAgent architecture