Litewave
Provides Phoenix/Elixir runtime tools for a running application via the development-only litewave_phoenix dependency. Over a private Unix socket it exposes tools for retrieving docs, source locations, logs, evaluation, and SQL, usable from the CLI or MCP server without an open browser.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@LitewaveCan you screenshot the current page?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Litewave
Local browser access and Phoenix runtime tools for coding agents.
Litewave keeps a dedicated Chromium open on your machine and lets an agent drive it through a CLI or an MCP server: navigate, click, fill, upload, download, screenshot, and read the accessibility tree. Every mutation is journaled with a caller-chosen request ID, so a lost response is reported as unknown, never as success, and is never replayed automatically.
For Phoenix applications, an optional development dependency publishes runtime tools (docs, source locations, logs, evaluation, SQL) on a private Unix socket at boot. No port, token, or endpoint change is needed, and the tools work without an open browser.
Everything stays on your machine. There is no Litewave account, relay, or model subscription.
Requirements
macOS. Linux runs in CI but is not yet a supported platform.
Node 24.21.0 or newer.
.nvmrcand.node-versionpin the development version.Your application already running. Litewave never starts, restarts, or repairs it.
Related MCP server: Agentic Browser bridge
Install
CLI and MCP server
npm install -g litewave
litewave browser installbrowser install downloads the pinned Chromium build once. Nothing is installed automatically. Prefer not to install globally? Prefix every command below with npx litewave instead. For MCP use, install globally (or as a project devDependency) so the command path init prints stays stable; an npx cache path is temporary.
Phoenix runtime tools
Add the development-only dependency and restart your app:
# mix.exs
{:litewave_phoenix, "~> 0.1", only: :dev}That is the whole install. Details, options, and the alternative HTTP transport are in the Phoenix package README.
First session
Register the project. When the Phoenix app is running with litewave_phoenix, the app URL is read from it; otherwise pass --app.
litewave init --project /absolute/path/to/app
litewave browser open --project /absolute/path/to/appinit prints an MCP server entry with absolute Node and CLI paths. Add it to your agent's MCP configuration; Litewave never edits agent configuration itself. Sign into your app normally in the dedicated browser. The profile persists, so you sign in once.
Every browser operation uses the same JSON schema and response envelope through the CLI, the library, and the MCP browser tool. List tabs, then act on one:
litewave call --project /absolute/path/to/app --json '{"method":"tabs","requestId":"tabs-1"}'{
"method": "navigate",
"requestId": "home-1",
"tabId": "TAB_ID",
"url": "http://localhost:4000"
}{
"method": "click",
"requestId": "export-1",
"tabId": "TAB_ID",
"target": { "kind": "role", "role": "button", "name": "Export" },
"postcondition": {
"target": { "kind": "role", "role": "heading", "name": "Export ready" },
"state": "visible"
}
}Use a new request ID for each intended mutation. After a lost response, query action_status with actionId: "export-1": the same ID returns the prior state and never clicks again. dispatched means the browser call completed; postcondition_met confirms the requested observation; outcome_unknown means investigate, not that the app failed.
Runtime tools need no browser:
litewave phoenix status --project /absolute/path/to/app
litewave phoenix call --project /absolute/path/to/app --tool get_docs --json '{"reference":"Enum.map/2"}'
litewave mcp --project /absolute/path/to/appOne runtime per project directory
A project is a directory. Its identity is the canonical path, and every piece of state derives from it: the runtime socket, the descriptor, the browser registration, and the Chromium profile. Two directories are two projects, even when they are worktrees of one repository, and that is deliberate.
The app publishes for the directory it runs in. A dev server started inside a worktree publishes a socket for that worktree, and the BEAM answering on it is that server, so
project_eval,get_docs,get_source_location,get_logs, and SQL run against the worktree's own code, modules, and repo configuration. Several dev servers, one per worktree on its own port, run side by side without touching each other.Clients pick the project from
--project, or from the current directory when it is omitted. For one checkout, themcpServersentry printed byinit(with--projectfixed) is fine. For a repository worked on in several worktrees at once, commit a.mcp.jsonwithout--project, so each editor session started in a worktree talks to that worktree's runtime with no per-worktree configuration:{ "mcpServers": { "litewave": { "command": "litewave", "args": ["mcp"] } } }MCP clients such as Claude Code start stdio servers in the project directory, which is what
litewave mcpresolves.Browser access is per project too. Each worktree that wants browser tools runs its own
litewave initwith its own app URL and gets its own profile and logins. Runtime tools need none of that.Nothing is shared but the code. The
litewavecommand and the Node runtime are stateless; all state is underLITEWAVE_HOME, keyed by project. Deleting a worktree leaves itsprojects/<key>/entry behind;litewave stop --project PATHbefore removing it closes the browser cleanly, and the runtime socket disappears when the dev server stops.
Guides
Phoenix package: install, options, tool behaviour, the HTTP Plug alternative.
Reference
Locators, waits, files
Locators support exact role/name, test ID, and explicit CSS. Ambiguous targets fail. Supply revision from a snapshot to reject an action after navigation.
snapshot: bounded accessibility text, optionally scoped to a target. Truncation is explicit.wait: a target,state: "visible"or"hidden", and optionaltimeoutMsup to 30 seconds.screenshot: viewport by default,fullPage: true, ortargetfor an element. Returns a local PNG path; password inputs are masked.upload: a file-inputtargetand absolutepathsinside registered upload roots.paths: []clears the selection. Selection does not confirm server import.Downloads are captured from every tab from creation, before click dispatch. Poll
downloadsforcomplete, retainedpath, size, and SHA-256. Each download gets its own directory.
Full schemas: src/protocol.ts. Library exports: src/index.ts.
Upload folders
Uploads are optional. Browser uploads send local files to your app, so Litewave limits selection to folders you allow explicitly; the agent cannot pick arbitrary local files. Use an existing folder of files you intend to upload, such as a fixture directory. Subfolders are allowed; symlinks cannot escape the boundary.
litewave init --project /absolute/path/to/app --upload-root /absolute/path/to/fixturesFor an existing registration, doctor shows the configured folders and the registration file. To change them: finish active actions, stop, edit only uploadRoots in that file, then browser open. There is no registration-update command yet.
Browser version and profile transitions
Litewave pins Playwright 1.62.0 / Chromium 151.0.7922.34 to avoid a reproduced Chromium 153/154 crash on restart with retained downloads; see the investigation. It refuses to open a profile last used by a newer Chromium. To create a compatible replacement while keeping the old profile:
litewave stop --project /absolute/path/to/app
litewave browser open --project /absolute/path/to/app --fresh-profileSign in again, or add --storage-state /absolute/path/to/state.json to import an explicitly exported Playwright storage state. That file contains authentication: keep it private and delete it after import. Litewave never exports authentication or copies cookies from another browser.
Ownership and troubleshooting
litewave doctor --project /absolute/path/to/app
litewave stop --project /absolute/path/to/appdoctor probes the app over HTTP, the browser worker, and the Phoenix runtime separately. stop closes the owned browser and worker and refuses while an action or download is active. Closing an MCP client only detaches it.
State lives in ~/.litewave with owner-only permissions. LITEWAVE_HOME relocates it: use a short absolute path (socket paths are limited to about 100 bytes on macOS), not a symlink, and set the same value for the app and every CLI/MCP client of a project; the MCP entry printed by init includes it. Project identity is the canonical project directory; see One runtime per project directory.
Litewave never kills an unknown browser or deletes a profile lock. After a verified close it may let Chromium reacquire its own leftover lock only when the recorded owner is absent and the profile evidence matches. Worker death currently loses volatile tab state; saved downloads remain on disk.
Status
Litewave is a development alpha. Browser access and the Phoenix runtime tools work and are covered by contract tests, real-browser suites, and a real MCP client over the socket. Not yet implemented: automatic worker recovery, snapshot references and frames, dialogs, drag and scroll, enforced read-only SQL, and Windows or Linux support. The capability matrix lists what is tested and what remains.
Contributing and licence
Start with CONTRIBUTING.md. Original code is MIT licensed; dependency and upstream notices are in NOTICE. The Phoenix package additionally carries Apache-2.0 attribution for code adapted from Tidewave.
This server cannot be deployed
Maintenance
Related MCP Connectors
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
On-demand cloud browser sessions; page actions need a compatible CDP client.
1Real Chrome for agents: start a browser, read pages as numbered markdown, click, type, hand off.
Provides cloud browser automation capabilities using Stagehand and Browserbase, enabling LLMs to i…
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to drive a live, persistent self-hosted Chromium session over MCP, running browser actions via Playwright/CDP, capturing page snapshots, screenshots and videos, and managing uploads and downloads in the same tabs and signed-in accounts a human user can take over at any time.3 npmApache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables an AI agent to observe, plan, and act inside a real browser session by exposing navigation, snapshot, click, type, and screenshot MCP tools over local JSON-RPC and SSE. It runs a Playwright-backed browser in-process and provides stable element references for reliable actions.MIT
- AlicenseNot gradedqualityAmaintenanceLets AI coding tools drive the user's already-signed-in Chrome browser — reading and snapshotting pages, clicking, typing, uploading files, screenshotting, and inspecting tabs, cookies, console, and network traffic. It works through a local Chrome extension bridge, so no remote debugging port is opened and the real, authenticated browser session is used.1 npmISC
- FlicenseNot gradedqualityAmaintenanceExposes a local MCP endpoint that lets AI agents and human operators drive isolated Chromium profiles — each with its own cookies, fingerprint, and proxy — through tools for navigation, clicking, typing, extraction, screenshots, JS evaluation, tabs, and cookie management. Persistent per-profile session state keeps logins and context alive across launches and across AI sessions, so agents can complete real authenticated workflows.-