Skip to content

Repository files navigation

Grok Build Web

Professional local web workspace for the grok CLI and Grok Build workflows.

Website | xAI | Agent Client Protocol

This project is funded by Bags.

Grok Build Web runs on your machine and turns grok agent stdio into a browser-based workspace for coding sessions, tool calls, traces, project navigation, settings, routines, uploads, memory, and session management. It uses plain Node.js, static HTML, CSS, and browser JavaScript, with Mermaid for diagram previews. There is no frontend framework or build step.

Created by @lamps_apple, creator of grokify.ai and AppleLamps/grokify.

What It Provides

  • Local browser UI for grok agent stdio
  • One Grok agent process per browser tab session
  • Per-tab sessions with ?session= URLs and local resume state
  • Project sidebar grouped by workspace, including local display aliases
  • Chat, thinking traces, final answers, todos, plans, permissions, elicitations, and tool activity
  • Tool renderers for terminal commands, edits, browser actions, multimodal read_file, web and X search, images, videos, scheduler events, subagents, and plan cards
  • Manual approval or auto-approval mode for agent tool requests
  • Settings for model, agent profile, subagent definitions, effort, sandbox behavior, rules, tool allow-lists, and display name
  • Searchable, grouped sidebar tools for running tasks, managing resources, configuring the CLI, and diagnostics
  • Structured plugin and worktree managers with contextual actions and guarded destructive operations
  • Built-in panels for inspect, MCP servers, models, CLI version details, memory, hooks, traces, imports, routines, and headless runs
  • File attachment, drag-and-drop, clipboard paste, upload previews, and generated media previews
  • Share link support through grok share
  • Update notice from grok update --check --json
  • Mobile sidebar drawer, labeled workspace control, topbar overflow menu, and readable model selector for narrow viewports

Requirements

  • Node.js 24 (the currently tested runtime)
  • grok CLI installed and available on PATH
  • A cached Grok login from grok login, or API-key billing enabled through configuration
  • Windows, macOS, or Linux

Quick Start

Clone and run the local server:

git clone https://github.com/AppleLamps/grok-build-web.git
cd grok-build-web
npm install
npm start

The server prints a one-time local URL:

http://127.0.0.1:58991/?token=...

Open that URL in your browser. The token is used once to set a local HttpOnly session cookie, then the app redirects to a clean URL.

Optional grok -web Shortcut

The official Grok CLI does not currently provide a -web flag. You can add an opt-in shell function that sends grok -web and grok --web to this checkout while forwarding every other command to the normal Grok CLI.

On PowerShell, open your profile:

if (!(Test-Path $PROFILE)) { New-Item -ItemType File -Force $PROFILE }
notepad $PROFILE

Add the following, replacing the example path with the absolute path to your clone:

$GrokWebRoot = 'C:\path\to\grok-build-web'

function grok {
    $webFlags = @('-web', '--web')
    if ($args | Where-Object { $_ -in $webFlags }) {
        $rest = $args | Where-Object { $_ -notin $webFlags }
        $env:GROK_CWD = (Get-Location).Path
        node (Join-Path $GrokWebRoot 'server.mjs') @rest
        return
    }

    $grokCli = Get-Command grok -CommandType Application -ErrorAction Stop
    & $grokCli.Source @args
}

Reload the profile, then start the web app from the workspace you want to use:

. $PROFILE
grok -web

On bash or zsh, add this to ~/.bashrc or ~/.zshrc, replacing the example path with the absolute path to your clone:

export GROK_WEB_ROOT="/path/to/grok-build-web"

grok() {
  case "${1-}" in
    -web|--web)
      shift
      GROK_CWD="$PWD" node "$GROK_WEB_ROOT/server.mjs" "$@"
      ;;
    *)
      command grok "$@"
      ;;
  esac
}

Restart the shell, or source its configuration file, before running grok -web. This shortcut is local to the configured shell; cloning the repository does not modify the Grok CLI or install it automatically.

Setup

  1. Install Node.js 24.

    node --version
  2. Install and authenticate the Grok CLI.

    grok login
  3. Install dependencies and start Grok Build Web.

    npm install
    npm start
  4. Choose a workspace from the folder button in the topbar. New sessions start in the selected workspace.

  5. Open Settings to choose model, agent profile, subagent definitions, effort, sandbox behavior, rules, approval mode, tool allow-lists, and sidebar display name.

Daily Use

Start Or Resume Work

The sidebar groups sessions by workspace. Expand a project to resume a recent session, or use New Chat to start a fresh session in the current workspace.

Each browser tab has its own ACP session ID. Prompts from different tabs can run in parallel, while prompts in the same tab share that tab's agent process and prompt queue.

Send Prompts

In a new session, the composer sits below the welcome shortcuts. After the first message, it moves to the standard bottom chat position. Enter sends, and Shift+Enter inserts a newline.

The send mode selector is capability-aware:

  • Interactive: normal ACP session
  • + self-check: shown only when the installed CLI accepts --check
  • Best of 3 / Best of 5: shown only when the installed CLI accepts --best-of-n

Retired modes disappear automatically instead of dispatching unsupported flags. Headless modes do not append to the interactive ACP session history.

For more control, Tools -> Run -> Headless opens a runner with plain, json, streaming-json, or streaming-messages-json output; text, file, or ACP JSON prompts; JSON Schema output; new, named, resume-by-ID/title, continue, and forked-session modes. Collapsible launch settings expose permission and sandbox modes, allow/deny rules, tool and agent configuration, prompt overrides, memory/plan/subagent/web-search switches, verbatim prompts, and worktree name/ref options.

Attach Files

The attach button inserts text-like files into the prompt as fenced code blocks. Other files upload into .grok-web-uploads inside the current session workspace and are sent as attached file paths so Grok can read them with its native tools. Drag-and-drop and clipboard paste use the same flow.

Each attach action is capped at 5 files. Text files are capped at 256 KB, and binary uploads default to 25 MB.

Supported text extensions include .txt, .md, .js, .mjs, .ts, .tsx, .json, .css, .html, .py, .sh, .ps1, .yml, .yaml, .toml, .csv, .xml, and .log.

Images support .png, .jpg, .jpeg, .gif, .webp, .bmp, and .svg. PDFs support .pdf. Audio, video, archives, and other binary formats upload by path; images, PDFs, audio, and video receive browser preview links when their type is recognized.

Control Approvals

Use the composer approval pill:

  • Auto-approve: the bridge accepts allowed tool requests automatically
  • Manual approval: tool requests render as permission cards

Use Tools

The Tools section is searchable and grouped by intent:

  • Run: headless prompts and routines
  • Manage: worktrees, plugins, memory, and capability-gated session import
  • Configure: MCP servers, models, and hooks
  • Diagnose: inspect, version information, session information, and traces

Plugin and worktree lists render as structured records rather than raw CLI JSON. Each record exposes relevant contextual actions. Plugin uninstall and worktree removal open their existing confirmation forms; worktree removal and garbage collection remain dry-run-first.

The Plugins manager supports install, update, enable, disable, details, uninstall, and workspace-confined manifest validation. The Worktrees manager supports named/ref-based creation, details, guarded removal and garbage collection, and worktree database statistics, path lookup, or confirmed rebuilds.

Use Slash Commands

Type / in the composer to open slash-command autocomplete. Commands streamed by the installed Grok CLI are normalized before display, and compatibility fallbacks keep native commands such as /export, /config-agents, and /code-review reachable when older or partial command streams omit them.

Rename Projects Locally

Use the pencil button on a project row in the sidebar to set a local display alias. Aliases are stored in browser localStorage and only change what the sidebar shows. They do not rename folders, Grok sessions, or summary.json values.

Code Quality

Biome recommended lint rules apply repository-wide. The only project-specific exceptions are noSvgWithoutTitle, because inline SVGs are decorative inside already-labelled controls, noControlCharactersInRegex, because the terminal renderer intentionally parses ANSI escape sequences, and noDescendingSpecificity, because the layered responsive stylesheet intentionally places state overrides before some base component rules.

Configuration

Environment variables read at startup:

Variable Default Purpose
PORT 0 HTTP port. 0 selects a random free port.
GROK_BIN grok Path to the Grok CLI binary.
GROK_BIN_ARGS [] Extra Grok CLI prefix args as a JSON array of strings.
GROK_CWD process.cwd() Initial workspace directory.
GROK_WEB_USER OS username Default sidebar display name.
GROK_WEB_NO_OPEN unset Set to skip opening the browser automatically.
GROK_WEB_USE_API_KEY unset Set to 1 to keep XAI_API_KEY in spawned agent and one-shot CLI environments.
GROK_WEB_SESSIONS_ROOT ~/.grok/sessions Session directory used for sidebar history and plan hydration.
GROK_MEMORY_ROOT ~/.grok/memory Memory directory used by the memory panel.
GROK_WEB_MAX_UPLOAD_BYTES 26214400 Maximum binary upload size.
GROK_WEB_MAX_REQUEST_BODY_BYTES 67108864 Maximum JSON request body size.
GROK_WEB_MAX_CLI_STDOUT_BYTES 33554432 Maximum retained CLI stdout bytes; larger output keeps diagnostic head and tail content.
GROK_WEB_MAX_CLI_STDERR_BYTES 4194304 Maximum retained CLI stderr bytes; larger output keeps diagnostic head and tail content.
GROK_WEB_MAX_AGENT_LINE_BYTES 67108864 Maximum ACP stdout frame size before the agent is terminated as a protocol violation.
GROK_WEB_RPC_TIMEOUT_MS 120000 JSON-RPC timeout for non-prompt ACP calls.
GROK_WEB_PROMPT_TIMEOUT_MS 1800000 JSON-RPC timeout for session/prompt.
GROK_WEB_PERMISSION_TIMEOUT_MS 300000 Timeout for pending permission cards.
GROK_WEB_ELICITATION_TIMEOUT_MS 300000 Timeout for pending elicitation cards.
GROK_WEB_MAX_ACTIVE_AGENTS 4 Maximum active per-tab agent processes.
GROK_WEB_AGENT_IDLE_MS 1800000 Idle time before an agent process can be evicted.
GROK_WEB_AGENT_IDLE_SWEEP_MS 60000 Agent idle sweep interval.
GROK_WEB_GRACEFUL_SHUTDOWN_MS 3000 Maximum time allowed for graceful server shutdown.
GROK_WEB_SESSIONS_CACHE_TTL_MS 2000 In-memory session-list cache lifetime.
GROK_WEB_SESSIONS_WATCH_DEBOUNCE_MS 1500 Filesystem session-change debounce interval.
GROK_WEB_SESSIONS_WATCH_POLL_MS 5000 Poll interval used by the session watcher fallback.
GROK_WEB_SESSIONS_WATCH_RETRY_MS 5000 Delay before retrying a failed session watcher.
GROK_WEB_DISABLE_FS_WATCH unset Set to 1 to disable filesystem watching for session changes.
GROK_OTEL_ENABLED unset Passed through to spawned Grok CLI processes. Set when your Grok build uses this switch for OpenTelemetry export.
OTEL_EXPORTER_OTLP_ENDPOINT unset Passed through to spawned Grok CLI processes as the OpenTelemetry collector endpoint.
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT unset Passed through to spawned Grok CLI processes as the trace-specific OpenTelemetry collector endpoint.
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT unset Passed through to spawned Grok CLI processes as the metrics-specific OpenTelemetry collector endpoint.
OTEL_SERVICE_NAME unset Passed through to spawned Grok CLI processes for OpenTelemetry service labeling.

By default, Grok Build Web strips XAI_API_KEY and GROK_API_KEY from spawned agent processes and one-shot CLI runs so the CLI uses the cached grok.com login from ~/.grok/auth.json. Set GROK_WEB_USE_API_KEY=1 to use API key billing instead.

OpenTelemetry variables are inherited by the Grok child process unchanged. Tools -> Diagnose -> Session info shows whether telemetry-related variables are present without displaying their values.

Architecture

browser  -> POST /prompt -> server.mjs -> stdin  -> grok agent stdio
browser  <- SSE /stream  <- server.mjs <- stdout <- grok agent stdio

The Grok CLI exposes Agent Client Protocol over grok agent stdio. server.mjs starts a local HTTP server, creates a one-time bootstrap token, and lazily spawns Grok agent children through the bridge.

Each browser tab receives its own ACP sessionId, stored in the URL and browser state. The bridge tags events with sessionId, so each tab receives only its own stream. Agent processes are lazy-spawned on /tab/new or /tab/load, reused for prompts in that tab, and evicted after the configured idle period.

The server also shells out to the Grok CLI for non-ACP actions such as inspect, models, MCP servers, worktrees, sharing, traces, capability-gated imports, update checks, login, and headless prompts. Managed ACP and headless runs pass --no-auto-update when supported so the web app remains in control of update notices and process restarts.

Repository Map

grok-web/
|-- server.mjs                 Thin boot + HTTP listener
|-- lib/                       Bridge modules (ACP, routes, sessions, CLI)
|   |-- grok-bridge.mjs        Multi-agent pool (one stdio child per tab session)
|   |-- agent-connection.mjs   Single ACP stdio child + prompt queue
|   |-- sessions-store.mjs     Session list + plan.json reads
|   |-- cli-runner.mjs         One-shot grok CLI shell-outs
|   `-- http/
|       |-- router.mjs         Request dispatch
|       `-- routes/            Per-domain HTTP handlers
|-- public/
|   |-- index.html             Page shell
|   |-- styles/
|   |   |-- main.css           Layout, sidebar, composer, settings, modals
|   |   `-- cards.css          Tool, plan, permission, and elicitation cards
|   `-- js/
|       |-- main.js            Browser entry point
|       |-- api.js             Fetch wrappers
|       |-- state.js           Shared client state and DOM refs
|       |-- dispatch.js        SSE event dispatch
|       |-- chat.js            Turn rendering and assistant output
|       |-- tools.js           Barrel re-export for tool rendering
|       |-- tools/             Per-tool renderers + details registry
|       |-- settings.js        Settings panel
|       |-- identity.js        Sidebar identity display
|       |-- sidebar.js         Project drawer and recents
|       |-- composer.js        Input, send, stop, approval mode
|       |-- topbar.js          Workspace picker, mobile actions, share, update notice
|       `-- tools-menu.js      Grouped/searchable sidebar tool wiring
|-- package.json
|-- test/                      Fake ACP, renderer, UI-state, bridge, and live integration tests
`-- probe/                     Protocol discovery scripts

HTTP Routes

Route Method Purpose
/ GET Token-gated app shell
/static/* GET Static CSS and JS
/vendor/mermaid.min.js GET Locally installed Mermaid browser bundle
/session-media GET Authenticated previews for generated media under Grok session storage
/upload-media GET Authenticated previews for uploaded media under the session workspace
/stream GET SSE stream of agent events
/prompt POST Send an ACP prompt
/cancel POST Cancel the running turn
/upload POST Upload a file into the current session workspace
/settings GET, POST Bridge settings, including auto approve and display name
/identity GET Current sidebar identity
/spawn-opts GET Current launch flags and detected Grok agent capabilities
/sessions GET Recent sessions from the configured sessions root
/session/plan GET Persisted plan.json state for a session
/session/new POST Start a new session in a workspace
/session/load POST Load an existing session
/session/respawn POST Restart the agent with new launch flags
/tab/new POST Create a per-tab ACP session
/tab/load POST Load a per-tab ACP session
/permission POST Answer a pending permission request
/elicitation POST Answer a pending elicitation request
/cli/inspect GET grok inspect --json
/cli/update-check GET grok update --check --json
/cli/version GET Normalized grok version --json details
/cli/models GET grok models
/cli/mcp GET grok mcp list
/cli/worktree GET Legacy plain-text grok worktree list output
/cli/plugins GET Installed plugins from grok plugin list --json
/cli/plugins/action POST Validated plugin lifecycle actions
/cli/worktrees GET Tracked worktrees from grok worktree list --json --all
/cli/worktrees/action POST Validated create/show/remove/GC/database actions
/cli/login/status GET Whether ~/.grok/auth.json exists after device auth
/cli/memory/list GET List Grok memory files under the configured memory root
/cli/memory/read GET Read one Grok memory file, confined to the memory root
/cli/share POST grok share <sessionId>
/cli/trace POST grok trace --local --json
/cli/login POST grok login --device-auth
/cli/oneshot POST Capability-gated legacy check and best-of-N modes
/cli/headless POST Configurable headless grok -p runner
/cli/sessions/search POST Search local Grok sessions
/cli/import POST grok import --json -- <targets> when supported; otherwise HTTP 501

Development

Run syntax, lint, and format checks:

npm run check

Run the fast account-free development suite:

npm test

This runs the focused CLI, API, rendering, streaming, security, permission, and utility checks used during normal development. Run the exhaustive account-free suite before publishing:

npm run test:full

The full suite adds fake ACP bridge/SSE integration, per-session cwd isolation, sidebar/settings behavior, bootstrap recovery, session edge cases, uploads, oversized replay pruning, fork-session isolation, large output, cancellation, and complete tool-lifecycle coverage. npm run verify combines static checks, the full account-free suite, and browser visual smoke coverage.

Run browser visual smoke checks:

npm run test:visual

Run live integration checks against the installed grok CLI:

npm run test:live

Live tests start a real local server on an ephemeral port, bootstrap the one-time token, connect SSE, call /sessions, /spawn-opts, /cli/models, /cli/mcp, trigger real web search, read generated PNG/JPG/PDF/PPTX fixtures through read_file, and verify cancellation recovery. X search and plugin MCP auth are account-dependent opt-in checks:

$env:GROK_WEB_LIVE_X_SEARCH='1'; npm run test:live
$env:GROK_WEB_LIVE_PLUGIN_MCP_NAME='<server-name>'; npm run test:live

Grok CLI Compatibility

The current audit baseline is Grok CLI 0.2.118 (1e1687c1cf) stable. On August 1, 2026, grok update --check --json reported the installation up to date. The app detects optional commands and launch flags at runtime, so unsupported import and legacy headless dispatch modes are hidden instead of being sent to the CLI.

After a CLI upgrade, run npm run verify, then use the live verification checklist for account-dependent and platform-specific behavior. Update FUTURE.md when the CLI adds a web-relevant command or flag.

Feature touch points:

  • New tool renderer: add a file under public/js/tools/ and register it in public/js/tools/details-registry.mjs.
  • New event type: update public/js/dispatch.js.
  • New permission UI: update public/js/permissions.js.
  • New elicitation UI: update public/js/elicitation.js.
  • New launch flag: update public/js/settings.js and lib/grok-bridge.mjs.
  • New HTTP route: add a handler in lib/http/routes/ and register it in lib/http/router.mjs.
  • New CLI panel: update lib/http/routes/cli.mjs, public/js/api.js, and public/js/panels.js.
  • Sidebar or layout polish: update public/styles/main.css.
  • Tool card polish: update public/styles/cards.css.

Security Model

Grok Build Web is designed for local use. The launch URL includes a one-time token that sets an HttpOnly cookie. API and SSE requests require that cookie. Static assets are public because they contain no secrets.

HTTP responses include a local-app security baseline: CSP with frame-ancestors 'none', X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and Referrer-Policy: no-referrer. The server only accepts Host values for 127.0.0.1, localhost, or ::1 on its active port. Mutating browser requests with an Origin header must come from the same local origin.

The bridge can read and write files only through ACP requests from the agent, and those filesystem handlers are confined to the request's session workspace. Generated media previews are served only through the authenticated /session-media endpoint, which is confined to Grok session storage and does not expose arbitrary local files. Uploaded media previews are served only from .grok-web-uploads inside the active session workspace.

Per-tab session APIs keep workspace cwd in per-session state so one tab cannot silently change another tab's fallback cwd. Windows extended-length path prefixes are stripped from model-facing and rendered display text while internal filesystem paths remain confined by workspace checks. Agent restarts and session loads are serialized per agent and through a small bridge operation queue. Permission and elicitation timeout handles are cleared across respawns, and SSE reconnect replay is delivered with response backpressure, history pruning, and listener cleanup.

Related

About

Local web workspace for the Grok CLI, with browser chat, tool rendering, project sessions, approvals, uploads, traces, and Grok Build workflow controls.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages