# How Agent Reach Auto-Detects Local vs Server Environments: Inside the `_detect_environment` Function

> Discover how Agent Reach auto-detects local or server environments using a smart scoring system within its _detect_environment function. Learn the logic behind environment classification.

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

---

**Agent Reach uses a weighted scoring system in `_detect_environment` (located in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py)) that inspects SSH sessions, Docker containers, display availability, cloud VM identifiers, and virtualization status; accumulating 2 or more points classifies the environment as `"server"`, otherwise `"local"`.**

When you run `agent-reach install` with the default `--env auto` flag, the CLI must decide whether you are on a personal workstation or a remote headless machine. The Panniantong/Agent-Reach repository implements this logic through a sophisticated heuristic function that aggregates multiple system indicators to determine the runtime environment without manual configuration.

## How the Detection Algorithm Works

The automatic environment detection relies on a scoring mechanism rather than single binary checks. This prevents false positives—such as labeling a local laptop as a server just because it lacks a display in a TTY session.

In [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), the `_detect_environment` function initializes a counter at zero and adds weighted points based on infrastructure cues. The threshold is set at **2 points**: reaching this value returns `"server"`, while anything lower returns `"local"`.

## The Five Heuristics Explained

The function evaluates five distinct categories of environment indicators, each assigned a specific weight based on reliability:

- **SSH Session Detection (+2 points)**  
  Checks for the presence of `SSH_CONNECTION` or `SSH_CLIENT` environment variables using `os.environ.get()`. These variables indicate an active remote shell session, strongly suggesting a server environment.

- **Docker or Container Environment (+2 points)**  
  Verifies containerization by testing if `/.dockerenv` or `/run/.containerenv` exists using `os.path.exists()`. Containers typically run on servers or CI/CD pipelines rather than local desktops.

- **Headless Display (+1 point)**  
  Detects the absence of graphical interfaces by confirming both `DISPLAY` and `WAYLAND_DISPLAY` environment variables are unset. Headless systems receive a modest weight since local machines can also run without displays.

- **Cloud VM Identification (+2 points)**  
  Reads `/sys/hypervisor/uuid` and `/sys/class/dmi/id/product_name` to identify hypervisor signatures. The function searches for strings like `"amazon"`, `"google"`, `"microsoft"`, `"digitalocean"`, `"linode"`, `"vultr"`, or `"hetzner"` to detect major cloud providers.

- **Virtualization Status (+1 point)**  
  Executes `systemd-detect-virt` via `subprocess.run()` and checks if the output is anything other than `"none"`. This catches VirtualBox, VMware, KVM, and other hypervisors commonly used in server infrastructure.

## Code Implementation in agent_reach/cli.py

The source code implementing these heuristics appears in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) between lines 955–994. Here is the complete implementation:

```python
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"

```

The subprocess call utilizes UTF-8 encoding utilities found in [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py) (lines 14–22) to ensure consistent text handling across different Linux distributions.

## Usage Examples

You can trigger automatic detection explicitly or let it run as the default behavior during installation:

```bash

# Explicit auto-detection (default behavior)

python -m agent_reach.cli install --env auto

# Short form invocation

agent-reach install

```

For programmatic access or debugging, import the function directly:

```python
from agent_reach.cli import _detect_environment

environment = _detect_environment()
print(f"Detected environment: {environment}")  # Outputs: 'server' or 'local'

```

The returned value drives downstream configuration decisions, such as enabling safe mode for MC-Porter installations or configuring proxy settings for restricted server networks.

## Testing Environment Detection

The test suite validates this logic in [`tests/test_cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cli.py) (lines 88–100). These tests mock environment variables and filesystem states to verify that the `--env auto` flag correctly interprets different infrastructure scenarios, ensuring the 2-point threshold logic remains accurate across releases.

## Summary

- Agent Reach auto-detects local vs server environments through the `_detect_environment` function in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py).
- The system uses a **weighted scoring mechanism** requiring **2 or more points** to classify as `"server"`.
- **Strong indicators** (SSH sessions, Docker containers, cloud VMs) award **2 points** each, while **weak indicators** (headless displays, virtualization) award **1 point**.
- The function checks environment variables, filesystem paths (`/.dockerenv`, `/sys/class/dmi/id/product_name`), and subprocess output (`systemd-detect-virt`).
- You can invoke detection manually via `--env auto` or programmatically through the Python API.

## Frequently Asked Questions

### What triggers Agent Reach to classify an environment as "server"?

The environment is classified as `"server"` when the internal `_detect_environment` function accumulates **2 or more indicator points**. This typically happens when the function detects an SSH session, finds Docker container files, or identifies cloud provider metadata in system files—each worth 2 points—or through combinations of weaker signals like headless displays (1 point) plus virtualization (1 point).

### How does Agent Reach detect cloud VMs like AWS or Google Cloud?

The function reads `/sys/hypervisor/uuid` and `/sys/class/dmi/id/product_name`, converting the content to lowercase and searching for provider-specific strings. It looks for `"amazon"` (AWS), `"google"` (GCP), `"microsoft"` (Azure), `"digitalocean"`, `"linode"`, `"vultr"`, or `"hetzner"`. Finding any match adds 2 points to the server indicator count.

### Can I override the automatic environment detection?

While the source analysis focuses on the automatic detection mechanism, the CLI accepts an `--env` parameter that defaults to `"auto"`. You can explicitly specify `--env local` or `--env server` to bypass the heuristic detection entirely, though the specific override options depend on the complete CLI implementation beyond the `_detect_environment` function.

### Where are the environment detection tests located?

Unit tests for the auto-detection logic reside in [`tests/test_cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cli.py) between lines 88–100. These tests mock `os.environ` values and filesystem states to simulate various deployment scenarios, verifying that the indicator scoring correctly distinguishes between local workstations and remote servers under controlled conditions.