# Understanding the Difference Between '--safe' and '--dry-run' Installation Modes in Agent Reach

> Learn the key differences between Agent Reach installation modes --safe and --dry-run. Understand how each flag simulates or reports installation steps without system changes.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-07-15

---

**The `--safe` flag skips automatic system modifications and only reports missing dependencies, while `--dry-run` simulates the complete installation process including optional channels and cookie imports without making any changes to the system.**

Agent Reach is an open-source automation framework that provides distinct installation preview modes to help administrators audit system requirements before committing changes. Understanding the difference between '--safe' and '--dry-run' installation modes ensures you choose the right level of system interaction for your deployment scenario. Both flags are defined in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) and control whether the installer executes `apt`, `brew`, or pip commands, or merely previews what would happen.

## What is the '--safe' Installation Mode?

The `--safe` flag activates a **read-only audit mode** that checks for missing system dependencies without modifying the host environment. When enabled, the installer prints a "SAFE MODE" banner and invokes checking-only versions of dependency helpers rather than their installation counterparts.

Specifically, in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) at lines 45-53, the code branches based on these flags:

- **`safe_mode`** triggers `_install_system_deps_safe()` (line 50)
- **`dry_run`** triggers `_install_system_deps_dryrun()` (line 47)
- **Default** behavior runs `_install_system_deps()` (line 52)

The `--safe` mode also disables optional channel installation and cookie import steps entirely. According to lines 69-71 in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), optional channels only install when both `dry_run` and `safe_mode` are false.

This mode is ideal when you need a quick audit of missing packages or configuration steps but cannot risk automatic package manager execution in production environments.

## What is the '--dry-run' Installation Mode?

The `--dry-run` flag performs a **full simulation** where every actionable step is replaced by a `[dry-run]` prefixed message. Unlike `--safe`, which skips optional features, `--dry-run` previews the complete installation workflow including optional channels and cookie extraction without touching the filesystem or network.

Key implementation details from [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py):

- **Lines 177-179**: The arguments are parsed into local variables `safe_mode = args.safe` and `dry_run = args.dry_run`
- **Lines 80-82**: When `dry_run` is true, the installer prints a summary of channels that would be installed instead of executing the installation
- **Lines 88-90**: Cookie extraction displays a placeholder message rather than accessing browser data

The `--dry-run` mode runs the checking versions of system dependency helpers while also printing the exact commands it would have executed. This provides a complete view of the installer’s behavior including network operations and file modifications that would occur in a real installation.

## Key Differences Between '--safe' and '--dry-run'

While both flags prevent system modification, they serve different verification purposes:

| Feature | `--safe` | `--dry-run` |
|---------|----------|-------------|
| **System Dependencies** | Reports missing packages via `_install_system_deps_safe()` | Reports missing packages via `_install_system_deps_dryrun()` and shows commands |
| **Optional Channels** | Completely skipped | Previewed with `[dry-run]` prefix |
| **Cookie Import** | Disabled | Simulated with placeholder output |
| **Network Activity** | None | None |
| **Best For** | Dependency audits | Full deployment previews |

In [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) at lines 92-95, both modes trigger a banner to make the non-destructive state obvious to the user, but the scope of reporting differs significantly.

## Implementation Details in agent_reach/cli.py

The divergence between these modes is handled through a three-branch conditional structure in the CLI implementation.

**Argument Definition (Lines 71-74):**

```python

# From agent_reach/cli.py

install_parser.add_argument('--safe', action='store_true', ...)
install_parser.add_argument('--dry-run', action='store_true', ...)

```

**System Dependency Routing (Lines 45-53):**

```python
if dry_run:
    _install_system_deps_dryrun()
elif safe_mode:
    _install_system_deps_safe()
else:
    _install_system_deps()

```

**MCporter Installation (Lines 55-61):**

The same pattern applies to MCporter installation, with dedicated safe and dry-run helper functions that mirror the system dependency logic.

**Optional Channel Guard (Lines 69-71):**

```python
if not dry_run and not safe_mode:
    # Actually install optional channels

```

## When to Use Each Mode

Choose your installation preview mode based on the depth of verification required:

- **Use `--safe`** when running in restricted environments where even simulated commands might trigger security alerts, or when you only need a dependency checklist without execution details.

- **Use `--dry-run`** when validating complex configurations that include optional channels (like Twitter, Reddit, or Bilibili) and cookie imports, or when documenting the exact commands that will run during deployment.

Both flags are mutually exclusive in practice, though the code handles them through separate conditionals. Running neither flag performs the actual installation with network and filesystem modifications enabled.

## Code Examples

Execute these commands to see the difference between '--safe' and '--dry-run' installation modes:

```bash

# Safe mode - only reports missing system packages

agent-reach install --safe

```

Expected output:

```

SAFE MODE — skipping automatic system changes

System dependency check:
  [safe] Would install ffmpeg, libmagic, etc.

```

```bash

# Dry-run mode - shows complete plan including optional channels

agent-reach install --dry-run --channels=twitter,reddit,bilibili

```

Expected output:

```

[dry-run] Would install system dependencies: ffmpeg, libmagic
[dry-run] Would install optional channels: twitter, reddit, bilibili
[dry-run] Would try to import cookies from Chrome/Firefox

```

## Summary

- **`--safe`** performs a dependency audit without system modifications, skipping optional channels and cookie imports entirely.
- **`--dry-run`** simulates the full installation workflow, printing `[dry-run]` prefixes for every command including optional features.
- **Implementation** resides in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) with distinct helper functions for each mode: `_install_system_deps_safe()` versus `_install_system_deps_dryrun()`.
- **Optional channels** only preview in dry-run mode; safe mode skips them completely according to lines 69-71.
- **Use cases** differ by scope: `--safe` for quick audits, `--dry-run` for complete deployment validation.

## Frequently Asked Questions

### Can I use --safe and --dry-run together?

No, these modes are designed to be mutually exclusive. While the code in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) handles both flags through separate conditionals, using them together results in the dry-run behavior taking precedence for system dependencies while both flags block actual optional channel installation. For clarity, choose one mode based on whether you need a quick audit (`--safe`) or a full simulation (`--dry-run`).

### Does --dry-run check if system packages are actually installed?

Yes, `--dry-run` invokes `_install_system_deps_dryrun()` which performs the same dependency checks as the safe mode, but additionally prints the exact commands that would be executed. According to the implementation in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), both checking variants validate package presence before reporting status, though `--dry-run` includes the simulation of installation commands that would follow.

### Why does --safe skip optional channels while --dry-run shows them?

The `--safe` flag is designed for minimal system interaction—only checking core dependencies via `_install_system_deps_safe()` and `_install_mcporter_safe()`. Optional channels require additional configuration steps that safe mode explicitly avoids. In contrast, `--dry-run` aims to provide a complete preview of the installation behavior, so it includes optional channels at lines 80-82 with `[dry-run]` markers to indicate these are simulated rather than executed.

### Will these modes work on all operating systems?

Yes, the `--safe` and `--dry-run` flags are implemented at the CLI level in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) before platform-specific code executes. The helper functions `_install_system_deps_safe()` and `_install_system_deps_dryrun()` wrap the platform detection logic (whether `apt`, `brew`, or other package managers), ensuring consistent preview behavior across Linux, macOS, and Windows environments regardless of the underlying system commands.