Local vs Server Environment Detection in Agent Reach: A Complete Guide

Agent Reach uses a multi-indicator scoring system in _detect_environment() to automatically distinguish between local desktop environments and headless servers, enabling it to install appropriate backends like OpenCLI for desktops or pure CLI tools for remote machines.

Agent Reach requires precise environment detection to determine whether it's running on a graphical workstation or a headless server. This distinction, implemented in the agent_reach/cli.py module, drives critical decisions about which backend tools to install for platforms like Reddit and XiaoHongShu. Understanding how local and server environment detection works in Agent Reach helps developers predict behavior across different deployment scenarios.

How Environment Detection Works in Agent Reach

The _detect_environment() Implementation

The core detection logic resides in agent_reach/cli.py (lines 955-994) within the private helper _detect_environment(). This function aggregates multiple OS-level indicators using a weighted scoring system, returning "server" when the cumulative score reaches 2 or higher, and "local" otherwise.

def _detect_environment():
    """Auto‑detect if running on local computer or server."""
    import os
    indicators = 0

    # 1️⃣ SSH session – typical for remote logins

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

    # 2️⃣ Docker / container environment

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

    # 3️⃣ Headless display (no X11/Wayland)

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

    # 4️⃣ Cloud‑VM identifiers (Amazon, Google, Azure, DigitalOcean, …)

    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 (detects virtualisation)

    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 Five Detection Signals

The function checks five specific environment indicators with weighted values:

  • SSH connections (2 points): Checks for SSH_CONNECTION or SSH_CLIENT environment variables, indicating remote login sessions.
  • Container environments (2 points): Detects /.dockerenv or /run/.containerenv files present in Docker and containerized runtimes.
  • Missing display servers (1 point): Verifies absence of DISPLAY (X11) or WAYLAND_DISPLAY variables, suggesting headless operation.
  • Cloud VM signatures (2 points): Reads /sys/hypervisor/uuid and /sys/class/dmi/id/product_name for strings like "amazon", "google", "microsoft", or "digitalocean".
  • Virtualization detection (1 point): Executes systemd-detect-virt to identify virtualized environments, adding a point for any non-"none" result.

Platform-Specific Backend Selection

Agent Reach uses the environment classification to determine which backend implementation to install for each platform.

Platform Local Environment Server Environment
XiaoHongShu Installs OpenCLI (reuses desktop Chrome session) Recommends xiaohongshu-mcp binary with QR-login guide
Reddit Prefers OpenCLI; falls back to existing rdt-cli Installs rdt-cli (pure CLI without UI requirements)
General Browser-based tools assuming graphical environment Self-contained binaries or pure CLI tools

Reddit Installation Logic

The branching logic for Reddit dependencies (lines 778-892 in cli.py) demonstrates this pattern:

def _install_reddit_deps():
    """Set up Reddit — desktop prefers OpenCLI, rdt-cli for servers/legacy."""
    if _detect_environment() != "server":
        _install_opencli_deps()
        print("  Reddit 走 OpenCLI(浏览器里登录过 reddit.com 即可用)")
        # ... optionally use rdt‑cli if already present ...

        return

    _install_rdt_cli()

This ensures that desktop users get the browser-integrated OpenCLI experience while server deployments receive the headless-compatible rdt-cli tool.

Understanding the Threshold Logic

The function returns "server" only when indicators >= 2. This threshold-based design intentionally weights strong signals (SSH, containers, cloud VMs) at 2 points each, while weak signals (missing display, virtualization) contribute only 1 point.

This prevents false positives where a desktop workstation might lack a DISPLAY variable but isn't actually a server. Conversely, a Docker container automatically scores 2 points, immediately triggering server mode regardless of other factors.

Testing Environment Detection

The test suite in tests/test_cli.py (lines 88-100) verifies this branching behavior by mocking the environment detection function:


# Simulating a server environment in a test (see tests/test_cli.py)

def test_install_reddit_deps_routes_by_environment(monkeypatch):
    monkeypatch.setattr(cli, "_detect_environment", lambda: "local")
    # ...assert OpenCLI path...

    monkeypatch.setattr(cli, "_detect_environment", lambda: "server")
    # ...assert rdt‑cli path...

You can manually verify your current environment using:

from agent_reach.cli import _detect_environment
print(_detect_environment())  # Outputs: 'local' or 'server'

Summary

  • Multi-factor detection: Agent Reach evaluates SSH sessions, container files, display variables, cloud VM signatures, and virtualization status to determine the environment type.
  • Weighted scoring: Strong indicators (SSH, containers, cloud VMs) contribute 2 points; weak indicators (missing display, virtualization) contribute 1 point.
  • Threshold decision: The environment is classified as "server" only when the cumulative score reaches 2 or higher.
  • Backend routing: Local environments receive browser-based tools like OpenCLI, while server environments get pure CLI binaries like rdt-cli or xiaohongshu-mcp.
  • Implementation location: All detection logic resides in agent_reach/cli.py (lines 955-994), with platform-specific installation branching throughout the same file.

Frequently Asked Questions

How does Agent Reach detect if it's running on a server?

Agent Reach checks five OS-level indicators in agent_reach/cli.py: SSH environment variables, Docker/container files, display server availability, cloud VM hardware signatures, and virtualization status via systemd-detect-virt. Each indicator carries a weighted score, and the function returns "server" when the total reaches 2 or more points.

What happens if Agent Reach incorrectly detects my environment?

If detection fails, the tool defaults to "local" mode (since the threshold requires >= 2 points to trigger server mode). However, this may cause installation failures when attempting to launch browser-based tools like OpenCLI on headless systems. You can verify the detection by importing _detect_environment() from agent_reach.cli and checking the return value.

Can I override the automatic environment detection in Agent Reach?

While the source code in agent_reach/cli.py shows that installation functions directly call _detect_environment(), the test suite demonstrates that you can monkeypatch this function for custom behavior. For production deployments, ensure your environment presents sufficient server indicators (such as running inside Docker) to trigger automatic server mode.

Why does Agent Reach use different backends for Reddit on local vs server?

OpenCLI requires a graphical browser environment to reuse existing Chrome sessions, making it ideal for local desktops but incompatible with headless servers. rdt-cli operates as a pure CLI tool without UI dependencies, ensuring Reddit functionality remains available in SSH sessions or containerized deployments where no display server exists.

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 →