Skip to main content
This guide shows how to run the OpenHands V1 app-server while spawning a fully local agent-server process (no Docker, no remote runtime).
Applies to the V1 app-server path enabled under /api/v1.

Prerequisites

  • Python 3.12, Node 22.x, Poetry 1.8+
  • OpenHands repository checked out
  • software-agent-sdk is an install-time dependency of OpenHands (see pyproject.toml), and provides the openhands.agent_server entrypoint

Where V1 Lives (Execution Path Overview)

OpenHands V1 exposes its API under /api/v1 and keeps the V1 server logic in app_server/:
  • The FastAPI app includes V1 only when ENABLE_V1 != “0”. See server/app.py.
  • The V1 router aggregates app_server endpoints. See v1_router.py.
  • For a local runtime, the app-server launches a separate agent-server process (from software-agent-sdk) on a free localhost port via the process sandbox: process_sandbox_service. It executes python -m openhands.agent_server and probes /alive.
  • This selection comes from env→config wiring. When RUNTIME is local or process, injectors select the process-based sandbox/spec: see app_server/config.py and process_sandbox_spec_service.py.
  • On the SDK side, the agent-server exposes /alive and /health (and /api/*). See server_details_router.py and bootstrap in agent_server/main.py.
  • The app-server talks to the agent-server using AsyncRemoteWorkspace and the agent-server REST/WebSocket API. See AsyncRemoteWorkspace and where the app-server builds conversation requests in _build_start_conversation_request_for_user (source).

Run App-Server with a Local Agent-Server

1) Build OpenHands and Enable V1

By default V1 is enabled (unless ENABLE_V1=0). Ensure you’re on Python 3.12 and have Poetry and Node installed, then:
Build
export INSTALL_DOCKER=0         # No Docker for this guide
export RUNTIME=process            # Force process-based sandbox (spawns sub-process agent-server)
# optional: export ENABLE_V1=1  # V1 is enabled by default; set explicitly if you disabled it elsewhere

make build

2) Run Backend and Frontend

For local development, either run everything together or separately.
Full App (Backend + Frontend)
# Adjust ports/hosts if you’re on a remote machine.
make run FRONTEND_PORT=12000 FRONTEND_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0
or start servers individually:
Separate Servers
make start-backend
make start-frontend

3) Start a V1 Conversation (Spawns Local Agent-Server)

From the UI (Chat → Start) or via the V1 endpoints under /api/v1, create a new conversation. The app-server will:
  • Start a sandbox using the process sandbox service, which launches a local agent-server process via python -m openhands.agent_server
  • Poll the agent-server /alive endpoint until it reports status ok
  • Store the agent-server URL and a per-sandbox session API key, then reuse it for subsequent operations

4) Verify the Local Agent-Server

You can list sandboxes via V1 API and find the exposed agent-server URL; the name in the response is “agent-server”. The health checks are:
  • GET {agent_server_url}/alive{"status":"ok"} (see server_details_router.py)
  • GET {agent_server_url}/server_info for uptime/idle info

5) How the App-Server Talks to the Agent-Server

When reading/writing files or executing commands in the conversation’s workspace, the app-server uses AsyncRemoteWorkspace that targets the agent-server. Example usage: app_conversation_router.read_conversation_file and throughout live_status_app_conversation_service.

Customize the Agent Loaded by the GUI

For customization paths (skills/MCP, agent presets, or defining a new Agent type the app can instantiate), see:
  • /sdk/guides/agent-server/app-integration
  • /sdk/guides/agent-custom
  • /sdk/guides/custom-tools

Troubleshooting

  • If no agent-server starts when you create a V1 conversation, ensure:
  • To inspect the agent-server API, open its Swagger at {agent_server_url}/docs (the server is started via uvicorn in main.py).

References