How Agent Reach Auto-Detects Local Computer vs Server Environment

Agent Reach determines its execution context by evaluating environment variables, CI indicators, TTY attachment, and filesystem writability in agent_reach/utils/paths.py, caching the result to adapt behavior for interactive workstations versus headless servers.

Agent Reach is an open-source automation framework that must distinguish between a developer's local laptop and a remote CI/CD server to adjust its output and safety checks accordingly. The project implements a robust auto-detection mechanism that requires no manual configuration and is centralized in a single utility function consumed across the CLI, diagnostics, and configuration modules.

The Four-Step Detection Logic in is_server()

The core detection routine lives in agent_reach/utils/paths.py inside the is_server() function. This helper returns a boolean indicating whether the current process is running in a non-interactive server environment by executing four sequential checks.

1. Explicit Environment Variable Override

The function first looks for an explicit hint via the AGENT_REACH_ENV variable. When set to "server", the function immediately returns True; when set to "local", it returns False. This allows operators to force a specific mode regardless of other system indicators.


# agent_reach/utils/paths.py

def is_server() -> bool:
    env = os.getenv("AGENT_REACH_ENV", "").lower()
    if env in ("server", "local"):
        return env == "server"
    # ... additional checks

2. CI Environment Detection

If no override is present, the code scans for common CI-specific variables. The presence of any of the following environment variables forces server mode: CI, GITHUB_ACTIONS, GITLAB_CI, or TRAVIS.

    ci_vars = ("CI", "GITHUB_ACTIONS", "GITLAB_CI", "TRAVIS")
    if any(os.getenv(v) for v in ci_vars):
        return True

3. Interactive TTY Fallback

When CI variables are absent, the function checks for an attached terminal using sys.stdin.isatty(). A true value indicates an interactive shell, signaling a local environment; otherwise, the code assumes it is running headless.

    if sys.stdin.isatty():
        return False

4. Config Directory Writability Test

As a final safety net, the routine attempts to write to the user-specific configuration directory at ~/.agent-reach. Failure to create or access this directory (common in read-only CI containers) is interpreted as evidence of a server environment.

    try:
        Config()._ensure_dir()
        return False
    except OSError:
        return True

Where Detection Drives Behavior

The result of is_server() is cached in Config.is_server and consulted throughout the codebase to conditionally enable features.

CLI Output Adjustments

In agent_reach/cli.py, the detection suppresses interactive elements like progress bars and colorized output when running on a server.


# agent_reach/cli.py

from .utils.paths import is_server

def main():
    if is_server():
        logger.info("Running in head-less/server mode")
    else:
        logger.info("Running on a local workstation")

Doctor Diagnostics

The diagnostics command in agent_reach/doctor.py reports the detected mode to help users verify their environment setup.


# agent_reach/doctor.py

from .utils.paths import is_server

def run():
    env = "server" if is_server() else "local"
    print(f"Environment detected: {env}")

Credential Safety Guards

In agent_reach/config.py, the detection prevents accidental credential storage on shared servers by refusing to write sensitive keys when is_server() returns True.


# agent_reach/config.py

from .utils.paths import is_server

def set(self, key: str, value: Any):
    if is_server() and key.lower().endswith(("token", "key")):
        raise RuntimeError("Refusing to store credentials on a non-interactive server")
    self.data[key] = value
    self.save()

Summary

  • Centralized logic: The is_server() function in agent_reach/utils/paths.py encapsulates all environment detection logic.
  • Four-layer checks: Detection prioritizes the AGENT_REACH_ENV variable, then CI environment variables, then TTY attachment, and finally config directory writability.
  • Automatic adaptation: The CLI, doctor, and config modules consume this detection to adjust output styling, diagnostic reporting, and security policies without user intervention.

Frequently Asked Questions

How can I force Agent Reach to run in server mode on my local machine?

Set the AGENT_REACH_ENV environment variable to "server" before executing any command. This override bypasses TTY and CI checks, ensuring the framework behaves as if it were running in a headless environment.

Which CI platforms does Agent Reach automatically recognize?

Agent Reach detects CI, GITHUB_ACTIONS, GITLAB_CI, and TRAVIS. If any of these variables are present in the environment, the framework automatically switches to server mode, disabling interactive prompts and colorized logging.

Why does Agent Reach check if the config directory is writable?

Many CI/CD containers run with read-only filesystems or without a home directory. By attempting to write to ~/.agent-reach, Agent Reach can reliably distinguish between a developer's writable local workstation and a restricted server environment where persistent configuration should be avoided.

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 →