Content
# Architect.tool
> The reliable, local browser layer for any AI agent — drives your real logged-in
> sessions (no API tokens, no metering), and learns site workflows by watching
> instead of needing per-site code.
<!-- hero demo: record per docs/DEMO_WHATSAPP_REPLAY.md, export to docs/media/hero-demo.gif, then uncomment:

-->
Show your agent a task **once** — it watches, compiles the demonstration into a
parameterized workflow, and replays it forever with **zero LLM tokens**, surviving
DOM drift along the way. Everything runs locally: a single Go binary driving your
real Chrome session over CDP, exposed to any agent as an MCP server.
## Quickstart (MCP)
One command — downloads the latest release and registers with Claude Code if present:
```bash
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/liamparker17/architect-tool/master/scripts/install.sh | sh
```
```powershell
# Windows
irm https://raw.githubusercontent.com/liamparker17/architect-tool/master/scripts/install.ps1 | iex
```
Or manually:
```bash
go install github.com/liamparker17/architect-tool@latest # or grab a release binary
claude mcp add architect-tool -- architect-tool mcp # Claude Code
```
Any MCP client works — the server command is simply `architect-tool mcp`.
The browser opens on first use; log in to your sites manually and the session
persists across runs.
**Every agent surface is supported** — Claude Code/Desktop, Codex CLI, Cursor,
ChatGPT connectors (`architect-tool mcp --http`), or any function-calling model
via REST + `architect-tool schema`. See [docs/INTEGRATIONS.md](docs/INTEGRATIONS.md).
## Why Architect.tool?
- **Demonstrate once, replay free** — observe mode records a human doing the task; the compiled workflow replays token-free with self-verifying steps and selector-rot fallback
- **No API tokens required** — agents interact with services through the browser, using your existing sessions and subscriptions
- **Built for unfamiliar pages too** — accessibility-tree `read_page` outline and free-text `find` beat screenshot-driven guessing on token cost
- **No bypassed caching** — requests go through the same CDN, rate limits, and cache layers as a real user
- **Full orchestration** — not just automation, but parallel agents, service bridges, and enforced guardrails in one runtime
## Core Concepts
| Concept | What it does |
|---------|-------------|
| **Browser Control** | Interact with websites via Chrome DevTools Protocol — click, type, scroll, navigate, screenshot, evaluate JS |
| **Agents** | Run work items in parallel across multiple browser tabs with shared auth and guardrails |
| **Bridges** | Connect to external services (ChatGPT, future: NotebookLM, etc.) through a pluggable registry |
| **Rulebook** | Enforce safe, structured agent behavior with must/should/prefer rules that ship with the binary |
## Prerequisites
A Chromium-based browser — **Chrome, Brave, or Edge**. That's it.
## Install
### macOS (recommended: double-click .app)
1. Download from the [latest release](https://github.com/liamparker17/architect-tool/releases/latest):
- Apple Silicon (M1/M2/M3/M4) → `architect-tool-darwin-arm64.app.zip`
- Intel → `architect-tool-darwin-amd64.app.zip`
2. Unzip and drag the `.app` into `/Applications`.
3. **First launch only:** right-click the `.app` → **Open** → click **Open** in the warning. macOS remembers the approval; future double-clicks work normally.
Studio opens in a Chrome window within a few seconds. See [docs/MAC_INSTALL.md](docs/MAC_INSTALL.md) for the macOS Sequoia 15 fallback (`xattr -cr`) and the bare Mach-O option.
### macOS (CLI binary)
Bare Mach-O binary at `architect-tool-darwin-arm64` / `architect-tool-darwin-amd64` if you'd rather skip the `.app` wrapper. Both are ad-hoc-codesigned (≥ v1.16.1) so the kernel will launch them on Apple Silicon — older versions will not.
```bash
curl -L -o architect-tool https://github.com/liamparker17/architect-tool/releases/latest/download/architect-tool-darwin-arm64
chmod +x architect-tool
sudo mv architect-tool /usr/local/bin/architect-tool
xattr -cr /usr/local/bin/architect-tool # clear quarantine
```
### Windows
Download `architect-tool-windows-amd64.exe` from the [Releases](https://github.com/liamparker17/architect-tool/releases/latest) page. Put it somewhere in your PATH, or double-click to launch Studio directly.
### From source (requires Go 1.26+)
```bash
go install github.com/liamparker17/architect-tool@latest
```
### Verify
```bash
architect-tool --version
architect-tool --help
```
## Desktop UI (Studio)
New in v1.7.0 (revamped in v1.11.0). Studio is designed so that someone with zero technical knowledge can go from downloading the binary to having a working AI browser assistant in under five minutes — no terminal, no config files, no jargon.
```bash
architect-tool # opens Studio (or just double-click the .exe)
architect-tool studio # same thing, explicit
```
### Zero-config onboarding
The setup tutorial walks new users through everything in four plain-English steps:
1. **Welcome** — explains what architect-tool does in one sentence, no jargon
2. **Sign in** — tells the user to log into their sites in the browser window. A live indicator detects when they've actually signed in (polls open tabs via CDP) and updates in real time
3. **Connect your AI app** — auto-scans the machine for installed AI apps (Claude Desktop, Cursor, Windsurf, Continue) and offers one-click config patching. Users who don't have one yet get a step-by-step install guide with download links tailored to each app. Power users can expand a manual-config panel with copy-pasteable JSON instead. Connected apps can be disconnected later from the hamburger menu
4. **Try it out** — shows three ready-to-copy example prompts (browse a site, teach it a workflow via observe mode, do real work across sites), tailored to whichever app was connected in step 3
Every step has a back button, a skip link, and progress dots. The tutorial can be re-opened from the hamburger menu at any time. After completion, a **quick-reference card** below the action log shows six things the user can ask their AI to do — each with an example prompt they can copy directly.
### Live monitoring
Studio shows a real-time action log of everything the AI does in the browser — every navigate, click, type, and screenshot appears with timestamps and duration. A cycling tip bar teaches new users one feature at a time. Click-to-learn help popovers explain each part of the UI on first click.
### How it works under the hood
Studio auto-starts the daemon if one is not already running and leaves it running when the window closes, so your AI keeps working in the background. The window is a frameless Chrome `--app=...` instance pointed at a loopback control server — no webview runtime, no cgo, no extra dependencies. On Windows, double-clicking `architect-tool.exe` in Explorer launches Studio directly. On macOS, double-clicking the `.app` from `/Applications` does the same — see [docs/MAC_INSTALL.md](docs/MAC_INSTALL.md).
### MCP-daemon proxy (v1.11.0)
When an MCP client (Claude Desktop, Cursor, etc.) calls `architect-tool mcp`, the MCP server detects the running Studio daemon and proxies browser tool calls through it via `POST /execute`. This means Studio and your AI app share the same Chrome session — no profile conflicts, no second browser window, and every action the AI takes shows up in Studio's live log. If no daemon is running, the MCP server falls back to launching its own Chrome.
## Quick Start
```bash
# Open a visible browser and navigate
architect-tool navigate --url "https://example.com" --visible
# Keep the browser open for follow-up commands
architect-tool navigate --url "https://google.com" --visible --keep-alive
# Output: Session: abc123
# Type, click, screenshot using that session
architect-tool type --selector "textarea[name='q']" --text "hello world" --session abc123
architect-tool screenshot --output page.png --session abc123
# Run JavaScript
architect-tool evaluate --expr "document.title" --session abc123
```
## Four Interaction Modes
| Mode | Command | Use case |
|------|---------|----------|
| **Studio** | `architect-tool` (no args) or `architect-tool studio` | New users — tutorial, status bar, live action log in a native desktop window |
| **One-shot CLI** | `architect-tool navigate --url ...` | Single actions, scripting |
| **Daemon** | `architect-tool daemon --visible` | AI agent integration via JSON stdin/stdout |
| **MCP server** | `architect-tool mcp` | Claude Code, Cursor, Windsurf, etc. |
---
## Browser Control
Full browser automation via CDP:
- Navigate, click, type, insert text (bulk), scroll (CDP mouse wheel), keyboard shortcuts, hover, select, file upload
- DOM querying (CSS selectors + XPath), JavaScript evaluation
- Screenshots (full page, element-level), PDF generation
- Cookie management, network interception
- Navigation history, wait for elements/navigation
- `--visible` flag to watch automation in real time
## Agents
Run hundreds of items across parallel browser tabs.
```bash
# 1. Create a script with {{variables}}
cat > ~/.architect-tool/scripts/update-title.json << 'EOF'
{
"name": "update-title",
"steps": [
{"action": "navigate", "params": {"url": "{{url}}"}},
{"action": "click", "params": {"selector": ".edit-btn"}},
{"action": "type", "params": {"selector": "#title", "text": "{{title}}"}},
{"action": "click", "params": {"selector": "#save"}}
],
"variables": ["url", "title"]
}
EOF
# 2. Dispatch — 3 tabs in parallel
architect-tool dispatch --script update-title --items-file pages.csv --concurrency 3 --visible
```
From daemon mode:
```json
{
"id": "1",
"action": "dispatch",
"params": {
"items": [
{"script": "update-title", "vars": {"url": "https://cms/page/1", "title": "Title 1"}, "url": "https://cms/page/1"},
{"script": "update-title", "vars": {"url": "https://cms/page/2", "title": "Title 2"}, "url": "https://cms/page/2"}
],
"concurrency": 5,
"scopeLock": true,
"actionBudget": 500
}
}
```
**How it works:** The orchestrator opens N tabs, distributes items (no two agents share a URL), streams per-item results, and detects common patterns to auto-promote as reusable scripts.
**Guardrails:**
| Guard | What it does |
|-------|-------------|
| **Scope lock** | Agents can ONLY navigate to URLs in the work items |
| **Action budget** | Caps total actions across all agents — dispatch killed when hit |
## Observe Mode
Observe mode lets an agent learn a browser task by watching a human do it. It is **not** a command recorder — it does not capture what the LLM types, it captures what the human does in the browser the daemon already drives. Use it when the agent needs to learn an unfamiliar site or workflow by demonstration.
- `observe_start {task, instruction, total_runs?}` — inject a content-script banner and begin capturing. The banner appears in **Idle** state; capture does not begin until the user clicks Start.
- `observe_stop` — finalize the current run and write trace files.
- `observe_status` — poll for the banner state (`idle` / `observing` / `done_received` / `cancelled`) plus event count and gap markers.
- `analyze_traces {task}` — read every run under a task and return structured experience units. Output uses deliberately non-authoritative names (`common_target_tuples`, `candidate_step_counts`, `seen_in_runs`) — the tool reports observations, the LLM does inference.
Live observe actions require the daemon (run `architect-tool daemon` or connect via an MCP client). Offline analysis is available via the CLI: `architect-tool observe analyze --task <name>`.
Traces live under `~/.architect-tool/traces/<task>/run_<NNN>/` as `meta.json`, `trace.jsonl`, `network.jsonl`, and snapshot HTML files. See `docs/REFERENCE.md` for the full reference.
## Interaction Mode Enforcement
Every domain gets a runtime interaction mode that controls what agents can do:
| Mode | Behavior |
|------|----------|
| **unset** (default) | Navigation, screenshots, and system actions allowed. Interaction and JS evaluation blocked until the user confirms a mode. |
| **`cdp_only`** | All CDP interactions allowed. Mutating JS evaluation blocked — only read-only expressions (DOM queries, measurements) pass through. |
| **`js_first`** | Everything allowed, including JS evaluation. |
**How it works:**
1. When an agent navigates to a domain, the policy engine checks embedded site rules for a pre-configured mode (e.g., `chatgpt.com` is `cdp_only`)
2. If no mode is set, interaction actions return `CONFIRMATION_REQUIRED` — the agent must ask the user and call `confirm_interaction_mode`
3. `PolicyExecFunc` is the single enforcement boundary — every action passes through it
4. Page-level bypass detection passively monitors for violations that skip enforcement
The evaluate allowlist uses regex-based heuristics to distinguish read-only expressions (`document.title`, `el.getBoundingClientRect()`) from mutations (`el.click()`, `el.innerHTML = '...'`). This is a best-effort filter, not a security boundary.
## Bridges
Bridges connect AI agents to external services through a pluggable registry. Each bridge registers its actions, and the registry handles routing, health checks, caching, and activity tracking.
```
Agent calls ask_chatgpt
-> Registry routes to ChatGPT bridge
-> Health check passes
-> Activity event emitted
-> Bridge executes action
-> Response cached (if cacheable)
-> Result returned with activity log
```
**Available bridges:**
- **ChatGPT** (ships built-in) — `ask_chatgpt` sends prompts to ChatGPT via the signed-in browser session.
- **Memory** (ships built-in) — a local reference bridge backed by SQLite at `~/.architect-tool/memory.db`. Three actions: `remember` (persist a key/value note), `recall` (read back by key or tag), `forget` (delete a note). No browser required; validates the bridge framework end-to-end.
**Bridge actions:**
| Action | Description |
|--------|-------------|
| `list_bridges` | Discover registered bridges, their status, and available actions |
| `bridge_activity` | Recent activity events across all bridges |
| `stop_bridge` | Cancel a bridge operation mid-flight |
In the MCP server, unknown tool names are automatically routed through the bridge registry — any bridge action works as an MCP tool without additional configuration.
## Rulebook
The master rulebook ships with the binary and enforces discipline on AI agents. Seven built-in rules at `must` severity:
- Check available context before starting work
- Use retrieval bridges instead of raw document parsing
- Follow service rules returned by bridge actions exactly
- Discover available bridges before assuming capabilities
- Report bridge errors to the user, don't silently retry
- Never automate login — tell the user to log in manually
- Respect interaction modes — when an action returns `CONFIRMATION_REQUIRED`, ask the user which mode to use
Users can add custom rules via `~/.architect-tool/rules/master.json`:
```json
{
"add": [{"id": "my-rule", "rule": "Always summarize responses", "severity": "should"}],
"disable": ["some-non-must-rule"]
}
```
Must-severity rules cannot be disabled.
---
## ChatGPT Bridge
Send messages to ChatGPT via browser automation using your existing subscription — no API keys.
**Daemon mode** (action/params format):
```json
{"action": "ask_chatgpt", "params": {"message": "Critique this error message for clarity", "session": "ux-copy", "system_context": "You are a UX copywriter."}}
```
**MCP mode** (name/arguments format):
```json
{"name": "ask_chatgpt", "arguments": {"message": "Critique this error message for clarity", "session": "ux-copy", "system_context": "You are a UX copywriter."}}
```
> **Note:** The daemon also accepts MCP-style `name`/`arguments` as an alias for `action`/`params`.
**Sessions** persist across calls. Omit `session` to auto-route by keyword overlap. You can also resume sessions by their `AT-XXXX` tag (see below).
**Conversation tagging and sidebar navigation:** After the first message in a new session, the bridge automatically:
1. Scrapes ChatGPT's auto-generated title
2. Generates a unique `AT-XXXX` tag
3. Renames the conversation in the sidebar to the tag
When resuming a session, the bridge uses a 3-tier lookup: URL fast path → sidebar scan → ChatGPT search. This means conversations survive URL changes and can be found even if the browser was closed and reopened.
**CDP-only interaction:** All ChatGPT interactions use Chrome DevTools Protocol input events (mouse clicks, keyboard input, mouse wheel scrolling). ChatGPT uses ProseMirror which silently ignores DOM manipulation and JS clicks — CDP events are the only reliable method.
**Under the hood:** Auto-launches Chrome with a debug profile, injects stealth patches, applies human-like cadence (shared `bridge/cadence` package), detects streaming completion, handles Cloudflare challenges. Login persists after the first manual sign-in.
### Response extraction — race conditions to know about
ChatGPT's DOM has three subtleties that break naive response scraping. All three are handled by the bridge, but worth documenting for anyone extending it:
1. **Empty streaming placeholder.** During streaming, ChatGPT creates a `.result-thinking .markdown` div with an empty `<p>` tag *before* any tokens stream in. A `querySelectorAll("div[data-message-author-role='assistant'] .markdown")` without filtering returns this empty div as the "latest response". `readLastResponse` walks backward and **skips empty elements**, returning the last non-empty `.markdown` text instead.
2. **Stale baseline race.** If you poll `readLastResponse` immediately after clicking send, you get the *previous* response back — the new `.markdown` hasn't been populated yet. The stability detector then sees "stable text" and returns the stale response. The fix: snapshot the response text *before* sending (`baselineText`), and in the stability loop, skip any poll where `currentText == baselineText`.
3. **DOM hydration lag after navigation.** Immediately after navigating to a conversation URL, the `.markdown` children may not be populated yet even though the assistant `<div>`s exist. `readLastResponse` can return empty, which makes the baseline useless (any non-empty text looks "new"). The bridge polls for a non-empty baseline (up to 5s) before sending.
4. **DOM virtualization.** ChatGPT virtualizes long conversations — only a few recent turns are in the DOM at once. Don't rely on "count assistant divs" as a signal for anything other than *change*; absolute counts are meaningless.
The stability detector in `chatgpt/extractor.go` requires *both* text stability *and* the stop button to be gone before declaring a response complete. Requiring only one of those produces truncated responses on GPT's mid-stream pauses.
## WordPress Migration
6-stage pipeline: gather ACF fields, organise into blocks, evaluate layouts, resolve images via WP REST API, inject blocks + preview, verify output.
```bash
architect-tool migrate --post 8550 --session isp4 --visible # stops at preview
architect-tool migrate verify --post 8550 --session isp4 # automated checks
architect-tool migrate publish --post 8550 --session isp4 # re-verifies, then publishes
```
Never auto-publishes. WordPress revisions are the rollback mechanism.
## Daemon Mode
```bash
architect-tool daemon --visible # new browser, watch it happen
architect-tool daemon --session abc123 # reconnect to existing
```
```json
{"id":"1","action":"navigate","params":{"url":"https://example.com"}}
-> {"id":"1","status":"ok","result":{"url":"https://example.com/","title":"Example Domain"}}
```
First command should be `capabilities` — returns available actions, registered bridges, master rulebook, scripts, dispatch config, and agent guidelines.
**Actions:** `navigate`, `click`, `type`, `insertText`, `scroll`, `shortcut`, `select`, `hover`, `setFiles`, `evaluate`, `screenshot`, `pdf`, `cookies`, `query`, `waitForSelector`, `clickAndWait`, `reload`, `back`, `forward`, `dispatch`, `agentStatus`, `confirm_interaction_mode`, `list_bridges`, `bridge_activity`, `stop_bridge`, `run_tasks`, `run_status`, `capabilities`
## MCP Server
```json
{
"mcpServers": {
"architect-tool": {
"command": "architect-tool",
"args": ["mcp"]
}
}
}
```
20+ tools. Browser primitives, ChatGPT, bridge management, task runner, setup flow. Unknown tools fall through to the bridge registry automatically. Master rulebook included in initialization instructions.
## UserScripts
Replay and auto-detect reusable action sequences.
```bash
architect-tool script run login-flow --profile mysite
architect-tool script list
architect-tool script candidates # auto-detected patterns
```
The tool journals every action. A post-session analyzer detects repeated patterns (3+ occurrences) and saves them as script candidates with template variables.
## Site Rules
Embedded interaction rules for sites where standard automation fails. When an agent navigates to a known domain, the response includes site-specific selectors, shortcuts, and workflows.
```bash
architect-tool rules list
architect-tool rules show docs.google.com
```
**Built-in:** Google Docs, Sheets, Slides, Drive, Gmail, Calendar, ChatGPT. Each rule can declare an `interaction_mode` (`cdp_only`, `js_first`, or unset) to control how the tool interacts with the site. Drop a JSON file in `~/.architect-tool/rules/` to add your own.
## CLI Reference
| Command | Description |
|---------|-------------|
| `navigate` | Navigate to a URL |
| `click` | Click an element |
| `type` | Type text into an element |
| `insertText` | Insert text at cursor (bulk) |
| `shortcut` | Keyboard shortcut (`--key b --ctrl` for bold) |
| `hover` | Hover over an element |
| `select` | Select a dropdown option |
| `setfiles` | Set files on a file input |
| `evaluate` | Execute JavaScript |
| `screenshot` | Capture a screenshot |
| `pdf` | Generate a PDF |
| `query` | Query DOM elements |
| `cookies` | Manage cookies |
| `back` / `forward` / `reload` | Navigation history |
| `waitforselector` | Wait for an element |
| `clickandwait` | Click and wait for navigation |
| `dispatch` | Parallel multi-tab execution |
| `migrate` | WordPress migration pipeline |
| `daemon` | Daemon mode (JSON stdin/stdout) |
| `mcp` | MCP server |
| `rules` | Site-specific rules |
| `script` | Manage scripts |
| `profile` | Manage profiles |
| `sessions` | Manage browser sessions |
### Flags
| Flag | Default | Description |
|------|---------|-------------|
| `--visible` | `false` | Show browser window |
| `--headless` | `true` | Headless mode |
| `--chrome-path` | auto | Path to browser binary |
| `--timeout` | `30s` | Operation timeout |
| `--keep-alive` | `false` | Keep browser open after command |
| `--session` | | Reconnect to existing session |
| `--connect-port` | | Attach to Chrome debug port |
| `--user-data-dir` | | Chrome user data directory |
## Architecture
```
architect-tool/
├── bridge/ # Unified bridge framework
│ ├── bridge.go # Interface, types (HealthStatus, ActionSpec, Rule)
│ ├── registry.go # Action routing, health, caching, activity
│ ├── activity.go # Event emission, logging, bridge stop
│ ├── cache.go # LRU response cache with TTL
│ ├── cadence/ # Shared timing — jittered delays, rate limiter
│ └── rulebook/ # Master rules, user overrides, merge logic
├── cdp/ # Chrome DevTools Protocol client
├── browser/ # Browser discovery, launch, lifecycle
├── page/ # High-level page API (navigate, click, stealth)
├── chatgpt/ # ChatGPT bridge adapter, sessions, streaming
├── session/ # Daemon mode, command dispatch
├── orchestrator/ # Multi-agent dispatch, work queue, guardrails, PolicyExecFunc
├── policy/ # InteractionPolicy, evaluate allowlist, mode enforcement
├── mcp/ # MCP server (JSON-RPC 2.0 over stdio)
├── runner/ # Task runner with retries and state persistence
├── scripts/ # Script engine, recording, variable substitution
├── journal/ # Action logging (JSONL)
├── analyzer/ # Pattern detection, SQLite storage
├── rules/ # Site-specific rules (embedded + user overrides)
├── migrate/ # WordPress ACF migration pipeline
├── profiles/ # Profile management, encrypted credentials
├── whitelist/ # URL/selector allowlisting
└── cmd/ # CLI commands (Cobra)
```
## Known Issues
See [KNOWN_ISSUES.md](KNOWN_ISSUES.md) for the current list of open bugs, workarounds, and fix directions.
## License
[Business Source License 1.1](LICENSE) — free for non-commercial use and small teams (<10 employees). Converts to Apache 2.0 after 4 years. Commercial licenses available.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available