# How Agent Reach Auto-Detects Local Computer vs Server Environment

> Agent Reach auto-detects your environment by checking variables, TTY, and writability. Learn how this intelligently adapts behavior for workstations and servers.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-06-26

---

**Agent Reach determines its execution context by evaluating environment variables, CI indicators, TTY attachment, and filesystem writability in [`agent_reach/utils/paths.py`](https://github.com/Panniantong/Agent-Reach/blob/main/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`](https://github.com/Panniantong/Agent-Reach/blob/main/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.

```python

# 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`.

```python
    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.

```python
    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.

```python
    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`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py)**, the detection suppresses interactive elements like progress bars and colorized output when running on a server.

```python

# 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`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py)** reports the detected mode to help users verify their environment setup.

```python

# 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`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py)**, the detection prevents accidental credential storage on shared servers by refusing to write sensitive keys when `is_server()` returns `True`.

```python

# 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`](https://github.com/Panniantong/Agent-Reach/blob/main/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.