Skip to content

Command line

Three programs have a command line today. All of them are built from source; there are no packages yet. A fourth, tealhand-power, is not built yet (it is planned for the next milestone).

usage: tealhand-host <command> [options]
commands:
run run Tealhand Host until Ctrl-C or SIGTERM
connect show a code in this terminal and connect a phone (quit a running Tealhand Host first)
unpair forget the connected phone, for a lost phone (refused while Tealhand Host is running)
remote off
keep remote control off from the next start; only this computer can switch it on again
(refused while Tealhand Host is running)
share list | add <path> | remove <id> | default <id>|none
the folders phones may browse; add takes --name <name>, --read-only and --downloads
(the folder phones offer first for downloads; default sets it later); refused while
Tealhand Host is running
downloads [cancel <id>]
what phones downloaded here, and stop one (works while Tealhand Host runs)
ssh on | off
SSH access: connected phones may open a terminal here and add commands (with
their fingerprint); off by default; `terminal` works as `ssh`
(refused while Tealhand Host is running)
commands list | add <key> <label> -- <line> | remove <key>
commands a phone may run by name; add takes --cwd <folder>, --fingerprint (the phone
must ask for the fingerprint) and --timeout <seconds> (default 1 day, at most 7 days);
the line is everything after --; refused while Tealhand Host is running
mcp for AI apps on this computer (Claude Desktop, LM Studio, ...): they launch this
command to read your other devices (status, shared folders, files; never a change)
mcp add | remove claude|lmstudio|cursor
add Tealhand to that AI app's MCP config, or take it out; the app's other
settings stay as they are, and the first change keeps a .tealhand-backup copy
mcp on | off | setup | folder <dir> | limit <MB>
let AI apps read your other devices (off by default); setup prints what to paste
into the AI app; folder is where copies go (default ~/Downloads/Tealhand); limit
is the largest copy (default 1024 MB); refused while Tealhand Host is running,
except setup
agent setup | remove claude
connect Claude Code: every tool call it would ask you about goes to your phone
(approve with your fingerprint; declined, no answer or Tealhand not running:
denied); writes hooks into ~/.claude/settings.json with a .tealhand-backup
copy; remove takes out only Tealhand's hooks
agent hook PermissionRequest | Notification | Stop
what Claude Code runs as a hook (set up by agent setup)
options:
--data-dir <dir> Tealhand Host's files (default: this user's Tealhand folder)
--relay <choice> disabled (default: this network only), public (n0's public relays),
or the https address of your own Tealhand Relay. With `connect` the
choice is saved and `run` uses it when no --relay is given.
--relay-pin <sha256:...>
your relay's certificate fingerprint, only for a self-signed
certificate (get it with tealhand-relay fingerprint). Needs --relay
with your relay's address; that relay must use this certificate.
--port <n> the UDP port to listen on (default: the one used last time, else a free
one). It is saved; if it is taken, a free one is used and saved instead.
--power-helper <path> the tealhand-power program (default: next to this program)
--name <name> this computer's name on the phone (default: its host name)
--help, --version
exit codes: 0 done, 1 failed while running, 2 wrong command, option or setting
A sample systemd user unit is in packaging/tealhand-host.service (Restart=on-failure).
Command What it does
run Starts Tealhand Host and keeps it running until Ctrl-C or SIGTERM. It logs “Tealhand Host is running”, with “, relay pinned” when a certificate fingerprint is in use
connect Starts a Host just for connecting a phone: prints the QR code in the terminal (or a note that it can’t be drawn), the code as text for “Paste the code” on the phone, then the phone’s name and the check code, and asks Connect? [y/N] (y, Y, yes or Yes connects). The QR works for 10 minutes. A --relay (with its --relay-pin, or none) given here is saved for run. The old name pair still works as an alias
unpair Forgets the connected phone: removes the device list and the rules, keeps the computer’s key, and writes a journal line
remote off Keeps remote control off from the next start, writes a journal line, and prints “Remote control is off from the next start. Only this computer can switch it on again.” Refused while a Host runs on the data folder. remote with anything but off is a command line error
share list Prints one line per shared folder: its number, name and path, then tags in brackets: read-only, default for downloads, and missing: share it again for a folder that was deleted or replaced. With none shared it says “No folder is shared. Share one with tealhand-host share add .”
share add <path> Shares a folder with connected phones. --name <name> (1 to 64 characters; default: the folder’s own name), --read-only (no changes from the phone), --downloads (makes it the default for downloads, which phones offer before the other folders; not with --read-only; only one folder can be the default). Prints “Shared it as folder N. Connected phones see it the next time they open Files.”
share remove <id> Stops sharing the folder with that number, from share list. Deletes nothing. Prints “Stopped sharing folder N. Phones can no longer open it.”
share default <id>, share default none Makes the folder with that number the default for downloads, or clears the default. Prints “Folder N is the default for downloads now.” or “No folder is the default for downloads now.” Refused while a Host runs on the data folder
downloads (or downloads list) Lists what phones downloaded here, one line each: the number, the file’s name, from <host>, into <folder> and the state: downloading 40%, paused (remote control is off), done, failed, stopped, or a web page; pick the file on the phone. With none it says “Nothing was downloaded here yet. Share a link with Tealhand on your phone.” Works while a Host runs
downloads cancel <id> Stops the running or paused download with that number. With no Host running it prints “Stopped download N. Its partial file was removed.”; with a Host running it prints “Asked the running Tealhand Host to stop download N. It stops within a second.” Works while a Host runs
ssh on, ssh off Turns SSH access on or off: with it on, a connected phone may open a terminal on this computer and add or remove saved commands, after its fingerprint. Off by default. The old name terminal on and terminal off still works. Refused while a Host runs on the data folder
commands list, commands add <key> <label> -- <line>, commands remove <key> The saved commands a phone may run by name. add takes --cwd <folder>, --fingerprint (the phone must ask for the fingerprint) and --timeout <seconds> (default 1 day, at most 7 days). The line is everything after --. A phone can also add and remove saved commands while SSH access is on; this is the way to do it at the computer. Refused while a Host runs on the data folder
mcp The stdio side of AI apps: an AI app launches it and it relays the app’s requests to the running Tealhand on this computer. While AI apps are off, or no Tealhand runs, it answers each request with how to fix that. Takes --data-dir
mcp on, mcp off Lets AI apps on this computer read your other devices, or stops it, from the next start. Off by default. A terminal at the computer needs no Windows Hello (the Tealhand app asks for it). Off also deletes the endpoint’s port and token, and takes Tealhand’s entry out of every AI app config it was added to. Writes a journal line. Refused while a Host runs on the data folder
mcp add <app>, mcp remove <app> Adds a tealhand entry that launches tealhand-host mcp to the MCP config of claude (Claude Desktop), lmstudio (LM Studio) or cursor (Cursor), or takes it out. Everything else in that file stays as it was; the first change copies the file to <file>.tealhand-backup once. Prints “Added Tealhand to Claude Desktop (). Restart Claude Desktop to use it.”, and “AI apps are off: turn them on with tealhand-host mcp on.” while they are off. An app that isn’t installed for this user, or a config that isn’t valid JSON, is left alone: the fix is mcp setup. Works while a Host runs
mcp setup Prints the MCP config to paste into the AI app (the tealhand-host mcp command form, with no token in it) and where copies go. Works while a Host runs
mcp folder <dir>, mcp limit <MB> Where download_file saves copies (default ~/Downloads/Tealhand), and the largest file it copies (1 to 65536 MB, default 1024). Refused while a Host runs on the data folder
agent setup claude, agent remove claude Connects Claude Code to your phone (guide): writes three hooks (PermissionRequest, Notification, Stop) that run this program into Claude Code’s user settings (~/.claude/settings.json, or CLAUDE_CONFIG_DIR), keeping everything else and copying the file to settings.json.tealhand-backup once; remove takes out only Tealhand’s hooks. Works while a Host runs (it notices within 5 s)
agent hook <event> What Claude Code runs. Reads the hook’s JSON on stdin; for PermissionRequest asks the phone through the running Host and prints Claude Code’s decision (allow only when a phone approved with the fingerprint; deny otherwise, with a short reason); for Notification and Stop sends a notice and prints nothing. Always exits 0
help, --help, -h Prints the usage above
--version Prints tealhand-host and its version

unpair, remote off, ssh, commands, the share commands and mcp on, off, folder and limit change files that a running Host also uses, so they refuse while one runs on the data folder: “Tealhand Host is already running for this data folder: quit it first”. Stop it first. downloads, downloads cancel, mcp, mcp setup and mcp add or remove are the exceptions: they work while the Host runs.

A folder can’t be shared when it is a whole drive, a system folder, Tealhand’s data folder, a link, or inside or around a folder that is already shared. At most 64 folders can be shared. See Share folders.

Option Default Notes
--data-dir <dir> Windows %LOCALAPPDATA%\Tealhand\host; Linux $XDG_DATA_HOME/tealhand/host or ~/.local/share/tealhand/host Made if missing
--relay <choice> The choice saved by connect, else disabled disabled, public, or an https:// address (at most 512 characters to be saved). connect saves it in settings.bin; run only reads it
--relay-pin <sha256:...> The fingerprint saved with the saved relay, else none sha256: and 64 hex digits. Only with --relay and your relay’s https:// address, never with disabled or public. For a relay with a self-signed certificate: the relay connection then accepts only that certificate. connect saves it; a connect --relay without --relay-pin clears a saved one
--port <n> The port used last time, else a free one 1 to 65535. The UDP port iroh listens on. It is saved in the data folder, so the address in a connection QR stays valid for run. If it is taken, a free port is used and saved instead
--power-helper <path> tealhand-power (tealhand-power.exe on Windows) in the same folder as tealhand-host Must be an absolute path. In release builds the file must exist, and on Unix neither it nor its folder may be writable by group or others, and both must be owned by you or root. tealhand-power is not built yet, so use a debug build for now
--name <name> The host name, cleaned and cut to 64 characters; “This computer” when there is none 1 to 64 characters, no control characters. With share add, it names the folder instead
--read-only, --downloads off Only with share add. --downloads makes the folder the default for downloads

Options come after the command. Each option that takes a value takes one value.

The sample unit for systemd is crates/tealhand-host/packaging/tealhand-host.service: see Install Tealhand Host on Linux.

Environment variable Used for
RUST_LOG Log filter. Default error,tealhand_host=info,tealhand_mesh=warn
LOCALAPPDATA (Windows), XDG_DATA_HOME and HOME (Linux) The default data folder. A relative XDG_DATA_HOME is ignored
COMPUTERNAME, then HOSTNAME, then /etc/hostname The default computer name
Exit code Meaning
0 Done: run stopped cleanly, connect connected a phone, unpair forgot the phone, remote off, ssh, commands, downloads, an mcp command or a share command did its work, or help and version
1 Failed while running: Tealhand Host could not start (for example “Tealhand Host is already running for this data folder: quit it first”, a bad computer name, a power helper path that is not absolute, or in a release build a missing power helper), connecting was cancelled, timed out or failed, or unpair, remote off, ssh, commands, downloads, an mcp command or a share command could not do their work (for example mcp add for an AI app that isn’t installed)
2 Wrong command, option or setting: an unknown command or option, remote without off, share without list, add, remove or default, ssh without on or off, downloads cancel without a number, mcp with an unknown word, mcp add or remove without claude, lmstudio or cursor, mcp limit outside 1 to 65536, a missing value, a relay address that is not https://, a bad --port or --relay-pin, a folder that can’t be shared, or no data folder found

Every error is two lines on stderr: error: and what happened, then the fix. For example:

error: --relay-pin needs --relay
Add your relay's address with --relay https://..., or leave --relay-pin out.
usage: tealhand-relay --config <file.toml>
tealhand-relay fingerprint --config <file.toml>
Command and option What it does
--config <file> Runs the relay with this config file until Ctrl-C or SIGTERM. The format: Relay config
fingerprint --config <file> Prints the SHA-256 fingerprint of the certificate named in the config, alone on one line: sha256: and 64 hex digits. It is the value for the phone’s Certificate fingerprint field and for tealhand-host --relay-pin. The relay also logs it at every start
--help, -h Prints the usage, the licence (GNU AGPL-3.0-only, no warranty) and the source code address
Environment variable Used for
RUST_LOG Log filter. Default error,iroh_relay=error,tealhand_relay=info
Exit code Meaning
0 Stopped by Ctrl-C or SIGTERM, or printed help or a fingerprint
1 The relay could not start (for example the TLS key is readable by others, a stored device list does not verify, or a port is taken), or the relay server stopped by itself (it logs “the relay server stopped”), so a supervisor with restart-on-failure restarts it
2 Bad command line, or the config file could not be read or is not valid
tealhand-planner --bind 127.0.0.1:8787 --model <ollama model>
Option Environment variable Default Notes
--bind <addr> TEALHAND_PLANNER_BIND none, required An IP and port. 0.0.0.0, :: and their IPv4-mapped form are refused
--model <name> TEALHAND_PLANNER_MODEL none, required Names containing :cloud or -cloud are refused
--ollama-url <url> TEALHAND_PLANNER_OLLAMA_URL http://127.0.0.1:11434 http:// with a loopback IP, no host names, no user or password
--timeout-secs <n> 30 1 or more. Seconds for one request, the model call included
--max-concurrent <n> 2 1 or more. Model calls at once
--rate-burst <n> 10 1 or more. Requests one client address may send in a burst
--rate-per-minute <n> 30 1 or more. Requests per minute one client address may keep up
--help, --version Print help or the version

It logs at info level to standard output: the listening address, then one line per request with the status code, the duration in milliseconds and the number of steps. Ctrl-C stops it.

Exit code Meaning
0 Stopped by Ctrl-C, or printed help or version
1 Could not start: a refused bind address, Ollama URL or model name, or the port is taken
2 Bad command line (a missing or invalid option)