# How Agent Reach Auto-Detects Environments to Distinguish Local from Server

> Agent Reach auto-detects environments distinguishing local from server using a weighted heuristic system checking SSH sessions, container files, display variables, and cloud identifiers.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-06-14

---

**Agent Reach uses a weighted heuristic system in the `_detect_environment` function located in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) that checks for SSH sessions, container files, display variables, cloud VM identifiers, and virtualization status, classifying the machine as `"server"` if the score reaches 2 or higher, otherwise `"local"`.**

The open-source tool Agent Reach (available at `Panniantong/Agent-Reach`) automatically determines whether it is running on a local workstation or a remote server using environment inspection heuristics. This detection powers the default `--env auto` behavior during installation, ensuring appropriate configuration for headless servers without manual intervention.

## How the Weighted Detection Algorithm Works

When you invoke `agent-reach install` without specifying an environment, the CLI triggers `_detect_environment()` which aggregates multiple system indicators into a cumulative score. Each indicator carries a specific weight based on its reliability for identifying server environments.

The function checks five distinct categories:

- **SSH Session Detection** (+2 points): Checks for `SSH_CONNECTION` or `SSH_CLIENT` environment variables
- **Container Environment** (+2 points): Looks for `/.dockerenv` or `/run/.containerenv` files
- **Headless Display** (+1 point): Verifies absence of `DISPLAY` or `WAYLAND_DISPLAY` variables
- **Cloud VM Identification** (+2 points): Reads hypervisor files for known cloud provider strings
- **Virtualization Detection** (+1 point): Executes `systemd-detect-virt` to confirm non-bare-metal environments

## Deep Dive into the Detection Logic

The core implementation resides in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) at lines 955-994. The function uses `os.environ` lookups and filesystem checks to build the indicator count without requiring external dependencies.

```python

# agent_reach/cli.py – lines 955-994

def _detect_environment():
    """Auto-detect if running on local computer or server."""
    import os
    indicators = 0

    # SSH session

    if os.environ.get("SSH_CONNECTION") or os.environ.get("SSH_CLIENT"):
        indicators += 2

    # Docker / container

    if os.path.exists("/.dockerenv") or os.path.exists("/run/.containerenv"):
        indicators += 2

    # No display (headless)

    if not os.environ.get("DISPLAY") and not os.environ.get("WAYLAND_DISPLAY"):
        indicators += 1

    # Cloud VM identifiers

    for cloud_file in ["/sys/hypervisor/uuid", "/sys/class/dmi/id/product_name"]:
        if os.path.exists(cloud_file):
            try:
                with open(cloud_file) as f:
                    content = f.read().lower()
                if any(x in content for x in [
                    "amazon", "google", "microsoft",
                    "digitalocean", "linode", "vultr", "hetzner"
                ]):
                    indicators += 2
            except Exception:
                pass

    # systemd-detect-virt

    try:
        import subprocess
        result = subprocess.run(
            ["systemd-detect-virt"], capture_output=True,
            encoding="utf-8", errors="replace", timeout=3
        )
        if result.returncode == 0 and result.stdout.strip() != "none":
            indicators += 1
    except Exception:
        pass

    return "server" if indicators >= 2 else "local"

```

### Cloud Provider Detection

For cloud identification, the code reads `/sys/hypervisor/uuid` and `/sys/class/dmi/id/product_name`, scanning for case-insensitive matches against major providers including **Amazon**, **Google**, **Microsoft**, **DigitalOcean**, **Linode**, **Vultr**, and **Hetzner**. This catches most popular VPS and cloud instances without requiring metadata service calls.

### Virtualization Verification

The `systemd-detect-virt` subprocess call (with a 3-second timeout) provides a fallback mechanism for detecting KVM, Xen, VMware, or other hypervisors. A return value other than `"none"` adds 1 point to the indicator count.

## Threshold Logic and Classification

The classification threshold requires **2 or more indicators** to return `"server"`. This design prevents false positives from single conditions that might occur on local machines:

- A laptop running a headless terminal (no DISPLAY) scores only 1 point, remaining classified as `"local"`
- A Docker container on a local workstation scores 2 points (Docker file check), correctly identifying as server-like for configuration purposes
- An EC2 instance accessed via SSH typically scores at least 3 points (SSH + Cloud provider + systemd-virt)

This weighted approach balances **precision** and **recall**, ensuring headless servers are properly identified while avoiding misclassification of local development environments.

## Using Auto-Detection in Practice

The automatic detection runs by default when using the `--env auto` flag (or omitting the flag entirely) during installation:

```bash

# Let Agent Reach decide based on the heuristics

python -m agent_reach.cli install --env auto

```

You can also invoke the detection directly in Python to verify how the current environment is classified:

```python
from agent_reach.cli import _detect_environment

result = _detect_environment()
print(result)  # Outputs: 'server' or 'local'

```

## Impact on Installation Behavior

According to the Agent Reach source code, the detected environment influences downstream configuration decisions. When `"server"` is detected, the installer may enable **safe mode** for MC-Porter or configure proxy settings required for network-restricted server environments. Local workstations bypass these server-specific configurations, streamlining the setup for development machines.

## Summary

- **Location**: The `_detect_environment()` function in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 955-994) handles all auto-detection logic
- **Method**: Weighted scoring system examining SSH variables, container files, display availability, cloud metadata, and virtualization status
- **Threshold**: 2+ indicators classify as `"server"`; fewer than 2 classify as `"local"`
- **Providers**: Automatically recognizes Amazon, Google, Microsoft, DigitalOcean, Linode, Vultr, and Hetzner cloud platforms
- **Usage**: Activated by default with `--env auto` during `agent-reach install`

## Frequently Asked Questions

### How does Agent Reach detect if I'm running in a Docker container?

Agent Reach checks for the existence of `/.dockerenv` or `/run/.containerenv` files on the filesystem. If either file exists, the function adds 2 points to the server indicator count, as implemented in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) at lines 962-963.

### Why does Agent Reach require 2 indicators to classify as a server?

A single indicator (such as a missing `DISPLAY` variable) is insufficient because many local laptops can run headless terminals. Requiring 2 or more indicators reduces false positives while reliably catching remote servers, which typically exhibit multiple server-specific characteristics simultaneously (e.g., SSH connection + cloud VM metadata).

### Can I override the auto-detection in Agent Reach?

Yes. While `--env auto` is the default, you can explicitly specify `--env local` or `--env server` when running `agent-reach install` to bypass the automatic detection logic entirely and force a specific configuration profile.

### Which cloud providers does Agent Reach recognize automatically?

The detection system scans for strings identifying **Amazon**, **Google**, **Microsoft**, **DigitalOcean**, **Linode**, **Vultr**, and **Hetzner** in the `/sys/hypervisor/uuid` and `/sys/class/dmi/id/product_name` system files. This covers the majority of mainstream VPS and cloud hosting providers without requiring API calls or network access.