How Agent Reach Auto-Detects Local vs Server Environments

Agent Reach uses a weighted heuristic scoring system in _detect_environment() that assigns points for SSH sessions, containers, headless displays, cloud VM identifiers, and virtualization status, classifying the machine as "server" if the score reaches 2 or higher.

The Panniantong/Agent-Reach repository includes an intelligent environment detection mechanism that automatically distinguishes between local development workstations and remote server instances. When you run agent-reach install --env auto, the CLI evaluates multiple system indicators to determine whether it should apply server-specific configurations or local desktop defaults.

How Environment Detection Works in Agent Reach

The detection logic resides in agent_reach/cli.py within the _detect_environment() function (lines 955-994). This function implements a scoring-based approach that aggregates evidence from five distinct system characteristics to make an accurate classification.

The Heuristic Scoring System

Each indicator carries a specific weight based on its reliability for identifying server environments. The function initializes a counter at zero and accumulates points across multiple checks.

SSH Session Detection

Remote access via SSH is a strong server indicator. The function checks for the presence of SSH_CONNECTION or SSH_CLIENT environment variables using os.environ.get(), adding 2 points if either is present.

Container Detection

Docker and containerized environments typically run on servers. The code verifies the existence of /.dockerenv or /run/.containerenv using os.path.exists(), contributing 2 points to the score when found.

Display and Cloud VM Identification

Headless systems without graphical displays receive 1 point when both DISPLAY and WAYLAND_DISPLAY environment variables are absent. Additionally, the function reads /sys/hypervisor/uuid and /sys/class/dmi/id/product_name to detect cloud providers like Amazon, Google, Microsoft, DigitalOcean, Linode, Vultr, or Hetzner, adding 2 points if any match is found.

Virtualization Checks

The function executes systemd-detect-virt via subprocess.run() to identify virtualized environments. If the command returns a value other than "none", it adds 1 point to the indicator count.

Threshold Logic: When Is a Machine Considered a Server?

After aggregating all indicators, the function applies a simple threshold: if the total score is 2 or greater, it returns "server"; otherwise, it returns "local". This threshold ensures that a single weak indicator (like a headless laptop) does not trigger server mode, while combinations of signals (SSH + no display) or strong single signals (Docker container) reliably identify server environments.

Implementation Details in agent_reach/cli.py

The complete implementation handles exceptions gracefully, ensuring that missing files or failed subprocess calls do not crash the detection process.


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

Practical Usage Examples

You can trigger automatic detection via the CLI or import the function directly for programmatic use.

To use the auto-detection during installation:


# Let Agent Reach decide based on the heuristics

$ python -m agent_reach.cli install --env auto

# Internally triggers:

#   env = _detect_environment()

#   → "server" or "local"

To query the detection directly in Python:

>>> from agent_reach.cli import _detect_environment
>>> _detect_environment()
'server'   # or 'local' depending on where you run it

Testing and Validation

The detection logic is verified in tests/test_cli.py (lines 88-100), which mocks various environment variables and file system states to ensure correct classification. The subprocess utilities in agent_reach/utils/process.py (lines 14-22) provide UTF-8 encoding support for external commands like systemd-detect-virt.

Summary

  • Weighted scoring system: Agent Reach assigns points (1-2) based on the strength of server indicators rather than relying on single checks.
  • Threshold of 2: A machine must accumulate at least 2 points to be classified as a server, preventing false positives from individual weak signals.
  • Five detection vectors: SSH sessions, Docker containers, headless displays, cloud VM metadata, and virtualization status provide comprehensive coverage.
  • Graceful degradation: The function handles missing files, permission errors, and subprocess failures silently without crashing the CLI.
  • Cross-platform considerations: While optimized for Linux cloud instances (using /sys/ paths and systemd-detect-virt), the logic falls back safely on other systems.

Frequently Asked Questions

How accurate is Agent Reach's environment detection?

The multi-factor approach achieves high accuracy by requiring corroborating evidence. A standard laptop running locally typically scores 0 points, while a Docker container on a cloud VM easily exceeds the threshold with 4+ points. According to the source code in agent_reach/cli.py, the system specifically targets Linux server environments where SSH, containers, and cloud metadata typically coexist.

Can I override the automatic detection?

Yes. While --env auto is the default for agent-reach install, you can explicitly specify --env local or --env server to bypass the _detect_environment() function entirely. This is useful when the heuristics misidentify specialized environments like WSL or remote desktops that may present mixed signals.

Why does the detection use a threshold of 2 points?

The threshold prevents local development machines from being misclassified as servers. A laptop running without a display (1 point) or a local VM (1 point from systemd-detect-virt) would not trigger server mode. However, any combination of two indicators—such as SSH plus headless display, or Docker plus cloud metadata—reliably indicates a non-interactive server environment that requires server-specific configuration.

Does this work on Windows systems?

The current implementation in agent_reach/cli.py focuses on Linux-specific paths (/sys/hypervisor/uuid, /.dockerenv) and Unix utilities (systemd-detect-virt). On Windows, these checks will fail silently and return 0 points, causing the function to classify the environment as "local" by default. For Windows servers, manual specification via --env server is recommended.

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 →