OpAgent Web is a small, product-neutral workspace surface embedded in
opagent-server. It gives a developer one focused browser tab with a read-only
file explorer, text preview, model connection settings, and streamed Agent
conversation. Runtime thread JSONL remains the only conversation store.
From the repository root:
scripts/start-web.shThe script opens ${baseDir}/workspace and launches the default browser. With
the standalone default base directory, this is ~/.opagent/workspace. The
directory is created automatically. The process working directory is never
used as an implicit Workspace.
Pass another Server-local directory as the first argument when needed:
scripts/start-web.sh /absolute/path/to/projectThe equivalent command for the default Workspace is:
go run ./opagent-server/cmd/opagent-server --openAn explicit Workspace uses:
go run ./opagent-server/cmd/opagent-server --workspace /absolute/path/to/project --openThe Server remains loopback-only at 127.0.0.1:19531. Its standalone state is
under ~/.opagent unless OPAGENT_BASE_DIR is set.
The URL contains a Workspace ID and each browser tab binds to exactly one Server-owned directory. Choosing Open workspace registers another directory with the running Server and opens it in a new tab. It does not silently retarget the current conversation or file tree.
The file explorer and preview API are intentionally read-only:
- directory browsing is lazy and bounded;
- text files up to 2 MiB can be previewed;
- binary files, path traversal, and symlinks escaping the Workspace are rejected;
- roots that contain Runtime state such as
~/.opagentare rejected; - direct browser controls for edit, upload, delete, rename, terminal, and git are absent; the Agent can still perform Workspace work through Runtime tools.
The command enables dynamic Workspace opening. Embedders must opt in with
server.Options.AllowWorkspaceOpen; otherwise only the Workspaces passed in
server.Options.Workspaces are visible.
Open Models and configure:
- provider key and display name;
- API type: OpenAI Responses, OpenAI-compatible Chat Completions, Anthropic Messages, or Gemini native;
- HTTP(S) Base URL;
- API Token;
- provider Model ID.
The Server atomically writes schema-v6
<baseDir>/configs/user/models.json with mode 0600 and reloads Runtime model
configuration synchronously. Read APIs return only hasAPIToken; they never
return the Token itself. Leaving the Token field blank while updating the same
model preserves the existing value.
The bundled agent-web uses Runtime's read, write, edit, and shell
tools. Web thread creation explicitly trusts the selected Workspace and selects
the full permission profile, including host-file and internet access, before
capturing the thread permission snapshot. This is a local developer default:
the connection Token holder can operate the Workspace as the Server process
user, while the browser's file explorer and preview endpoints remain read-only.
The connection screen accepts a Server URL and the capability stored at
<baseDir>/run/local-connection-token. The connection Token is kept in
sessionStorage for the current origin and browser-tab session. Model API
Tokens are never placed in browser storage.
For remote use, keep the remote Server on loopback and forward its port:
ssh -N -L 29531:127.0.0.1:19531 user@remote-hostThen open http://127.0.0.1:29531/web/ and enter the remote Server's connection
Token. All file and chat requests now run on that remote machine through the
forwarded Server. The Web client does not store SSH keys, start SSH itself, or
turn the generic Server into an Internet-facing service.
Static Web assets are public so the connection screen can load. Every config,
Workspace, file, thread, and chat endpoint still requires
X-OpAgent-Connection-Token. The Web assets use a restrictive Content Security
Policy, no third-party scripts, no inline executable code, and no external
fonts or analytics.
The connection Token is a local capability, not multi-user authentication. Anyone who has it can operate the registered Workspaces and Runtime as the Server process user. Keep the listener on loopback and use a trusted encrypted tunnel for remote access.