# How Agent Reach Performs Environment Auto-Detection (SSH, Docker, DISPLAY)

> Agent Reach automatically detects your environment (SSH, Docker, DISPLAY) by scoring weighted indicators. Understand the process and how it scores 2 or higher for server detection.

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

---

**Agent Reach detects whether it is running on a local workstation or a remote server by scoring weighted indicators inside the `_detect_environment()` helper in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), returning `"server"` when the cumulative score reaches 2 or higher.**

The open-source Python framework [Panniantong/Agent-Reach](https://github.com/Panniantong/Agent-Reach) uses lightweight runtime inspection to decide installation behavior. Instead of relying on external tools or heavy dependencies, the CLI inspects environment variables, filesystem markers, and virtualization hints to classify the host environment.

## The Detection Algorithm in `_detect_environment()`

The core logic lives in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 555–594) inside the private function `_detect_environment()`. This function implements a **weighted scoring system** where each indicator adds points to a counter; if the total is **≥ 2**, the environment is classified as `"server"`, otherwise `"local"`.

### SSH Session Detection

Agent Reach checks for active SSH connections by inspecting standard environment variables.

- **Method**: `os.environ.get("SSH_CONNECTION")` or `os.environ.get("SSH_CLIENT")`
- **Weight**: +2 points

A positive result strongly suggests a remote VPS or cloud instance accessed via SSH.

### Docker and Container Detection

The function probes for container-specific filesystem artifacts that Docker and Podman create.

- **Method**: `os.path.exists("/.dockerenv")` or `os.path.exists("/run/.containerenv")`
- **Weight**: +2 points

These files are reliable indicators that the process is running inside a containerized environment rather than bare metal.

### Display Environment Checks

Headless servers typically lack graphical display servers.

- **Method**: Verify absence of `DISPLAY` and `WAYLAND_DISPLAY` environment variables
- **Weight**: +1 point

This is a weaker signal because headless mode can also occur on local workstations, hence the lower weight.

### Cloud VM Identification

Agent Reach reads hardware identification files to detect popular cloud providers.

- **Method**: Parse `/sys/hypervisor/uuid` and `/sys/class/dmi/id/product_name` for substrings: `amazon`, `google`, `microsoft`, `digitalocean`, `linode`, `vultr`, `hetzner`
- **Weight**: +2 points

If either file contains a known cloud provider string, the function adds significant weight to the server classification.

### systemd-detect-virt Fallback

As a final verification step, the function executes `systemd-detect-virt` when available.

- **Method**: `subprocess.run(["systemd-detect-virt"], ...)` with a 3-second timeout
- **Weight**: +1 point (if result is not `"none"`)

This catches virtual machines or hypervisors not identified by the cloud-specific file checks.

## Implementation Details in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py)

The complete implementation aggregates these checks into a single integer counter:

```python
def _detect_environment():
    import os, subprocess
    indicators = 0

    # 1️⃣ SSH detection

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

    # 2️⃣ Docker / container detection

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

    # 3️⃣ Headless display detection

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

    # 4️⃣ Cloud‑VM hints

    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

    # 5️⃣ systemd‑detect‑virt fallback

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

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

```

The threshold of **2 points** ensures that strong single indicators (SSH, Docker, or Cloud VM) immediately trigger server mode, while weaker signals require corroboration.

## Using Auto-Detection in the Installer

The `agent-reach install` command uses this logic when the `--env` flag is set to `auto` (the default):

```python
env = args.env
if env == "auto":
    env = _detect_environment()

```

When auto-detection runs, the CLI prints the result:

```bash
$ agent-reach install
Environment: Server/VPS (auto-detected)

```

You can manually override the detection to force a specific configuration:

```bash

# Force server mode

$ agent-reach install --env=server

# Force local mode

$ agent-reach install --env=local

```

## Testing the Detection Logic

The test suite in [`tests/test_cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cli.py) validates both code paths by monkey-patching the detector:

```python

# Simulate local workstation

monkeypatch.setattr(cli, "_detect_environment", lambda: "local")

# Simulate remote server

monkeypatch.setattr(cli, "_detect_environment", lambda: "server")

```

This allows unit tests to verify installer behavior without requiring actual SSH sessions or Docker containers.

## Summary

- **Weighted scoring**: `_detect_environment()` assigns +2 for SSH/Docker/Cloud, +1 for headless display or systemd-virt, requiring a total ≥ 2 to classify as `"server"`.
- **Filesystem probes**: Checks for `/.dockerenv`, `/run/.containerenv`, and cloud vendor strings in `/sys/class/dmi/id/product_name`.
- **Environment variables**: Inspects `SSH_CONNECTION`, `SSH_CLIENT`, `DISPLAY`, and `WAYLAND_DISPLAY`.
- **Override capability**: Use `--env=server` or `--env=local` to bypass auto-detection.
- **Source location**: Implementation resides in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) lines 555–594.

## Frequently Asked Questions

### How does Agent Reach detect if it's running inside Docker?

Agent Reach checks for the existence of `/.dockerenv` or `/run/.containerenv` on the filesystem. If either file is present, the function adds 2 points to the indicator score, typically pushing the total above the threshold required to classify the environment as a server.

### Can I manually override the environment detection?

Yes. When running `agent-reach install`, pass the `--env` flag with either `server` or `local` to skip auto-detection. For example: `agent-reach install --env=server` forces server mode regardless of what the detection algorithm would determine.

### What happens if the detection score is exactly 2?

A score of exactly 2 meets the threshold defined in `_detect_environment()`, causing the function to return `"server"`. This means any single strong indicator (SSH session, Docker container, or Cloud VM fingerprint) is sufficient to trigger server mode, while combinations of weaker signals (like headless display plus systemd-virt) can also trigger it.

### Where is the environment detection logic located?

The detection logic is implemented in the private helper function `_detect_environment()` within [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 555–594). This function is imported and called by the install command handler when the `--env` argument is set to `auto`.