# How Agent Reach Detects Local vs Server Environments: Inside `_detect_environment()`

> Agent Reach detects local vs server environments using OS indicators in cli.py. Discover how this scoring mechanism identifies your environment for streamlined operations.

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

---

**Agent Reach detects local vs server environments by scoring OS-level indicators in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), returning `"server"` when the weighted sum reaches at least 2 and `"local"` otherwise.**

Agent Reach is an open-source CLI tool that automatically adapts its installation and behavior depending on whether it runs on a developer workstation or a headless remote machine. Understanding how Agent Reach detects local vs server environments is essential for anyone debugging installation routing or contributing to the project. The core logic lives in `_detect_environment()` inside [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 977–1016), where it inspects SSH sessions, container files, display variables, cloud metadata, and virtualization state.

## How `_detect_environment()` Scores System Clues

The `_detect_environment()` function uses a **best-effort weighted scoring system**. It increments a local `indicators` counter when it finds clues associated with servers, containers, or cloud VMs. If the final count is **greater than or equal to 2**, the function returns `"server"`; otherwise it returns `"local"`.

### SSH Sessions and Containers (+2 Each)

Strong signals receive the highest weight. The function checks for an active SSH session by looking at the environment variables `SSH_CONNECTION` and `SSH_CLIENT`:

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

```

It also detects Docker or containerized environments by testing for the presence of `/.dockerenv` or `/run/.containerenv`:

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

```

### Display and Virtualization Checks (+1 Each)

For graphical workstations, the function checks for `DISPLAY` or `WAYLAND_DISPLAY`. Their absence suggests a headless server:

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

```

Virtualization is tested by running `systemd-detect-virt`. If the command succeeds and returns anything other than `"none"`, the score increases:

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

```

### Cloud VM Detection (+2)

The function reads two kernel-exposed files commonly present on cloud instances—`/sys/hypervisor/uuid` and `/sys/class/dmi/id/product_name`—and searches for known vendor strings:

```python
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:
                if any(x in f.read().lower()
                       for x in ["amazon", "google", "microsoft",
                                 "digitalocean", "linode", "vultr", "hetzner"]):
                    indicators += 2
        except Exception:
            pass

```

## Where the Detection Result Is Used

The environment string returned by `_detect_environment()` drives decisions beyond the CLI module. According to the Agent Reach source code:

- **[`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py)** consumes the detected environment when running diagnostics.
- **[`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py)** may adjust configuration defaults based on whether the host is classified as local or server.
- **[`tests/test_cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cli.py)** (lines 916–931) validates the routing logic that depends on this classification.

## Practical Code Examples

### Checking the Environment Directly

You can import and call the detector in your own scripts:

```python
from agent_reach.cli import _detect_environment

env = _detect_environment()
print(f"Running in a {env} environment")

# → "Running in a local environment" on a laptop,

#   "Running in a server environment" on a headless VM or container.

```

### Conditional Installation Logic

Agent Reach uses the result to choose between desktop-oriented and headless-oriented tools:

```python
from agent_reach.cli import _detect_environment, _install_opencli_deps, _install_rdt_cli

if _detect_environment() == "server":
    _install_rdt_cli()      # headless-friendly client

else:
    _install_opencli_deps() # desktop-friendly client

```

### Mocking the Detector in Tests

The test suite patches `_detect_environment()` to verify downstream behavior without relying on the host system:

```python
import pytest
import agent_reach.cli as cli

def test_detect_environment_local(monkeypatch):
    monkeypatch.setattr(cli, "_detect_environment", lambda: "local")
    assert cli._detect_environment() == "local"

def test_detect_environment_server(monkeypatch):
    monkeypatch.setattr(cli, "_detect_environment", lambda: "server")
    assert cli._detect_environment() == "server"

```

## Summary

- **`_detect_environment()`** in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) is the single source of truth for local vs server classification in Agent Reach.
- The function accumulates **weighted indicators** from SSH variables, container files, display availability, cloud vendor files, and virtualization state.
- A **threshold of 2** determines the final return value: `"server"` if the score is ≥ 2, otherwise `"local"`.
- The result propagates to the doctor, config, and test subsystems to ensure the correct tooling path is selected.

## Frequently Asked Questions

### Where is the environment detection logic located in Agent Reach?

The detection logic is implemented in **[`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py)** at lines 977–1016 inside the `_detect_environment()` function. This helper is imported and invoked by other modules such as [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) and [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py).

### What indicators does Agent Reach check to detect a server environment?

Agent Reach checks five categories of indicators: **SSH session variables**, **container markers**, **display availability**, **cloud vendor strings** in kernel-exposed files, and **virtualization state** via `systemd-detect-virt`. Each indicator carries a specific weight—strong signals like SSH or containers add 2 points, while weaker signals like missing displays add 1 point. The function tallies these weights to decide whether the host behaves like a local workstation or a remote server.

### How many indicators are needed to classify an environment as a server?

The function requires a **weighted score of at least 2**. Because strong signals like SSH or containers contribute +2 each, a single strong hint can trigger a `"server"` result. Weaker signals such as missing displays or virtualization contribute +1 and typically need to be paired to reach the threshold.

### Can I override or mock the environment detection for testing?

Yes. The Agent Reach test suite in **[`tests/test_cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cli.py)** (lines 916–931) demonstrates overriding `_detect_environment()` with `monkeypatch.setattr`. This lets tests verify server and local code paths without depending on the actual runtime environment.