Web UI
The AgentOS Web UI is the local control console for setup, chat sessions, approvals, channels, logs, agents, usage, and operational status. It is the best surface when you want browser-based chat, visible tool activity, durable approvals, and a quick view of runtime health.
Start the Web UI
Run the gateway in the foreground:
agentos gateway run
Open:
http://127.0.0.1:18791/control/
Or start a managed background gateway:
agentos gateway start --json
agentos gateway status
The default gateway binds to 127.0.0.1 for safety.
For gateway lifecycle, host/port, and exposure details, see Gateway.
React bundle and development
Published AgentOS wheels contain a prebuilt React/Vite Control UI. The gateway serves that single application for the base route and every deep link; there is no legacy-console fallback. The SPA shell is never cached, while content-hashed assets are cached immutably.
A source checkout must build the browser bundle before starting the production gateway:
python scripts/build_control_ui.py build
npm --prefix frontend run check
The shared build command requires Node.js 22 or newer, performs the clean npm
install, builds and verifies the bundle, and generates its exact third-party
license ledger. The source-install scripts perform it automatically. If a
checkout is started without a bundle, the Control UI returns an actionable
503 instead of a blank page or a different interface.
Gateway boot and agentos doctor also warn when a checkout's bundle is older
than its frontend sources (gateway.control_ui.dist_stale). The warning is
advisory: it never blocks serving the existing bundle and never degrades
overall health status, because source mtimes are a hint rather than an oracle —
git checkout and git pull rewrite them, so a freshly built bundle can be
flagged. Rebuild with python scripts/build_control_ui.py build; agentos doctor clears on the next run, and a gateway restart clears the boot-time log
line. Wheel installs ship no frontend sources and are never flagged, and the
check is skipped entirely when the Control UI is disabled.
For hot reload during frontend work, run the gateway and Vite together:
agentos gateway run
npm --prefix frontend run dev
Vite serves /control/ and proxies the gateway API and WebSocket. Production
builds use relative assets plus a server-provided runtime base, so custom
non-root mounts such as /console/ work without rebuilding. Root, /api, and
/ws mounts are rejected because they overlap the gateway's public endpoints.
Main Areas
| Area | Use it for |
|---|---|
| Chat | Run and resume chat sessions, inspect tool activity, publish artifacts, and use manual compact controls. |
| Projects | Group chat sessions, edit each project's shared knowledge (injected into every member session), and start new chats inside a project. |
| Overview / Health | See readiness, provider state, memory state, sandbox posture, and recovery hints. |
| Channels | Inspect configured channel adapter status and jump to Agent Setup for configuration changes. |
| Skills | Browse installed skills grouped by where they came from, see whether the agent is actually being offered each one, and install more from a hub. |
| Sessions | Inspect durable conversations and operational state. |
| Agents | Manage durable agent entries. |
| Usage | Inspect token and estimated-cost rollups. |
| Cron | View and manage scheduled runs. |
| MCP Servers | Add local or remote MCP servers, connect tools live, and complete OAuth authorization. |
| Agent Setup | Configure the agent through Guided capability setup or the complete Advanced Form/YAML editor. |
| Environment | Set, replace, and remove the environment variables skills and providers read. |
| Logs | Inspect runtime logs and diagnostics. |
| Approvals | Respond to sensitive tool-call approval requests. |
Keyboard Shortcuts
The Web UI features a comprehensive set of keyboard shortcuts to facilitate mouse-free navigation and control. Press ? (Shift + / on US keyboards) from any page to open the keyboard shortcuts cheat sheet.
Global & Chat Shortcuts
?- Show/hide the keyboard shortcuts cheat sheet.Cmd+Shift+O(macOS) /Ctrl+Shift+O(Windows/Linux) - Start a new chat session.Escape- Abort the active streaming turn, else recover the queue into the composer.
Sidebar Navigation Chords
The Web UI supports two-step chords (Gmail/GitHub style) to switch between sidebar views. Press g followed by a destination letter/key within 1.5 seconds to navigate:
gthenc- Go to Chatgtheno- Go to Overviewgthenh- Go to Healthgthenn- Go to Channelsgthenm- Go to MCP Serversgthenk- Go to Skillsgthenj- Go to Projectsgthens- Go to Sessionsgthena- Go to Agentsgthenu- Go to Usagegthenr- Go to Crongthen,- Go to Agent Setupgthene- Go to Environmentgthenl- Go to Logsgthenp- Go to Approvals
[!NOTE] Keyboard shortcuts are automatically suppressed while focus is inside a text input field, textarea, or content-editable region, and while modal dialogs or overlays are open.
Agent Setup
Open Settings > Agent Setup, or go directly to:
http://127.0.0.1:18791/control/settings
The workspace has two modes:
- Guided configures the provider, Pilot Router, channels, search, memory, image generation, audio, and readiness through the specialized onboarding operations for each capability.
- Advanced exposes Form and YAML editors for the complete current gateway
configuration. Form mode groups every current
GatewayConfigkey, keeps an Other section for future keys, searches across all sections, supports keyboard tab navigation, and provides accessible show/hide controls for sensitive inputs.
The workspace uses one redacted config.snapshot composite for a coherent view
of the catalog, readiness, active configuration, revision, persistence target,
restart state, and runtime/disk coherence. Writes still use the narrowly scoped
onboarding operations or config.patch / config.apply; the snapshot itself is
read-only. A legacy gateway fallback is used only when config.snapshot is not
implemented, not when the snapshot call fails or returns an invalid payload.
Existing bookmarks remain valid: /control/setup opens Guided mode and
/control/config opens Advanced mode. Both are compatibility paths into the
same Agent Setup workspace, not separate sidebar destinations. Guided and
Advanced stay mounted while you switch between them so in-progress drafts are
not discarded merely by changing modes.
Configuration write safety
Guided and Advanced are two editors for the same persisted configuration. Each
write carries the snapshot revision as expectedRevision when available. If
another editor advances that revision while a local draft is open, Save is
disabled until the stale draft is explicitly discarded and the latest snapshot
is loaded. A one-time secret is cleared from the saved form immediately after a
successful write, even when the follow-up refresh cannot complete.
Gateway configuration writes are persist-first transactions:
- validate a cloned candidate configuration;
- verify
expectedRevisionand the live/disk coherence state; - atomically persist the candidate;
- update the running configuration;
- hot-apply the adapters that support it.
If persistence fails, the running configuration and runtime adapters remain unchanged. If persistence succeeds but a hot-apply adapter fails, the persisted configuration remains authoritative and the gateway records a pending restart reason instead of reporting the change as fully live.
An external edit to the active config file is fail-closed. In that state,
config.snapshot returns revision: null, diskDiverged: true, and
writeBlocked: true; Agent Setup shows Out of sync and disables both Guided
and Advanced writes. Reload or restart the gateway with that file before
editing again. Refreshing only the browser cannot reconcile a stale running
configuration.
host, port, config_path, auth.token, and auth.password are display-only
in Advanced. The WebSocket config mutation RPCs reject attempts to retarget the
active config file or replace runtime-owned authentication credentials. Other
authentication settings, such as auth.mode, remain editable and may require a
gateway restart — auth.mode accepts only none, token, or trusted-proxy,
and any other value is rejected by the mutation RPC rather than saved.
Restart reporting is deliberately conservative. Mutation responses expose
restartRequired; subsequent snapshots expose cumulative pendingRestart and
restartReasons for boot-captured settings and failed hot applies. This covers
areas such as memory, channels, sandbox/bind posture, task runtime, server
middleware, MCP discovery, tools/skills loading, state paths, heartbeat, and
diagnostics. Treat a restart advisory as part of completing the change rather
than as a save failure.
Chat Sessions
The chat UI supports:
- streaming assistant output;
- live model reasoning ("thinking") as a collapsible block;
- tool-call cards;
- artifact cards;
- pending message queue behavior while compaction or runtime work is in flight;
- manual
/compact; - per-turn usage and savings metadata when available;
- copyable session keys.
Use the session selector to switch between existing sessions. Copy the session key when reporting a bug or asking another AgentOS surface to inspect the same session.
Model reasoning (thinking)
When the routed model streams reasoning (Anthropic thinking blocks, DeepSeek
reasoning_content, or local <think> models), the WebUI shows it live in a
collapsible block that folds away as soon as the reply text starts. Replies
whose reasoning was persisted show a collapsed Thinking block in history;
the reasoning body loads on first expand (it is not shipped with history
pages).
Turn it off with control_ui.show_thinking = false (or
AGENTOS_CONTROL_UI_SHOW_THINKING=false) — the gateway then neither streams
thinking events nor serves reasoning bodies. This is WebUI-only either way:
channel adapters (Slack, Telegram, …) never receive thinking.
Plan mode
Flip Plan mode in the run-modes popover (or type /plan) to make the
session research-only: the agent keeps its read, search, and analysis tools
but every mutating tool is withheld until you approve a plan. When the agent
finishes planning it calls exit_plan_mode, its turn ends, and the chat
shows the plan in a card with an Approve plan button. Approving turns
plan mode off and sends the go-ahead; typing feedback instead keeps plan
mode on and refines the plan. Plan mode is per-session and lives in gateway
memory — a gateway restart clears it.
Agent questions (ask_user)
When the agent needs a decision that is genuinely yours — scope, a
hard-to-reverse action, conflicting instructions — it can call the ask_user
tool. The chat renders a question card with clickable options (plus a
free-text field); picking an answer sends it as your next message and the
agent continues from there. Asking ends the agent's turn, so nothing blocks
while you decide, and typing a reply in the composer works exactly the same
as clicking the card.
Manual Compaction
Long sessions can be compacted from chat. If no compaction is needed, the UI reports:
Already within context budget; no compact was applied
If compaction is running, wait for its terminal state before assuming the next message has the compacted context. See Compaction and Cache Continuity.
Artifacts
When the agent publishes a file, the Web UI shows an artifact card. Use artifact cards for:
- generated HTML prototypes;
- reports and briefings;
- exported data files;
- PDFs, slide decks, images, and other generated outputs.
Images and audio play inline in the card. An artifact published as
application/vnd.agentos.chart+json renders as an interactive candlestick
chart instead of a download chip — the gmgn-market and gmgn-token skills use
this for token price charts.
For the chart payload shape, channel delivery limits, and artifact recovery, see Artifacts and Media.
Approvals
Some tools require confirmation. The approvals area gives operators a durable place to approve or deny sensitive actions instead of burying the decision in chat text.
Use the approvals area when:
- the agent wants to write files;
- a command requires elevated permissions;
- a channel or external action needs human confirmation;
- unattended automation should pause before a risky operation.
MCP Servers
Open Settings > MCP Servers to add and manage external MCP connections. The
screen supports local stdio, legacy SSE, and Streamable HTTP servers. Remote
servers can use custom headers or OAuth. OAuth tokens are stored separately
from config.toml in the AgentOS state directory. AgentOS applies mode 0600
inside a 0700 directory on POSIX systems; Windows uses the current user's
state-directory ACL.
The featured Robinhood Trading connection uses:
https://agent.robinhood.com/mcp/trading
It is configured as Streamable HTTP with OAuth. Saving the connection opens the provider authorization flow and loads its tools without requiring a gateway restart. Agentic trading involves significant risk. Review the server's access and action permissions before authorizing it.
Skills
Open Skills to see what is installed and what the agent can actually reach:
http://127.0.0.1:18791/control/skills
The Installed tab groups cards by where a skill came from, not by which directory holds it:
| Group | Contains |
|---|---|
| Partners | Skills published by an AgentOS partner |
| Shipped with AgentOS | Skills that ship with the release |
| Installed from a hub | Skills you installed with agentos skills install or from this screen |
| Your local skills | Skill directories you added yourself |
Partners wins over the other three, so a partner's skills stay under one heading whether they shipped with AgentOS or you installed them from that partner's hub. Partner identity comes from an allowlist inside AgentOS: a skill manifest can only select a recognized publisher by id, so a third-party skill cannot borrow a partner's name, link, or logo by writing them into its own frontmatter. Only a skill that ships with the release may select an id at all — an installed one is branded by the hub catalog row it came from — so dropping a directory into a skills path cannot put a card in the Partners group.
The storage layer (bundled, managed, personal, …) is still shown, as a
chip on each card, because it decides which skill wins a name collision. It no
longer decides what heading the card sits under.
Update and Remove follow what the install record actually supports rather than the layer. A hub-installed skill whose files no longer sit where the lockfile recorded them keeps Update — an update re-fetches by identifier — but loses Remove, and the dialog says why instead of offering a button that would fail.
Ready is not the same as offered
A card's status dot answers "is this skill set up". A second, separate label answers "is the agent being offered it right now", and a skill can be fully ready and still withheld. When it is, the card and its dialog say which of these applies: the manifest disables model invocation, a requirement is missing, a tool it needs is not enabled in this session, a native tool supersedes it, relevance filtering skipped it for that message, or the injected skills block hit its character budget. Nothing is shown when the skill is offered — the absence of a label is the normal case.
Community tab
Browsing and searching a hub also surfaces skills you have already installed from that source, including ones the catalog does not list — a skill installed straight from a GitHub URL appears alongside catalog rows rather than vanishing from the page it was installed on. Installed rows are marked and appear after catalog results. Installing or removing a skill updates the Installed marker immediately, without a page reload.
Environment
Open Settings > Environment to manage the variables in
~/.agentos/.env without touching a shell:
http://127.0.0.1:18791/control/env
Variables are grouped by what needs them — LLM provider, search, memory, each installed skill, and your own additions — with the description and, where the skill declared one, a link to where the credential is obtained. A skill listed as needing setup can be fixed from its own dialog on the Skills screen too: the Missing block offers Set <VAR> next to the existing install action.
A variable that is not set but is already obtainable elsewhere shows a Use
<source> button instead of asking you to go find a value — today that is
the GitHub CLI for GITHUB_TOKEN and GH_TOKEN, when gh auth login has been
run. Deciding whether to offer it never reads the credential, and importing
only happens when you click. The imported value is a copy and will not follow
that tool's own rotation.
Values are masked. Reveal asks for confirmation, is rate limited, writes an audit line, and hides the value again after thirty seconds. Setting a variable applies it to the running gateway, so a skill that was ineligible becomes eligible immediately — on this screen, on the Skills screen, and for the agent itself on its next turn. Provider keys additionally need a restart, and the screen says so when that is the case.
Two things the screen deliberately makes visible:
- Locked variables. Names that steer subprocess execution or AgentOS
runtime posture, or outbound routing (
PATH,LD_PRELOAD,AGENTOS_AGENT_PERMISSIONS,HTTP_PROXY, …) show a lock instead of an edit control. See Configuration. - Shadowed variables. If the shell that started the gateway exported a variable, that value wins over the file and editing here has no effect until the export is removed. The screen warns rather than letting you save repeatedly and conclude it is broken.
Logs and Diagnostics
For local diagnosis:
agentos diagnostics on
agentos gateway status
agentos doctor
Use the Web UI logs and health views to correlate provider readiness, channel state, session state, and user-visible errors.
Update Banner
If a newer release of use-agent-os is available on PyPI, a dismissible banner is displayed at the top of the Web UI console. The banner matches the 24h throttling behavior of the CLI update checks, and dismissing the banner suppresses it for that release version (persisted in local storage). This banner honors both the global updates.notify setting and the AGENTOS_NO_UPDATE_NOTICE environment flag.
Safety
The Web UI is local by default. If you bind the gateway to a public interface, configure token auth and network controls first:
agentos gateway run --listen 0.0.0.0 --port 18791
Do not expose an unauthenticated gateway to the public internet.