Skip to content

Network exposure

This page is for IT teams, network admins and security reviewers who need to know exactly what AgentMux puts on the wire.

ListenerProcessBindProtocolAuthenticationWhen
AgentMux server (web and ws ports)agentmux-srv127.0.0.1, two ephemeral portsHTTP, WebSocketX-AuthKey (instance auth key). Public: GET /, /webhook/whatsappAlways
AgentMux server, LAN listenersagentmux-srvThe same two ports on every non-loopback interface addressHTTPOnly four LAN-peer routes, each taking the lan_key or the auth key. Public: GET /, /health, /webhook/whatsappLAN discovery on (default off)
mDNSagentmux-srvUDP 5353, multicastmDNS / DNS-SDNoneLAN discovery on
UDP discovery responderagentmux-srv0.0.0.0:47891 UDPJSONNone; answers only private, link-local and loopback source addressesLAN discovery on
Dev proxyagentmux-srv127.0.0.1:8090HTTP reverse proxyNoneAlways (skipped if the port is taken)
OAuth callbackagentmux-srv127.0.0.1, ephemeralHTTP, one requestOAuth state and PKCEOnly during a browser sign-in to an account you configured OAuth for
Host IPC serveragentmux-cef127.0.0.1, ephemeralHTTPBearer token on /ipc and /agentmux/browser/*. Public: /health, the frontend’s static filesAlways
Chromium remote debugging (CDP)agentmux-cefLoopback; port 9222 (release), 9223 (dev), or a free portHTTP, WebSocketNoneDev builds, or when AGENTMUX_CDP_PORT turns it on. Off in release builds by default
Launcher IPCagentmux-launcherWindows named pipe \\.\pipe\agentmux-<hash>\command; Unix socket in $XDG_RUNTIME_DIR/agentmux/ or /tmp/agentmux-<uid>/Newline-delimited JSONNoneAlways
Server IPC (Windows)agentmux-srvNamed pipe \\.\pipe\agentmux-<hash>\srv-commandNewline-delimited JSONNoneWindows, when started by the launcher
Crash monitor (Windows)agentmux-srvUnix-domain socket C:\CrashDumps\agentmuxsrv\monitor.sockMinidump IPCNoneWindows, always

agentmux-mcp, the MCP server each agent runs, talks to its agent over stdio and opens no listener.

With LAN discovery off, nothing listens on a non-loopback address. Every TCP listener binds 127.0.0.1, and the pipes and sockets are local by construction. Loopback is shared by every account on the machine, though: other OS users can reach the loopback listeners too. That matters most for the remote-debugging port, when it is on.

agentmux-srv binds two ports on 127.0.0.1, both chosen by the OS at each launch, and serves the same API on both. The bind address is fixed in code (STARTUP_BIND_ADDR in crates/srv/src/backend/lan_listeners.rs); no setting changes it.

Authentication (auth_middleware in crates/srv/src/server/mod.rs):

  • Every route requires the X-AuthKey header to equal the instance auth key. The key is a UUIDv4 the launcher generates at each launch.
  • /ws also accepts the key as an ?authkey= query parameter, because the browser WebSocket API can’t set headers. No other route accepts it in the query string.
  • Unauthenticated: GET / returns {"status":"ok","version":"<version>"}. /webhook/whatsapp is the receiver for the WhatsApp bridge; it checks Meta’s verify token and X-Hub-Signature-256 HMAC instead of the auth key, and returns 503 until that bridge is set up.
  • Every response, including unauthenticated ones, carries an x-agentmux-srv-version header.

CORS reflects only the origins http://127.0.0.1[:port] and http://localhost[:port]. A web page from any other origin can’t read responses. A page still can’t call any authenticated route without the key. /ws also refuses a WebSocket upgrade whose Origin header is anything other than those two (ws_origin_guard); a client that sends no Origin, such as the launcher or agentmux-mcp, is allowed. Every key and token a caller presents is compared in constant time (crates/common/src/secret_eq.rs).

Every terminal pane and host agent process receives the auth key as AGENTMUX_AUTH_KEY. See the trust model for what that means. Container agents get a narrower per-agent token in the same variable instead.

When you turn on LAN discovery, LanListenerSupervisor binds the server’s two ports again on every non-loopback interface address: all IPv4 addresses, and all IPv6 addresses except link-local. That includes VPN and virtual adapters. It re-checks the interface list every 20 seconds, and removes the listeners when you turn LAN discovery off.

These listeners serve only the routes LAN peers need (build_routers_with in crates/srv/src/server/mod.rs, the lan router), with no filtering by source address. From any network that can reach one of those addresses:

  • anyone can call GET / and /health (the version) and the WhatsApp webhook;
  • anyone holding the lan_key can call four routes: send a jekt, look up one agent, list agent names, and ask whether an agent UID is running here (see what the lan_key unlocks);
  • nothing else. Every other route, /ws included, returns 404 on a LAN listener, even with the full auth key, and the LAN listeners never serve the frontend.

The mobile-pairing QR code in the host popover (Show QR code) still contains the full auth key, together with this machine’s LAN address and port. Over the network the key reaches only the four routes above, but on this machine it gives full control until AgentMux restarts, so don’t show the code where others can see it.

The lan_key is sent in cleartext to anyone on the local network (next section). Turn LAN discovery on only on networks you trust, and restrict the listeners with your host firewall to the peers or subnet you expect.

While LAN discovery is on and at least one LAN listener is bound, the server advertises itself over mDNS as service type _agentmux._tcp.local.:

  • instance name agentmux-<hostname>-<port>, host name <hostname>.local.;
  • the server’s web port and the machine’s IP addresses;
  • TXT record: version, hostname, instance_id (v plus the version, for example v0.57.6), and auth_key, which holds the lan_key, not the full auth key.

It also listens on UDP port 47891. A datagram {"type":"agentmux_discover","v":1} from a private, link-local or loopback address gets a unicast reply:

{ "type": "agentmux_discover_response", "v": 1, "instance_id": "v0.57.6",
"hostname": "<hostname>", "version": "0.57.6", "port": <web port>, "auth_key": "<lan_key>" }

Neither channel has confidentiality or authentication. Anyone on the broadcast domain learns the machine’s hostname, AgentMux version, server port and lan_key, and can then send messages to its agents. The lan_key is regenerated at each launch.

While LAN discovery is on, the server also contacts every peer it discovers, presenting that peer’s advertised lan_key:

  • every 30 seconds it asks each peer for its agent names; responses are capped at 64 KiB;
  • before an agent starts, and every 30 seconds while it runs, it asks each peer whether it is running that agent (GET /agentmux/agent/holding?uid=<uid>, 1.5-second timeout), so one agent doesn’t run on two computers (crates/srv/src/backend/agent_admission.rs).

A device that fakes an mDNS advertisement can make the server send these requests to an address of its choosing. Its answers aren’t authenticated either: by claiming to hold an agent, it can make this instance refuse to start that agent, or stop it.

agentmux-srv always starts a reverse proxy on 127.0.0.1:8090 (crates/srv/src/backend/dev_proxy.rs). It routes a request whose Host is <key>.localhost to a dev server an agent registered with the RegisterDevServer tool (a port inside that agent’s container). Unregistered hosts get 404. It has no authentication: any local process, including other users’ processes, can reach a registered dev server through it. If port 8090 is taken, the proxy logs a warning and doesn’t start.

The CEF host (agentmux-cef) runs an HTTP server on an ephemeral 127.0.0.1 port (crates/cef/src/ipc.rs). It serves the frontend’s static files and /health without authentication. /ipc and the browser-automation routes /agentmux/browser/* require Authorization: Bearer <token>, a UUIDv4 generated at each start of the host.

  • The token is passed to the frontend in the page URL. It is also written to an ipc-port-<hash> file in the data directory, with default file permissions (on Unix the data root itself is owner-only), so a second launch can find the running instance.
  • /ipc returns the server auth key to the frontend (get_auth_key), so the token is as valuable as the auth key itself.
  • The CORS layer is fully permissive (CorsLayer::permissive()): the bearer token is the only barrier.

Chromium’s remote-debugging (DevTools Protocol) server is off in release builds (crates/cef/src/cdp_port.rs). AgentMux doesn’t need it: its own browser automation (the /agentmux/browser/* routes, which back the Browser*, UIScreenshot, UIClick and UIQuery agent tools) drives the DevTools Protocol inside the process (crates/cef/src/browser_api/cdp.rs), and Inspect Element opens Chromium’s built-in DevTools window.

The AGENTMUX_CDP_PORT environment variable, read when AgentMux starts, turns it on or off:

AGENTMUX_CDP_PORTServer
Unset or emptyOff in release builds. On in dev builds, preferring port 9223
A port from 1024 to 65535On, preferring that port
1, on, true, yes or autoOn, preferring 9222 (release) or 9223 (dev)
0, off, false or noOff, dev builds included

When the preferred port is taken, it uses an OS-assigned free port. The port actually used is written to authkey.dev in the data directory.

When the server is on, AgentMux doesn’t set --remote-debugging-address, so Chromium binds it to loopback, its default. The server has no authentication. AgentMux starts Chromium with --remote-allow-origins set to http://127.0.0.1:<port> and http://localhost:<port> only (crates/cef/src/app/mod.rs, remote_allow_origins), so a web page from any other origin can’t open a DevTools WebSocket. A client that sends no Origin header, which any local program can do, is not stopped by that check.

What this means in practice, while the server is on:

  • Any process on the machine that can open a loopback TCP connection can attach to AgentMux’s windows, run script in them and read what they display. On a multi-user machine, that includes processes of other OS users.
  • The AgentMux UI holds the server auth key, so attaching to it gives full control of AgentMux: running commands as you, reading files, driving agents.

Mitigations: leave the server off unless you need it; don’t set AGENTMUX_CDP_PORT on a shared machine. Dev builds run it by default, so set AGENTMUX_CDP_PORT=0 there if other people use the machine. If you do turn it on on a shared host, block other accounts from the port with a per-user firewall rule if your OS supports one (on Linux, an iptables owner match on the loopback interface), and read the port from authkey.dev, since it can change.

The launcher, the CEF host and the server talk over local IPC (crates/launcher/src/ipc/server.rs, crates/srv/src/srv_ipc/server.rs). None of these channels uses a token; the first message a client sends declares what it is.

  • Unix: the launcher’s socket lives in a directory AgentMux creates with mode 0700, owned by you. It refuses to use the directory if it is a symlink, isn’t a directory, or is owned by another user. Other OS users can’t connect; any process running as you can.
  • Windows: the named pipes are created without an explicit security descriptor, so Windows’ default named-pipe security applies. Microsoft documents that default as full control for LocalSystem, administrators and the creator, and read access for Everyone and anonymous. Remote clients are rejected.
  • Windows crash monitor: a helper process receives crash reports over a Unix-domain socket at the fixed path C:\CrashDumps\agentmuxsrv\monitor.sock, shared by all users and instances, and writes minidumps to C:\CrashDumps\agentmuxsrv\. The directory gets no explicit access control.

Data sovereignty lists every outbound call with its trigger. In summary:

DestinationWhen
Your agents’ model providersMade by the agent CLIs, not by AgentMux
api.anthropic.com/v1/modelsAt each launch, when a Claude login token is found
muxbus.agentmux.ai, muxbus-ws.agentmux.aiOnly after you sign in to MuxBus Cloud
registry.npmjs.org (or your configured npm registry)Installing an agent CLI; checking CLI versions in the Toolchain pane
github.com release downloadsInstalling jq or ripgrep from the tool catalog; Crush’s npm install script fetches its binary there
github.com release downloads (goose), x.ai (Grok Build), aider.chat and pypi.org (Aider), dev.meta.ai, api.meta.ai and lookaside.facebook.com (Muse Code), antigravity.google (Antigravity)Made by the vendor’s installer when you install one of these harnesses, not by AgentMux
www.google.com/s2/faviconsShowing an agent’s web-search or web-fetch results
agentmux.aiOpening a browser pane with no URL (its default Home page)
Your default search engine (Google)Typing in a browser pane’s address bar: each edit is sent for suggestions before Enter, unless Search suggestions while typing (browser:searchsuggestions) is off; text that isn’t a URL is searched on Enter
winget, Homebrew or your Linux package managerOne-click installs of Node.js, Git or Python
Groq, Hugging Face, Discord, Telegram, Slack, WhatsApp, OAuth providers, key-validation endpointsOnly when you configure or use those features
LAN peersOnly with LAN discovery on

There is no telemetry endpoint, crash-report upload, update check or license check.

Workstation, LAN discovery off: no inbound rule is needed. Every listener is loopback or local IPC.

LAN discovery on: the server’s ports are chosen at each launch, so allow the program rather than fixed ports. Windows Firewall prompts for this the first time you turn LAN discovery on. Peers need:

  • inbound TCP to the server’s two ports (they change at every launch);
  • inbound UDP 5353 (mDNS) and, for probe-based discovery, UDP 47891.

Restrict these to your LAN subnet or to known peers.

Outbound: allow whatever your agents’ providers need, plus the destinations above for the features you use. Blocking muxbus.agentmux.ai and muxbus-ws.agentmux.ai disables MuxBus Cloud. Blocking the npm registry disables in-app CLI installs. Blocking a vendor’s download site stops you installing that harness, not AgentMux.


Source-of-truth references:

Marketing claims this page substantiates: “runs on your machine” on agentmux.ai.