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

Agent Reach uses a weighted scoring system in _detect_environment (located in 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, 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 between lines 955–994. Here is the complete implementation:

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 (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:


# 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:

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 (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.
  • 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →