Controlling a remote machine
malac-control, the computer and browser control service, does not have to run where malac runs. Start it on a remote machine that has a desktop, connect malac to it, and the agent’s computer_* and browser_* tools act on that machine: its screen, its mouse and keyboard, and its browsers.
This is how malac tests GUIs and websites on other machines: a Mac mini in a rack, a Linux desktop VM, a test laptop on the office network.
What runs where
Section titled “What runs where”| Runs on your machine | Runs on the remote machine |
|---|---|
malac: the agent, the model requests, the session transcripts |
malac-control serve: screenshots, mouse, keyboard and browsers |
read, edit, bash and the other built-in tools, on your files |
Browser profiles in the remote’s ~/.malac/browser/ |
| Your configuration and permission rules | The remote’s ~/.malac/control.toml |
So bash still runs commands on your machine, and a URL such as http://localhost:3000 in browser_navigate means port 3000 on the remote machine.
1. Install malac on the remote machine
Section titled “1. Install malac on the remote machine”Install malac there as usual (Installation); you only need the malac-control binary on that side, and it is installed next to malac. Use the same malac version on both machines.
2. Prepare the desktop
Section titled “2. Prepare the desktop”macOS. Desktop control needs the Screen Recording (Screen & System Audio Recording on macOS 15 and later) and Accessibility permissions, and macOS grants them to the app that started malac-control. The reliable way is to start the service from a terminal inside the remote machine’s desktop session, for example over Screen Sharing, and grant that terminal both permissions in System Settings → Privacy & Security. Check from a terminal there with malac-control permissions, which shows what is granted and to which app; malac-control permissions --request shows the macOS prompts and opens System Settings at what is missing. Add that app with + if it is not listed. See macOS permissions. Browser control needs neither permission.
Linux. Run the service inside the remote user’s graphical session, so that it can reach the display. A source build of malac-control needs the X11 and D-Bus headers (see Installation).
Only browser control needed? Set computer.enabled = false in the remote’s ~/.malac/control.toml, and the desktop permissions do not matter.
3. Start the service with a fixed token
Section titled “3. Start the service with a fixed token”malac-control serve requires a token. Without one it makes up a random token and writes it to ~/.malac/control.json, but that file is on the remote machine, where your malac cannot read it. So pick a token and give it to both sides:
# on the remote machine, in a terminal in its desktop sessionexport MALAC_CONTROL_TOKEN="$(openssl rand -hex 24)"echo "$MALAC_CONTROL_TOKEN" # copy this to your machinemalac-control serve # listens on 127.0.0.1:7878| Option | Default | Meaning |
|---|---|---|
--host <ip> |
127.0.0.1 |
Address to listen on. An IP address, such as 0.0.0.0 or a private network address. |
--port <port> |
7878 |
Port |
--token <token> |
random | The token clients must send. Prefer the MALAC_CONTROL_TOKEN environment variable, which does not show up in process lists. |
The service logs to its terminal (RUST_LOG=debug for more), and when it stops, it closes the browsers it launched.
4. Reach it safely
Section titled “4. Reach it safely”The service speaks plain WebSocket: the token is checked on every connection, but nothing is encrypted. Do not expose port 7878 to the internet. Use one of these:
An SSH tunnel (recommended). Keep the service on 127.0.0.1 on the remote machine and forward the port from your machine:
ssh -N -L 7878:127.0.0.1:7878 user@remote-hostYour malac then connects to ws://127.0.0.1:7878 on your own machine, and SSH carries the traffic encrypted.
A private network. On a VPN or an encrypted overlay network you trust, listen on the remote’s private address instead and connect to it directly:
malac-control serve --host 10.0.0.125. Point malac at it
Section titled “5. Point malac at it”On your machine, give malac the address and the name of a variable that holds the token, in your user config (~/.malac/config.toml; a project’s config cannot set [control]):
[control]url = "ws://127.0.0.1:7878" # the SSH tunnel; or ws://10.0.0.12:7878token_env = "MALAC_REMOTE_CONTROL_TOKEN"export MALAC_REMOTE_CONTROL_TOKEN=... # the token from step 3malac mcp # checks the connection from this shell● control (28 tools)Then restart the daemon from that same shell, so it reads the new [control] settings and has the token variable in its environment (the daemon keeps the environment it was started with, and connects the control service once when it starts):
malac daemon restartWith [control] url set, malac connects only to that address: it no longer reads the local ~/.malac/control.json or spawns a local malac-control. Remove url and restart the daemon to go back to local control. If the connection fails, malac mcp shows the error under control; in the terminal UI, the View menu says the control service is not connected and the status line shows control unavailable.
To use the remote machine for one-off runs only, put the [control] table in a profile and pass it to a run in its own process:
[profiles.remote.control]url = "ws://127.0.0.1:7878"token_env = "MALAC_REMOTE_CONTROL_TOKEN"malac -p --profile remote "check the sign-up page on the remote machine"6. Browser profiles on the remote machine
Section titled “6. Browser profiles on the remote machine”Browser profiles belong to the service, so they live on the remote machine: configure them in its ~/.malac/control.toml, and their data directories are in its ~/.malac/browser/. Everything in Browser profiles applies there:
# ~/.malac/control.toml on the remote machine[browser.profiles.staging]
[browser]headless = false # show the windows on the remote desktop, so you can watch over Screen SharingLog in once inside a profile on the remote desktop, and the session stays in that profile. List the remote’s profiles with malac-control profiles on that machine.
Worked example: test a web app’s UI on a remote desktop
Section titled “Worked example: test a web app’s UI on a remote desktop”Say the remote machine runs a development build of your web app on port 3000, and you want malac to check the sign-up flow in a real browser there.
-
On the remote machine, start the app and the control service in its desktop session:
npm run dev # the app, on http://localhost:3000MALAC_CONTROL_TOKEN=... malac-control serve -
On your machine, open the tunnel and start malac:
ssh -N -L 7878:127.0.0.1:7878 user@remote-host &malac --name signup-testWith
[control] urlin your user config (step 5), every tab of the daemon drives the remote machine. -
Ask for the test, and say where things are:
Using the browser on the remote machine (profile "staging"), openhttp://localhost:3000/signup. Fill in the sign-up form with a made-uptest user, submit it, and check that the welcome page appears. Take ascreenshot at each step and report anything that looks broken: overlappingelements, cut-off text, error messages, or controls that do not respond. -
Watch it work. malac uses
browser_navigate, reads the page withbrowser_snapshot, fills the form withbrowser_typeandbrowser_click, and checks the result withbrowser_screenshot. Snapshots and screenshots are read-only and never ask; navigation, typing and clicks follow your permission mode, so approve them or pre-approve the browser:[permissions]allow = ["browser_*"]deny = ["browser_eval", "computer_*"] # no JavaScript, no desktop, for this kind of test -
For a native app instead of a web page, use the desktop tools: ask malac to take a
computer_screenshot, open the app withcomputer_open_app, and click and type at positions from the screenshot. Those need the desktop permissions from step 2.
If the model you use cannot read images, set a vision_model and mark the model vision = false, so screenshots are described in words; see Computer and browser control.
Security checklist
Section titled “Security checklist”- The token is the only thing standing between the network and the remote machine’s mouse and keyboard. Keep it out of prompts and repositories; use environment variables on both sides.
- Keep the service on
127.0.0.1and use an SSH tunnel, or a private network you trust. The WebSocket is not encrypted. - Give the remote machine a dedicated user account and test-only logins. The agent can do whatever that desktop session can.
- Deny the tools you do not need, such as
computer_*for browser-only tests orbrowser_eval. - Stop the service when you are done; it closes the browsers it launched.
malac is created by lobirus and released under the MIT license. About malac