# How orx up Starts the Local Dashboard and API in OpenResearch

> Discover how orx up starts the local dashboard and API in OpenResearch. Learn about TCP listeners, LLM hosts, and Axum HTTP servers for seamless operation.

- Repository: [alphaXiv/OpenResearch](https://github.com/alphaXiv/OpenResearch)
- Tags: how-to-guide
- Published: 2026-09-13

---

**`orx up` launches the autogressive research dashboard by binding a local TCP listener, hydrating SQLite state, spawning LLM agent hosts, and starting an Axum HTTP server that serves both the single-page web app and JSON API.**

The `orx up` command is the primary entry point for the alphaXiv/OpenResearch repository, transforming your local machine into a fully functional research environment. When invoked, it orchestrates a complex initialization sequence defined in [`src/commands/up.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/commands/up.rs), culminating in a web-based dashboard accessible at `http://127.0.0.1:4791`. This article traces the exact execution path from CLI argument parsing through graceful shutdown, referencing the specific functions and line numbers that handle each phase.

## Command Dispatch and Entry Point

The journey begins in [`src/main.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/main.rs), where the CLI dispatcher matches the `up` subcommand and delegates to the command handler. At line 1071, the dispatcher executes:

```rust
Command::Up(args) => commands::up::run(args).await

```

This invokes `commands::up::run` with an `UpArgs` struct containing the user-supplied port, `--no-browser` flag, and optional `--remote` host configuration. The `run` function in [`src/commands/up.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/commands/up.rs) immediately begins the twelve-step initialization process that prepares the runtime environment.

## Port Acquisition and DashboardLock

Before spawning network services, `orx up` ensures exclusive access to the target port using a `DashboardLock`. The lock guarantees that only one instance may bind the chosen port, preventing port collisions between multiple OpenResearch processes.

**Shared vs. Exclusive Locks:** In standard local mode, the lock operates in **shared** mode, allowing inspection but preventing duplicate servers. When `--remote` is specified, the lock becomes **exclusive**, ensuring the remote control server has sole authority over the port.

The binding logic at lines 65-73 in [`src/commands/up.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/commands/up.rs) attempts `tokio::net::TcpListener::bind` on `127.0.0.1:<port>`. If the address is already in use, the command probes the existing instance with `dashboard_is_serving`. If the dashboard responds, `orx up` simply opens the existing URL in the browser and exits gracefully rather than failing with an error.

## State Hydration and Store Recovery

With the port secured, the command initializes persistent storage. At lines 84-93, `Store::open()` creates or connects to the local SQLite database, reconciles any unfinished chat turns from previous sessions, and re-spawns supervisors for runs that were active when the previous instance crashed. This recovery mechanism ensures that long-running research tasks resume automatically after a restart.

## Agent Host Initialization

The dashboard requires three distinct LLM interfaces to function. At lines 98-102, `orx up` initializes:

- **AgentHost**: The generic LLM interface for general queries
- **CodexHost**: Specialized handler for code generation tasks  
- **ClaudeHost**: Anthropic Claude integration, which also spawns a background reaper thread for resource management

These hosts are wrapped in an `Arc<AppState>` (lines 104-119), making them accessible to every HTTP route handler via Axum’s state middleware.

## HTTP Server Construction with Axum

The core API surface is built at lines 225-298 in the `router` function. This constructs an Axum application registering over 150 REST endpoints under `/api/*`, a Server-Sent Events (SSE) stream at `/api/events` for live updates, and a SPA fallback that serves [`index.html`](https://github.com/alphaXiv/OpenResearch/blob/main/index.html) for all root paths.

### Middleware and Security Layers

The router is layered with two critical middlewares:

1. **loopback_guard**: Prevents accidental exposure when running via `--remote` by restricting access to local interfaces
2. **require_remote_auth**: Enforces bearer token validation when remote authentication is configured

### Remote Control Server

If the `--remote` flag is provided, `orx up` spawns an additional control server (lines 163-181). This component advertises the instance ID and dashboard protocol version, handling SSH-tunneled remote-session authentication through the logic defined in [`src/commands/up_remote.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/commands/up_remote.rs).

## Background Maintenance Tasks

Before starting the HTTP listener, `orx up` spawns four concurrent background tasks (lines 124-154):

- **Chat Lease Reaper**: Periodically reconciles expired chat-turn leases to prevent resource leaks
- **Agent Preflight**: Validates local toolchain availability via `spawn_agent_preflight()`
- **Claude Auth Monitor**: Watches the Claude authentication token for expiration
- **Update Checker**: Polls for new releases (disabled in remote mode) via `spawn_background_tasks`

These tasks run on Tokio’s runtime alongside the main server, ensuring the environment remains healthy without blocking request handling.

## Startup Completion and Browser Launch

With the Axum router built and background tasks running, `orx up` prints the dashboard URL to stderr (lines 87-97):

```bash
orx up: dashboard on http://127.0.0.1:4791

```

Unless the `--no-browser` flag is set, the command invokes `browser::open_browser(&url)` (defined in [`src/browser.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/browser.rs)), which uses platform-specific binaries—`open` on macOS, `start` on Windows, or `xdg-open` on Linux—to launch the default browser automatically.

## Running and Graceful Shutdown

The server enters its main execution loop at line 1089 with `axum::serve(listener, app)`, wrapped in a Tokio `select!` block that listens for termination signals (`Ctrl-C`, `SIGTERM`, `SIGHUP`). In remote mode, an additional `stop_rx` channel allows the control server to request early shutdown.

When a shutdown signal is received, the cleanup routine (lines 1290-1444) executes:

1. Shuts down the chat host and all agent instances
2. Terminates the remote-session manager
3. Removes the `DashboardLock` file
4. If a background update was installed, invokes `updates::relaunch` to restart the binary with the new version

## Practical Usage Examples

### Standard Local Launch

Start the dashboard on the default port (4791) with automatic browser opening:

```bash
orx up

```

This executes the full initialization sequence, binds to `127.0.0.1:4791`, and opens `http://127.0.0.1:4791`.

### Headless Server Mode

Run the API without launching a browser window:

```bash
orx up --no-browser

```

The server starts identically, but skips the `browser::open_browser` call at line 95.

### Remote SSH Access

Expose the dashboard securely over SSH:

```bash
orx up --remote user@my-server

```

This enables exclusive lock mode and starts the control server, requiring bearer token authentication for all API requests.

### Custom Port Binding

Override the default port to avoid conflicts:

```bash
orx up --port 8080

```

The listener binds to `127.0.0.1:8080` and the startup message reflects the custom endpoint.

## Summary

- **`orx up`** is dispatched from [`src/main.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/main.rs) to [`src/commands/up.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/commands/up.rs), where the `run` function orchestrates initialization
- **DashboardLock** prevents port collisions using shared or exclusive modes depending on local vs. remote operation
- **Store::open()** recovers SQLite state and resumes interrupted research runs automatically
- Three agent hosts (**AgentHost**, **CodexHost**, **ClaudeHost**) provide LLM capabilities to the dashboard
- An **Axum** router serves 150+ endpoints with **loopback_guard** and **require_remote_auth** middleware
- Background tasks handle lease reaping, preflight checks, and update monitoring without blocking the main thread
- **Graceful shutdown** (lines 1290-1444) ensures all agents, stores, and locks are properly released before exit

## Frequently Asked Questions

### What happens if the default port is already in use when running orx up?

If `127.0.0.1:4791` is occupied, the command probes the existing process with `dashboard_is_serving`. If the existing dashboard responds, `orx up` opens that URL in your browser and exits successfully. If the port is occupied by a non-OpenResearch service, the `TcpListener::bind` call fails with an error.

### How does orx up handle remote access security?

When invoked with `--remote`, the command activates **exclusive** lock mode and spawns a control server. The router middleware `require_remote_auth` enforces bearer token validation on all API routes. Additionally, `loopback_guard` prevents the dashboard from accidentally binding to public interfaces, ensuring access is only possible through the intended SSH tunnel.

### What is the difference between shared and exclusive DashboardLock modes?

**Shared** mode allows multiple `orx up` processes to start as long as they do not attempt to bind the same port, useful for local development. **Exclusive** mode (enabled via `--remote`) guarantees that only one instance controls the port, preventing race conditions when managing remote sessions through the control server defined in [`src/commands/up_remote.rs`](https://github.com/alphaXiv/OpenResearch/blob/main/src/commands/up_remote.rs).

### How does the graceful shutdown process work?

Upon receiving `SIGINT`, `SIGTERM`, or `SIGHUP`, the `select!` block at line 1089 breaks, triggering the cleanup section at lines 1290-1444. This sequence stops the chat host, terminates all LLM agents, closes the remote-session manager, deletes the lock file, and optionally relaunches the binary if an update was installed during the session.