Local vs Server Environment Detection in Agent Reach: How It Works
Agent Reach distinguishes between local desktop and headless server environments using a multi-signal scoring system in agent_reach/cli.py to automatically select the appropriate backend for each platform.
The Agent Reach repository (Panniantong/Agent-Reach) provides intelligent CLI automation for social media platforms, but it must adapt its behavior depending on whether it runs on a developer's laptop or a remote server. Understanding how local and server environment detection works in Agent Reach is crucial for debugging installation issues and predicting which backends the tool will provision.
How Environment Detection Works
The core detection logic resides in the private helper _detect_environment() inside agent_reach/cli.py (lines 955–994). This function aggregates multiple OS-level indicators and returns either "local" or "server" based on a weighted scoring threshold.
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"
Detection Signals and Scoring
The function checks five distinct signals, each assigned a weight reflecting its reliability:
- SSH sessions (
SSH_CONNECTIONorSSH_CLIENTenvironment variables): Adds 2 points — a strong indicator of remote server access. - Container environments (
/.dockerenvor/run/.containerenv): Adds 2 points — unambiguous proof of containerized deployment. - Headless display (missing
DISPLAYorWAYLAND_DISPLAY): Adds 1 point — suggests no GUI, but alone could indicate a minimal desktop setup. - Cloud VM identifiers (reading
/sys/hypervisor/uuidor/sys/class/dmi/id/product_namefor Amazon, Google, Microsoft, DigitalOcean, etc.): Adds 2 points — confirms virtualized cloud infrastructure. - Virtualization detection (
systemd-detect-virtreturning non-"none"): Adds 1 point — catches virtual machines not explicitly identified by cloud files.
Platform-Specific Backend Selection
Agent Reach uses the environment string to choose between graphical browser-based backends (for local) and headless CLI binaries (for server).
| Platform | Local Environment | Server Environment |
|---|---|---|
| XiaoHongShu (xhs) | Installs OpenCLI, reusing the user's existing Chrome session. | Recommends the xiaohongshu-mcp binary and provides QR-login guidance. |
Prefers OpenCLI; falls back to existing rdt-cli if present. |
Installs rdt-cli, a pure-CLI backend that operates without UI requirements. | |
| Standard CLI operation; assumes graphical environment available. | Standard CLI operation, but requires manual headless configuration (e.g., proxies). |
Reddit Installation Logic Example
The conditional routing is implemented in cli.py (lines 778–892). When installing Reddit dependencies, the code explicitly branches based on the detection result:
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()
Why the Threshold Is Set to ≥2
The function returns "server" only when the indicator sum reaches two or more. This conservative threshold prevents false positives:
- Strong signals (SSH, containers, cloud VMs) each contribute 2 points, immediately triggering server mode.
- Weak signals (missing display, virtualization) contribute only 1 point, requiring combination with another signal to classify as server.
Therefore, a desktop workstation running without a GUI but without SSH or containerization remains classified as local, while a Docker container or EC2 instance is correctly identified as server.
Practical Code Examples
You can invoke the detection directly from your Python code to verify the current environment:
# Quick check from the CLI
>>> from agent_reach.cli import _detect_environment
>>> _detect_environment()
'local' # on my laptop
For testing environment-specific logic, the test suite in tests/test_cli.py (lines 88–100) demonstrates how to mock the 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...
Summary
- Local environments trigger installation of OpenCLI and browser-based backends that require a graphical session.
- Server environments trigger installation of headless binaries like
rdt-cliandxiaohongshu-mcpthat function without UI dependencies. - The detection logic in
agent_reach/cli.pyuses a weighted scoring system (≥2 points) checking SSH variables, container files, display environment variables, cloud VM metadata, and systemd virtualization. - Key files involved include
agent_reach/cli.pyfor detection logic,tests/test_cli.pyfor validation, andagent_reach/backends/opencli.pyfor the desktop-only backend implementation.
Frequently Asked Questions
How does Agent Reach detect if it is running on a server?
Agent Reach checks five OS-level indicators in _detect_environment(): SSH environment variables, Docker/container files, display server variables (DISPLAY/WAYLAND_DISPLAY), cloud provider metadata in /sys/, and systemd-detect-virt output. Each indicator carries a weight of 1 or 2 points, and reaching a total of 2 or more points classifies the environment as "server".
Why does my headless desktop still show as "local"?
A single weak signal (such as missing DISPLAY or WAYLAND_DISPLAY variables) only adds 1 point to the score. The threshold requires ≥2 points to trigger server mode. Since headless workstations typically lack SSH sessions, containers, or cloud VM signatures, they remain classified as local unless multiple indicators are present.
What backends are installed on servers versus local machines?
On local machines, Agent Reach installs OpenCLI for Reddit and XiaoHongShu, which leverages the user's existing Chrome browser session. On servers, it installs pure CLI alternatives like rdt-cli for Reddit and xiaohongshu-mcp for XiaoHongShu, ensuring functionality without graphical dependencies.
Can I override the environment detection manually?
While the source code in agent_reach/cli.py does not expose a public override flag, you can manipulate the underlying indicators (such as setting SSH_CONNECTION or creating /.dockerenv) to influence the scoring, or patch the _detect_environment() function in tests using monkeypatch as demonstrated in tests/test_cli.py.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →