NoUI: Skip the UI. Turn any website into fast, reliable APIs for agents.
Overview
\ Go beyond Claw. Call the underlying APIs.\ Skip Computer-use Agents. ------------------------------------------------------------------------ Instead of automating clicks and scraping the UI, NoUI: 1. Records how you use a website (through a Tabby browser session) 2. Extracts the underlying APIs 3. Converts them into callable Python functions 4. Exposes them via MCP or as an installable Skill for agents No clicks. No DOM parsing. No brittle automation. NoUI ships as a (skills/noui/). The only external dependency is a reachable Tabby — there is no separate backend service to run and no LLM API key required. ------------------------------------------------------------------------ Computer-use agents simulate humans: - 🐢 Slow (UI loops, page loads) - 💸 Expensive (token-heavy, step-heavy) - 🧱 Fragile (break on UI changes) - ⚡ --- direct API calls - 💸 --- fewer steps, fewer tokens - 🎯 --- uses the same APIs the app uses internally
README
NoUI
Skip the UI. Turn any website into fast, reliable APIs for agents.
Go beyond Claw. Call the underlying APIs.
Skip Computer-use Agents.
🚀 What is NoUI?
NoUI turns any website into an API your agents can call.
Instead of automating clicks and scraping the UI, NoUI:
- Records how you use a website (through a Tabby browser session)
- Extracts the underlying APIs
- Converts them into callable Python functions
- Exposes them via MCP or as an installable Skill for agents
No clicks. No DOM parsing. No brittle automation.
NoUI ships as a single, agent-agnostic skill bundle (skills/noui/). The
only external dependency is a reachable Tabby — there is no separate backend
service to run and no LLM API key required.
⚡ Why NoUI?
Computer-use agents simulate humans:
- 🐢 Slow (UI loops, page loads)
- 💸 Expensive (token-heavy, step-heavy)
- 🧱 Fragile (break on UI changes)
NoUI executes software directly:
- ⚡ Fast — direct API calls
- 💸 Cheap — fewer steps, fewer tokens
- 🎯 Reliable — uses the same APIs the app uses internally
Stop automating clicks. Execute software.
🧠 How it works
- Record a session in a Tabby browser — manually in a VNC viewer, or with
Autopilot (the agent drives
POST /execute/browser) - Tabby captures HAR traces + interaction events server-side
- Compile the capture into Python API functions (a FastMCP server and/or a Skill)
- Execute tools from inside the authenticated Tabby browser session
- Install the Skill / run the MCP server in any agent
- Agents call APIs instead of clicking UI
Execution
Generated tools run from inside the authenticated Tabby browser, not from a
Python HTTP client. By default (the tabby execution mode) each operation calls
Tabby’s POST /execute/fetch endpoint over plain HTTP; the Tabby worker runs
fetch(url, {credentials: 'include'}) inside the real authenticated browser, so
the browser’s TLS fingerprint and cookies are used — no credential extraction,
and no Akamai/Cloudflare false positives. There is no WebSocket or CDP-port
access from the NoUI side.
The legacy Python-side path (httpx + resolved credentials) is still available
for server-to-server APIs that aren’t reachable from the browser origin; opt in
explicitly when compiling with --execution-mode http.
🏗️ Architecture
Tabby browser session
→ VNC (human drives) | Autopilot (agent drives POST /execute/browser)
↓ (HAR + click/url events — captured server-side by Tabby)
noui_core (the skill bundle, skills/noui/)
→ capture/ — drain/synthesize the recording bundle
→ compile/ — login → Tabby App Template; workflow → FastMCP server / Skill
→ activate/ — register App Templates, verify auth, install into agents
↓
Output (all under skills/noui/workbench/)
→ bundles/ — saved capture bundles (source for re-generalization)
→ mcp_servers/// — runnable FastMCP packages
→ skills// — installable agent Skills
↓
Tabby Runtime (persistent browser sessions + live auth, POST /execute/fetch)
↓
MCP / Skill → Claude / Codex / Agents
🔑 Core Components
🧩 HAR → API Compiler
- Parses browser network traffic (HAR), deterministically — no LLM calls
- Groups requests into logical workflows
- Generates clean Python functions (MCP server and/or Skill)
🐾 Tabby Runtime
- Keeps browser sessions alive in the cloud
- Handles cookies, headers, auth
- Streams VNC for login / 2FA when needed; runs
POST /execute/*for tools
🔌 MCP Server / Skill
- Exposes generated APIs as tools
- Works with Claude, Codex, and MCP-/skill-compatible agents
🎯 What you can do
- Automate websites with no public APIs
- Turn internal tools into agent-ready SDKs
- Replace brittle browser automation workflows
- Build production-grade agents that actually scale
⚡ Example
def create_invoice(customer_id, amount):
return call_api(
method="POST",
endpoint="/api/invoices",
headers=session_headers,
json={"customer_id": customer_id, "amount": amount},
)
Then your agent simply says:
“Create an invoice for customer X”
NoUI executes it directly.
🔐 Authentication Flow
- NoUI provisions a remote Tabby browser session
- Streams it via VNC
- You complete login / 2FA once, in the VNC viewer
- Tabby maintains the session
No username/password is ever stored (credential_ref: manual:). When the
browser reaches the post-login URL, Tabby auto-resolves the login — no
repeated “Mark as Resolved” clicks. Agents reuse the authenticated context
automatically through POST /execute/fetch.
⚔️ NoUI vs Computer-Use Agents
| Computer-Use Agents | NoUI | |
|---|---|---|
| Speed | Slow (UI loops) | Fast (direct APIs) |
| Cost | High | Low |
| Reliability | Breaks on UI changes | More Stable |
| Approach | Simulates humans | Executes software |
🧠 Philosophy
Websites already expose APIs. The UI is just a layer on top.
NoUI removes that layer.
🚀 Quick Start
Prerequisites
- Python 3.11+
- A reachable Tabby (cloud, or self-host via Docker + the
tabby/submodule) - Tabby credentials in one tenant:
TABBY_CLIENT_ID/TABBY_CLIENT_SECRET(agent), andTABBY_ADMIN_TOKEN(to register App Templates; Editor role suffices)
Clone with submodules
⚠️ NoUI includes Tabby as a git submodule (for local dev/test and to version-lock the endpoint contract). Clone recursively, or the
tabby/directory will be empty.
git clone --recursive https://github.com/adoptai/noui.git
# Or, if you already cloned without --recursive:
git submodule update --init
Install
cd noui/skills/noui
# 1. Create a venv and install the bundle (noui_core + deps: httpx, python-dotenv, mcp)
python -m venv .venv && . .venv/bin/activate
pip install -e .
# 2. Configure environment
cp .env.example .env
# Edit .env: TABBY_API_URL, TABBY_CLIENT_ID / TABBY_CLIENT_SECRET,
# and TABBY_ADMIN_TOKEN (for register). All in the SAME tenant.
Scripts are run from skills/noui/ as python scripts/.py ….
🤖 Agent Skills
Install the NoUI skill — one self-contained bundle covering the full record → compile → activate pipeline — into your agent (Claude Code, Codex, OpenCode…):
npx skills add https://github.com/adoptai/noui --skill noui
Then invoke /noui in your agent. The bundle’s SKILL.md documents the three
pillars and the scripts; references/ holds the deep dives.
Human users who prefer an interactive picker can run
npx skills add https://github.com/adoptai/noui(no--skillflag) and tick what they want. AI agents must use the per-skill--skillform — the interactive selector blocks on stdin.
Available skills
| Skill / plugin | Purpose |
|---|---|
/noui |
The bundle — Capture (VNC/Autopilot) → Compile (MCP/Skill/Profile) → Activate (register/install/run) |
skills/travel |
Claude Code plugin: Airbnb, Expedia, Flydubai, Google Flights via Tabby /execute |
skills/quickbooks |
Claude Code plugin: QuickBooks bank reconciliation via Tabby /execute |
Install demo plugins from a clone:
claude plugin install ./skills/travel
claude plugin install ./skills/quickbooks
🛠️ Developer Flow
All commands run from skills/noui/.
Unauthenticated apps
# 1. Record a workflow in a Tabby VNC session. --mode workflow is EXPLICIT here: with no
# login to capture, the combined default would ask you to sign in to nothing.
python scripts/capture_record.py --mode workflow --url "https://example.com"
# open the printed VNC URL, perform the workflow, click "Finish & export"
# 2. Drain + compile to a FastMCP server (and/or Skill)
python scripts/capture_import.py --as mcp
Authenticated apps (with Tabby) — the default flow
One recording session captures the login and the workflow, so the human gets a single link and signs in once. NoUI splits the capture at the login boundary.
# 1. Record: sign in AND drive the workflow in ONE VNC session, one "Finish & export".
# No --mode needed (it defaults to combined); --name also skips the capture entirely
# if an App Template already covers this app.
python scripts/capture_record.py --url "https://app.example.com/login" --name example
# 2. Drain + compile: registers a tenant-wide login App Template (per-user profiles
# auto-provision → ACTIVE, no stored credentials) AND compiles the workflow bound
# to it. No --combined flag: the provision ledger already recorded the mode.
python scripts/capture_import.py --as skill --name example \
--post-login-url-pattern ""
# 3. Install the generated Skill into your agent
python scripts/activate_install.py workbench/skills/ claude-code
The first live call against the new profile returns login_required: its per-user
session starts LOGIN_NEEDED (nothing is stored, and the recording’s cookies are
deliberately not reused for a tenant-wide template). The caller escalates — the Agent
Harness shows a Connect card; locally, read vnc_stream.url from
GET /agent/session-status/ and hand it to the human. One sign-in, then every later
call uses that session. There is nothing to run in advance.
Workflow only — the app already has a profile
# --profile/--from means the auth exists, so the mode defaults to workflow-only.
python scripts/capture_record.py --url "https://app.example.com/app" --profile example
python scripts/capture_import.py --as both --profile-slug example
# … or let the agent drive it headlessly instead of a human:
python scripts/capture_autopilot.py --steps steps.json --as both
Static API-key apps (no login to record)
# The app authenticates with a static key on every request — record only the
# workflow and declare the auth model. NoUI emits a ${SECRET:...} placeholder;
# an admin registers the value in the harness secret store (never held by NoUI).
python scripts/capture_record.py --mode workflow --url "https://example.com"
python scripts/capture_import.py --as skill --execution-mode harness \
--auth-type api-key --api-key-header Authorization
--auth-typedeclares the app’s auth model (sessiondefault |api-key|auto). Distinct from--auth-mode(agent_token/platform_jwt), which is the Tabby token mode.
📦 Generated MCP Output
skills/noui/workbench/
bundles/.json # saved capture bundle (re-generalization source)
mcp_servers///
server.py # FastMCP entrypoint
tools.json # Tool inventory
manifest.json # Server manifest (lifecycle + auth metadata)
noui_runtime/
auth.py # Runtime auth adapter (fetches live creds from Tabby)
execute.py # Calls Tabby /execute/fetch from inside the browser
operations/
.py # One file per generated tool
skills// # Installable agent Skill (SKILL.md + operations/)
🖥️ Scripts Reference
The bundle replaces the old CLI with thin, purpose-built scripts (run from
skills/noui/):
scripts/capture_record.py --url [--mode login|workflow|combined] [--from ]
[--profile ] [--auth-type {session|api-key}] [--api-key-header ]
# --mode defaults to `combined` (one link, one sign-in), or
# `workflow` when --profile/--from supplies the auth
scripts/bundle_inspect.py | --session [--json]
scripts/capture_autopilot.py --steps steps.json --as {mcp|skill|both}
scripts/capture_import.py [--name ] [--as {mcp|skill|both}] [--execution-mode {tabby|http|harness}]
[--combined] [--auth-type {session|api-key|auto}] [--api-key-header ]
[--profile-slug ] [--credential-mode {takeover|manual|stored|auto}]
[--auth-mode {agent_token|platform_jwt}] [--tenant-id ] [--post-login-url-pattern ]
scripts/compile_workflow.py --as {mcp|skill|both}
scripts/compile_login.py --out
scripts/activate_register.py [--tenant-id ]
scripts/activate_verify.py
scripts/activate_install.py # agent: claude-code|codex|cline|opencode|agents [--project]
🔌 Tabby endpoints used
NoUI talks only to Tabby (no NoUI backend service):
| Method | Path | Description |
|---|---|---|
| POST | /auth/agent-token |
Exchange TABBY_CLIENT_ID/SECRET for an agent token |
| POST | /recording/sessions |
Provision a VNC recording session |
| GET | /recording/sessions/{id}/bundle |
Drain the captured bundle (HAR + events) |
| POST | /admin/app-templates |
Create a tenant-wide App Template (login registration) |
| POST | /apps/{id}/sessions/scale |
Bring a worker session up/down |
| GET | /agent/session-status/{profile} |
Session state + HITL VNC URL (login) |
| POST | /execute/fetch · /execute/browser |
Run a tool / drive the browser inside the session |
🔗 Tabby compatibility
NoUI depends on Tabby for authenticated
browser sessions. To keep behavior deterministic across releases, NoUI pins a
specific SHA on Tabby’s tabby-noui branch via a git submodule.
- Current pin:
tabby-noui @ d3c7373 - Branch:
tabby-noui - Submodule path:
tabby/(inside this repository)
Using a different Tabby revision is unsupported. The submodule is for local
dev/test; at runtime NoUI talks to whatever Tabby TABBY_API_URL points at. See
CONTRIBUTING.md for the submodule-bump workflow.
🧩 Capture (no Chrome extension)
Capture happens server-side inside Tabby — there is no Chrome extension to install. Two modes:
- VNC —
capture_record.pyprovisions a recording session; you drive a real browser in the VNC viewer and click “Finish & export”. - Autopilot —
capture_autopilot.py/AutopilotSessiondrives the browser throughPOST /execute/browser; NoUI synthesizes the bundle from the inline HAR plus the commands it issued.
Both produce the same {har, click_events, url_events} bundle that the compiler
consumes.
📚 Project docs
- docs/HANDOFF.md — install & use the skill with Tabby (start here)
- CONTRIBUTING.md — dev setup, PR process, bumping the Tabby submodule
- SECURITY.md — responsible disclosure
- CHANGELOG.md — release history
- CODE_OF_CONDUCT.md
🔥 Status
Early open source — expect rough edges. Contributions welcome.
📢 Closing
Computer-use agents were step one.
NoUI is what comes next.
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add adoptai/noui