Run it locally for a first try
Start VCode on your own machine with one command and open it in a browser. No token, no systemd, no tunnel.
Why you would use it
You cloned the repo and want to see the app before deciding to install it. You
are changing the code and need a server you can restart. You want to check that
your claude, codex or opencode CLI is wired up before putting the app on a
phone.
How to use it
- Install node 24 or newer.
install.shrefuses anything older (node >= 24 required), andpackage.jsondeclares"node": ">=24". - Install at least one agent CLI —
claude,codexoropencode— so it is on yourPATH. VCode spawns them by name. - Install the dependencies:
npm install. The only runtime dependency isexpress. - Start it:
npm start(which runsnode server.js). - Open
http://127.0.0.1:3444/. There is no token prompt, becauseAUTH_TOKENis unset.
For development, npm run dev instead of npm start. It restarts by port
rather than by process name, and it binds the tailnet IP when tailscale ip -4
answers.
What you see
On startup the server writes three kinds of line to stdout:
VCode on http://127.0.0.1:3444/state /home/you/.v-code/threadsauth: OFF (loopback only). Set AUTH_TOKEN to require a token.
The token is never printed. If the port is taken, the server prints
port 3444 is already in use — another VCode server is running. followed by
find it: ss -ltnp 'sport = :3444' replace it: npm run dev, and exits 1.
In the browser the app opens straight into the thread view. /health answers
authRequired: false, so public/app.js skips the token sheet entirely.
Options and settings
| Option | Default | What it changes |
|---|---|---|
VCODE_PORT |
3444 |
The port server.js listens on |
BIND_HOST |
127.0.0.1 |
The address it binds. A tailnet IP makes it reachable from the tailnet, and closes loopback |
AUTH_TOKEN |
(unset) | Sets a login token. Unset means auth off |
VCODE_DEFAULT_CWD |
~/git, or the home folder when there is no ~/git |
The folder a new thread starts in |
VCODE_DEV_RELOAD |
off unless set to 1 |
File watchers and the reload stream. npm run dev sets it; the unit sets 0 |
VCODE_ENABLE_MOCK_AGENT |
(off) | Adds a scripted mock agent. For tests only |
npm run dev also reads VCODE_LOG (default /tmp/v-code-<port>.log)
and VCODE_UNIT (no default: with none set it restarts by port). The server
and npm run dev still read the old WORKBENCH_* names; the new name wins
when both are set.
Limits and known gaps
- With auth off, every host that can route to the bind address runs commands as you: agents run with approvals bypassed. See trust-model-and-security-headers.
BIND_HOST=0.0.0.0publishes the app on your wifi LAN as well as the tailnet.- Plain
http://to a tailnet IP is not a secure context, so the browser gives no service worker, nocrypto.randomUUIDand nonavigator.clipboard. The app has fallbacks for the last two; installing it on a phone and opening it offline both need HTTPS. See reach-it-from-a-phone. - No firewall change is needed on Fedora Workstation: the default zone already
opens
1025-65535/tcpandtailscale0falls into it.
Related
- install-as-systemd-units — make it survive a reboot
- log-in-with-the-token — what changes once
AUTH_TOKENis set - environment-variables — every variable the server reads
- start-a-thread — the first thing to do once it is up
- the-three-agents — which CLI VCode spawns