A modern, cross-platform client for the Agent Client Protocol (ACP) on desktop, mobile, and the web. Connect to AI coding agents like GitHub Copilot, Claude Code, Gemini CLI, Qwen Code, Codex CLI, OpenCode, OpenClaw, and any ACP-compatible agent from a unified interface.
No install required — open https://acp-ui.github.io/ and connect to a remote ACP agent over WebSocket. The web build supports the same chat, sessions, permissions, and traffic-monitor features as the desktop and mobile apps; it only omits local stdio agents and host filesystem access (which require a local subprocess and aren't available in a browser tab).
Pages served over HTTPS can only open
wss://URLs (browser mixed-content rule). For LANws://access, run the bundle locally (npm run preview:web) or use awss://tunnel — see Connecting from your phone or browser, the same setup works for the web build.
Download the latest release for your platform from GitHub Releases:
| Platform | Download |
|---|---|
| Web | https://acp-ui.github.io/ — no install, opens in any modern browser |
| Windows | .msi installer or .exe (NSIS) |
| macOS (Apple Silicon) | .dmg (ARM64) |
| macOS (Intel) | .dmg (x64) |
| Linux (x64) | .deb or .AppImage or .rpm |
| Linux (ARM64) | .deb or .AppImage or .rpm |
| Android | .apk — sideload via "Install unknown apps" |
| iOS | Build from source (see Building for iOS) — no prebuilt binary |
Mobile and web builds connect to remote agents over WebSocket. See Connecting from your phone or browser for how to expose a local agent so a phone or browser can reach it.
- Multi-Agent Support — Connect to any ACP-compatible agent
- Remote agents over WebSocket — Talk to agents on another machine via
ws:///wss:// - Web app — Run in any modern browser at acp-ui.github.io without installing anything
- Mobile — Android APK shipped on Releases; iOS via local Xcode build
- Foreground reconnect — On mobile and the web, automatically reattaches to your session when the app/tab regains focus
- Idle keep-alive — Sends a JSON-RPC
$/pingheartbeat every 25 seconds so NAT/proxy idle timeouts don't drop your WebSocket - Session Management — Create, resume, and manage conversation sessions
- Rich Chat Interface — Markdown rendering, syntax highlighting, tool call visualization
- Slash Commands — Quick access to agent capabilities with
/commandsyntax - Permission Controls — Approve or deny agent actions before execution
- Session Modes — Switch between agent modes (ask, code, architect, etc.)
- Model Picker — Select from available AI models (unstable API)
- Agent Thinking — View the agent's reasoning process (collapsible)
- Environment Variables — Configure per-agent environment variables (API keys, settings)
- Traffic Monitor — Debug and inspect ACP protocol messages in real-time
- Hot-Reload Config — Edit agent configurations without restarting (desktop)
- Cross-Platform — Web (any modern browser), Windows, macOS (ARM/Intel), Linux (x64/ARM64), Android, iOS
ACP UI comes pre-configured with these agents:
| Agent | Package |
|---|---|
| GitHub Copilot | @github/copilot-language-server |
| Claude Code | @zed-industries/claude-code-acp |
| Gemini CLI | @google/gemini-cli |
| Qwen Code | @qwen-code/qwen-code |
| Auggie CLI | @augmentcode/auggie |
| Qoder CLI | @qoder-ai/qodercli |
| Codex CLI | @zed-industries/codex-acp |
| OpenCode | opencode-ai |
| OpenClaw | openclaw |
Agent configurations are stored in:
| Platform | Path |
|---|---|
| Windows | %APPDATA%\acp-ui\agents.json |
| macOS | ~/Library/Application Support/acp-ui/agents.json |
| Linux | ~/.config/acp-ui/agents.json |
| Android | /data/data/formulahendry.acp_ui/files/agents.json (managed via Settings UI) |
| iOS | App sandbox — managed via Settings UI |
| Web | Browser localStorage (key acp-ui:agents) — managed via Settings UI |
On mobile and the web the config file isn't user-accessible — add and edit agents through the in-app Settings dialog. Stdio agents are filtered out of the list since they can't run in a browser or on a phone. Web-app config is per-browser per-origin: it doesn't sync across machines, and clearing site data wipes it.
{
"agents": {
"GitHub Copilot": {
"command": "npx",
"args": ["@github/copilot-language-server@latest", "--acp"],
"env": {}
},
"Claude Code": {
"command": "npx",
"args": ["@zed-industries/claude-code-acp@latest"],
"env": {
"ANTHROPIC_API_KEY": "sk-ant-..."
}
},
"Gemini CLI": {
"command": "npx",
"args": ["@google/gemini-cli@latest", "--experimental-acp"],
"env": {}
},
"Qwen Code": {
"command": "npx",
"args": ["@qwen-code/qwen-code@latest", "--acp", "--experimental-skills"],
"env": {}
},
"Auggie CLI": {
"command": "npx",
"args": ["@augmentcode/auggie@latest", "--acp"],
"env": {"AUGMENT_DISABLE_AUTO_UPDATE": "1"}
},
"Qoder CLI": {
"command": "npx",
"args": ["@qoder-ai/qodercli@latest", "--acp"],
"env": {}
},
"Codex CLI": {
"command": "npx",
"args": ["@zed-industries/codex-acp@latest"],
"env": {}
},
"OpenCode": {
"command": "npx",
"args": ["opencode-ai@latest", "acp"],
"env": {}
},
"OpenClaw": {
"command": "npx",
"args": ["openclaw", "acp"],
"env": {}
}
}
}Note: Environment variables are passed to the agent process on startup. Use these for API keys, custom settings, or overriding default behavior.
For agents running on another machine — or for connecting from a phone to an agent on your laptop — use the websocket transport instead of command:
{
"agents": {
"Copilot CLI (remote)": {
"transport": "websocket",
"url": "wss://acp.example.com/v1",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
}Both ws:// (cleartext, for LAN / Dev Tunnels) and wss:// (TLS) are accepted. Authorization: Bearer <token> is propagated as a WebSocket subprotocol because browser/WebView WebSocket APIs cannot set custom HTTP headers.
Note: Filesystem RPCs (
fs/read_text_file,fs/write_text_file) respond with JSON-RPC-32601 Method not foundfor remote agents. The agent operates on its own host's filesystem at the path you set as the working directory.
The mobile and web builds can only talk to remote agents (no subprocess in a phone or browser sandbox), so you need to expose a local stdio agent over a network endpoint. The recommended bridge is @rebornix/stdio-to-ws, which speaks ACP-over-WebSocket on one end and stdio on the other. The same setup works for the web build at acp-ui.github.io — with one extra rule: the HTTPS page can only open wss:// URLs (see HTTPS pages must use wss:// below).
On your computer:
npx @rebornix/stdio-to-ws "copilot --acp" --port 3000 --persist --grace-period -1- Allow inbound TCP 3000 in your OS firewall.
- Windows (one-time, elevated PowerShell):
New-NetFirewallRule -DisplayName "stdio-to-ws" -Direction Inbound -LocalPort 3000 -Protocol TCP -Action Allow -Profile Private
- Windows (one-time, elevated PowerShell):
- Find your computer's LAN IP (
ipconfigon Windows,ifconfig/ip aon macOS / Linux). - In ACP UI on the phone, add a websocket agent with URL
ws://<LAN IP>:3000/.
Android emulator uses
ws://10.0.2.2:3000/. USB-tethered phone can usews://localhost:3000/after runningadb reverse tcp:3000 tcp:3000.
stdio-to-ws exposes the agent on localhost; pair it with Microsoft Dev Tunnels to get a wss:// URL reachable from the public internet.
# Terminal 1 — wrap the agent as a WebSocket on port 3000.
npx @rebornix/stdio-to-ws "copilot --acp" --port 3000 --persist --grace-period -1
# Terminal 2 — expose port 3000 publicly. First-run prompts for login.
devtunnel host -p 3000devtunnel host prints a URL like:
https://<id>-3000.<region>.devtunnels.ms
Use the wss://...devtunnels.ms/ form (replace https with wss) as the agent URL in ACP UI on the phone or in the web app.
The ad-hoc URL changes every run. To get a reusable one:
# One-time setup
devtunnel user login
devtunnel create my-acp -a
devtunnel port create my-acp -p 3000 --protocol https
# Every session afterwards
devtunnel host my-acpReference: Dev Tunnels CLI commands.
When you open ACP UI in a browser at acp-ui.github.io, the page is served over HTTPS, and the browser blocks plain ws:// connections (mixed-content rule). Two options:
-
Easy: front your bridge with a
wss://URL (Dev Tunnels above gives you one for free). -
LAN-only: serve the bundle locally instead of the hosted site:
git clone https://github.com/formulahendry/acp-ui.git cd acp-ui && npm install && npm run preview:web
then open
http://localhost:4173/and add aws://<LAN IP>:3000/agent as usual.
Mobile OSes freeze backgrounded apps within seconds, dropping the WebSocket. --persist tells the bridge to keep the wrapped agent alive across disconnects, and --grace-period -1 makes that timeout infinite. When ACP UI on the phone returns to the foreground, it transparently reattaches via session/load and your conversation resumes. Without persistence, you'd lose the running agent every time you switched apps.
Tip: a future
stdio-to-wsrelease will integrate Dev Tunnels into the bridge itself (--tunnel-name <name>, currently only on itsdevbranch). Once published you'll be able to collapse the two terminals into one.
- Select an Agent — Choose from the dropdown in the sidebar (☰ on mobile / narrow web).
- Set Working Directory — Pick a folder on desktop, or type an absolute path on mobile / web. The path is interpreted on the agent's host, not your device.
- Create Session — Tap New Session to start chatting.
- Use Slash Commands — Type
/to see available commands. - Resume Sessions — Tap a saved session in the sidebar to resume.
- Node.js 18+
- Rust 1.70+
- Platform-specific build tools (see Tauri Prerequisites)
# Clone the repository
git clone https://github.com/formulahendry/acp-ui.git
cd acp-ui
# Install dependencies
npm install
# Run in development mode (Tauri desktop)
npm run tauri devnpm run tauri buildThe web app uses the same Vue 3 frontend, with the Tauri runtime swapped out for browser-native APIs (WebSocket, localStorage). It only supports remote agents over ws:// / wss://.
# Dev server with HMR (default port 5173)
npm run dev:web
# Production build → dist-web/
npm run build:web
# Serve dist-web/ locally to verify the production bundle
npm run preview:webThe live deployment at acp-ui.github.io is published from dist-web/ by .github/workflows/deploy-web.yml on every push to main.
Prerequisites:
- JDK 17 (Temurin recommended)
- Android SDK platform 34, build-tools 34, NDK 26
- Rust Android targets:
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android - Set
ANDROID_HOMEandNDK_HOMEenv vars
# `src-tauri/gen/android/` is gitignored; this regenerates it.
npm run tauri android init
# Allow plain ws:// to LAN agents (the init template defaults this off via
# a Gradle placeholder). Required for ACP UI's LAN-agent UX.
sed -i 's|usesCleartextTraffic="\${usesCleartextTraffic}"|usesCleartextTraffic="true"|' \
src-tauri/gen/android/app/src/main/AndroidManifest.xml
# Debug-signed APK suitable for sideload.
npm run tauri android build -- --debug --apk
# Output: src-tauri/gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apkTo run on a device with hot-reload during development:
npm run tauri android devIf the device can't reach the dev server, allow port 1420 through your firewall, or USB-tether the phone and run adb reverse tcp:1420 tcp:1420 first.
Prerequisites:
- macOS with Xcode 15+
- An Apple Developer team for signing
- Rust iOS targets:
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
npm run tauri ios initThen edit src-tauri/gen/apple/<app>_iOS/Info.plist and add:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
<key>NSLocalNetworkUsageDescription</key>
<string>ACP UI connects to ACP agents you configure, including agents on your local network.</string>Build and install via Xcode (.xcworkspace), or run on a connected device:
npm run tauri ios deviOS doesn't ship a binary today because it requires per-developer signing and an Apple Developer Program membership.
MIT License
