exe's settings are in one file, ~/.exe/config.json. Windows → Configuration edits it in place, and Windows → Log Viewer shows what the daemon is doing and who is calling its API.
An agent reads the same over HTTP: GET /v1/config is the whole configuration, and GET /v1/logs and GET /v1/logs/access stream the two logs. Chat can read the end of the daemon log as well, to work out why a publish or a VM failed. Changing the configuration is yours to do: an agent leaves it alone unless you ask.
The fields are grouped on tabs: General, Daemon, VMs, Ollama, OpenAI, GitHub, Hub and Cloudflare, and on a Linux machine Firecracker, which runs the VMs there. Change what you want and press Save.
* take effect after a daemon restart: ssh_user, image_url and everything on the Firecracker tab. Restart Daemon…, on the Daemon tab, does it when pressed twice; the VMs restart too.listen, proxy_listen and ssh_listen rebind as you save. If listen moved, reload the page at the new address.listen with that address for you to save.A few keys have no field in the window; vm_dir, the folder that holds the VMs' disks, is one. Edit the file for those and restart the daemon, which reads the file when it starts. Configuration, on the website, has a longer table of the keys, vm_dir among them.
Language, on the General tab, is the language of the desk: English, 简体中文 (Simplified Chinese) or 日本語 (Japanese). Choose one and press Save. Every screen that has this node's desk open loads it again in that language. A screen with unsaved work on it waits until the work is saved, as it does for an update.
language in the file: en, zh-Hans or ja. It is English when the key is not there.| Key | Tab | What it sets |
|---|---|---|
language | General | The language of the desk's menus, windows and messages: en, zh-Hans or ja. |
listen | Daemon | The address of this UI and API. Bind it to your Tailscale IP to use exe from your phone. |
api_token | Daemon | Set it before listening beyond localhost; every API call then needs it. |
ssh_listen | Daemon | The address of the SSH gate, :2222 unless changed; off disables it. |
ssh_user | Daemon | The user created in every VM (default dev). It is marked *. |
default_cpus, default_memory_mb, default_disk_gb | VMs | The size of a new VM when you leave its fields empty: 2 CPUs, 2048 MB and 20 GB unless changed. |
ollama.*, chat_provider, openai.model | Ollama, OpenAI | See The coding agent. |
github.client_id | GitHub | See Publishing to GitHub. |
hub.* | Hub | See The Hub. |
cloudflare.* | Cloudflare | See Publishing to the web. |
The desktop asks for the token by itself the first time a browser opens it, and checks it before keeping it (in localStorage).
The token goes on no address. Each time the desktop loads, it gives the token to exe and gets back a cookie that only exe's own pages can use and that no script can read. App windows, apps opened from /apps/, terminals and movies get in with that cookie. A new token ends every such cookie at once: each open terminal window says "signed out", and the desktop asks for the token again. The Terminal sessions stay in tmux, and the windows come back to them after you sign in. In a browser that keeps no cookies, the desktop puts the token on those addresses instead.
exe token, run on the machine that runs exe, shows it again.A passkey signs a browser in to exe in place of the API token, with Face ID, Touch ID, Windows Hello or a security key. On a phone, you no longer type the token.
A browser that signs in with a passkey keeps no token. It stays signed in until you remove the passkey or the token changes.
Windows → Log Viewer streams two logs live, a tab each, when something needs a closer look.
~/.exe/daemon.log.~/.exe/access.log: one line each with the time, the caller's address, the request, its status, size and duration, and for Tailscale Serve the tailnet login.API tokens in the URL are written as redacted, and in both logs every email address is masked to its first letter and domain ([email protected] shows as s***@example.com).
The access log's file moves to access.log.1 at 64 MB, so the two keep about twelve days of requests while two desktops are open.
Each tab has a Filter field at its top. It shows only the lines holding every word you type, in any case, and a word starting with - leaves out the lines holding it (GET -healthz).
A line you have scrolled up to stays under your eye while the log keeps filling:
This page lives at /docs.md, and the machine-readable counterpart for agents at /skill.md.