meshTerm

User Guide

Everything you need to connect, authenticate, and work in the terminal from your iPhone or iPad.
meshTerm User Guide
Version 1.1 · iOS & iPadOS

Overview

meshTerm is an SSH terminal client for iPhone and iPad. It lets you connect to remote servers using password or SSH key authentication, and integrates with Tailscale to browse and connect to your Tailnet devices directly from the app.

Beyond the terminal, meshTerm includes multi-session tabs with keyboard shortcuts, an SFTP file browser that integrates with the iOS Files app, a terminal macro bar for one-tap commands, and automatic tmux attachment so sessions survive dropped connections.

meshTerm Host List
The main host list dashboard.

Prerequisites

For all connections

  • A server with SSH enabled and accessible from your device
  • Your server's hostname or IP address, port, and a valid username

For password authentication

  • The password for your server account

For SSH key authentication Pro

  • An Ed25519 SSH key pair. You can generate one inside meshTerm, or bring your own unencrypted OpenSSH key.
  • The corresponding public key added to ~/.ssh/authorized_keys on the server

For Tailscale SSH Pro

  • Tailscale app installed on your iPhone/iPad — meshTerm routes connections through the Tailscale VPN tunnel, which requires the Tailscale app to be running and connected
  • Both your iPhone and the target server must be on the same Tailnet
  • The server must have Tailscale SSH enabled in your Tailnet ACLs

For Tailscale device browsing Pro

Getting Started

Adding your first host

  1. Open meshTerm. You will see the host list (empty on first launch).
  2. Tap + in the top-right corner.
  3. Fill in the connection details:
    • Label — a friendly name for this connection (e.g. "My Server")
    • Hostname or IP — the address of your server
    • Port — defaults to 22
    • Username — your account name on the server
  4. Under Authentication, choose a method and enter your credentials.
  5. Tap Add to save.
Add Host Screen
Adding a new SSH host.
Edit Host Screen
Editing existing host details.

Connecting

Tap any host in the list to open a terminal session. meshTerm connects immediately — you will see a "Connecting…" indicator while the session is being established.

Managing SSH Hosts

Editing a host

Swipe right on a host and tap Edit, or long-press the row to reveal options.

Deleting a host

Swipe left on a host and tap Delete.

Host limit

Free accounts can save 1 host. meshTerm Pro removes this limit.

Connecting to a Host

When you tap a host, meshTerm:

  1. Resolves the hostname and opens a TCP connection to the server.
  2. Verifies the server's host key against your saved known hosts (see Known Hosts).
  3. Authenticates using the method configured for that host.
  4. Requests a PTY and launches a shell session.
  5. Attempts to attach to a tmux session on the server (see tmux attach).

The terminal becomes interactive as soon as the shell is ready.

tmux attach

New hosts attach to tmux by default. When you reconnect, meshTerm re-attaches to the same session so your work survives dropped connections, backgrounded apps, and closed tabs.

  • If tmux is not installed on the server, meshTerm falls back gracefully to a standard shell — no configuration required.
  • You can disable automatic tmux attach per host from the edit screen if you prefer a plain shell.

Automatic reconnection

meshTerm watches the network path and your app's foreground state. If the connection drops — Wi-Fi in a lift, cellular-to-Wi-Fi handoff, backgrounding the app — the session reconnects automatically when the network returns or you bring the app back to the foreground.

A dim -- reconnected -- marker is drawn into the terminal so you can see exactly when the reattach happened. With tmux attach, you pick up where you left off.

Environment variables

You can attach custom environment variables to any host. These are sent to the shell session on connect. To add them, edit the host and use the Environment Variables section.

Disconnecting

Close the terminal view or terminate the shell session from the server side (e.g. exit, logout, or Ctrl+D).

Multi-Session Tabs

meshTerm supports multiple concurrent SSH sessions. A session bar sits above the terminal showing each open connection; tap a tab to switch, or swipe to dismiss it. Each session runs independently — run a build on one host while you tail logs on another, and switch between them in a single tap.

Opening and closing sessions

  • Tap a host in the host list to open it in a new tab.
  • Tap another host to add a second tab — the existing session stays alive in the background.
  • Swipe a tab down in the session bar, or close the terminal view, to end that session.

Keyboard shortcuts

With a hardware keyboard (Magic Keyboard, Smart Folio, or any Bluetooth keyboard) attached:

ShortcutAction
⌘ TOpen a new session (returns to host list to pick a host)
⌘ KClose the current session
⌘ 1 – ⌘ 9Jump directly to the tab at that position
⌘ [Switch to the previous tab
⌘ ]Switch to the next tab

Session persistence

Each tab is a live SSH connection. When paired with tmux attach and automatic reconnection, tabs survive the app going to the background or losing the network — they reconnect silently when you return.

Authentication Methods

Password

Enter your password when adding or editing the host. Passwords are stored securely in the iOS Keychain and never written to disk in plain text.

SSH Key Pro

Select one of your saved SSH keys when adding or editing the host. The private key never leaves your device — meshTerm signs the authentication challenge locally and sends only the public key to the server.

To use SSH key authentication:

  1. Generate or import a key in Settings → SSH Keys (see SSH Key Management).
  2. Copy the public key and add it to ~/.ssh/authorized_keys on your server.
  3. When adding or editing a host, set the auth method to SSH Key and select the key.

Tailscale SSH Pro

For servers on your Tailnet with Tailscale SSH enabled, no password or key is required. Tailscale authenticates the connection at the network layer using your device's Tailscale identity.

Requirements:

  • Tailscale app installed and connected on your iPhone/iPad
  • Server enrolled in the same Tailnet with Tailscale SSH enabled in ACLs
  • On the remote host: sudo tailscale up --ssh
Tailscale SSH authentication is handled entirely by the Tailscale app — meshTerm does not send any credentials for these connections.

SSH Key Management

Access SSH keys via Settings → SSH Keys.

Generating a new key

Generating a key is a two-step process. First, the key is created and saved; then you have the option to install it on a host without leaving the sheet.

  1. Tap Add Key.
  2. Enter a label (e.g. "Work iPhone").
  3. Tap Generate. meshTerm creates a new Ed25519 key pair, saves it securely in the iOS Keychain, and keeps the sheet open.

The public key is shown in the key list in OpenSSH format:

ssh-ed25519 AAAA... Work iPhone

The comment at the end reflects the label you gave the key. Tap Done to close the sheet at any time.

Installing a key on a host

If you have any saved hosts, an Install on a Host section appears on the sheet immediately after the key is generated. This lets you push the public key to a host in one step — no manual copy-and-paste into authorized_keys required.

  1. In the Install on a Host section, select a host from the picker.
  2. Tap Install Key.

meshTerm opens a non-interactive exec channel to the selected host (no PTY or shell session is started) and appends the public key to ~/.ssh/authorized_keys on the server. The connection uses the credentials already stored for that host.

Known host required. Installation uses strict host key verification — TOFU prompting is not shown during this flow. If the host's key is not yet trusted, a message in the footer will tell you to connect to that host via the terminal first, then return to install the key.

Once the key is installed successfully, the status updates in the sheet. Tap Done to dismiss.

Importing an existing key

  1. Tap Add Key → Import.
  2. Paste your unencrypted OpenSSH private key (the full contents of the file, including the -----BEGIN OPENSSH PRIVATE KEY----- and -----END OPENSSH PRIVATE KEY----- lines).
  3. Tap Import.
Import SSH Key
Importing keys.

Requirements for import:

  • Ed25519 keys only
  • Unencrypted (no passphrase). To strip a passphrase: ssh-keygen -p -N "" -f ~/.ssh/id_ed25519

Copying a public key

Tap the copy icon next to a key to copy the full OpenSSH public key to your clipboard. Paste this into ~/.ssh/authorized_keys on your server.

Deleting a key

Swipe left on a key and tap Delete. The private key is permanently removed from the Keychain.

If you delete a key that is assigned to a host, that host will fail to connect until you edit it and assign a different key.

Key storage

  • Private keys are stored as 32-byte Ed25519 seeds in the iOS Keychain, protected at rest by the device's secure enclave.
  • Private keys are marked WhenUnlockedThisDeviceOnly — they cannot be backed up to iCloud or moved to another device.
  • Public keys are stored in UserDefaults for display purposes only.

Tailscale Integration

meshTerm integrates with the Tailscale VPN to let you browse your Tailnet and add devices directly as SSH hosts.

Prerequisites

  • meshTerm Pro
  • Tailscale app installed and connected to your Tailnet
  • A read-only Tailscale API token (see below)

Getting a Tailscale API Token

In meshTerm, tap Settings → Tailscale → How to get an API token for in-app instructions. The steps are:

  1. Go to tailscale.com and sign in.
  2. Navigate to Settings → Personal Settings → Keys.
  3. Under API Access Tokens, click Generate token.
  4. Give the token a label (e.g. "meshTerm").
  5. Set an expiry — 90 days is recommended.
  6. Leave permissions as read-only (meshTerm does not need write access).
  7. Copy the token.
  8. In meshTerm, go to Settings → Tailscale → API Token and paste it in.
Your API token is stored securely in the iOS Keychain. meshTerm uses it only to fetch your device list and never modifies your Tailnet configuration.

Browsing your Tailnet

  1. Tap the globe icon in the host list toolbar.
  2. Your Tailnet devices are listed with their hostname, IP address, and operating system.
  3. Enter a username (applied to all devices added in this session).
  4. Tap + next to a device to add it as an SSH host.

Devices added from the Tailnet browser are automatically configured to use Tailscale SSH auth (if you are on Pro).

Tailnet Device Browser
Browsing active devices on your Tailnet.

API token expiry

Tailscale API tokens expire. When your token expires, the Tailnet browser will show an error. Return to Settings → Tailscale and generate a new token using the steps above.

Snippet Vault

The Snippet Vault (Pro) is a searchable library of terminal commands you can send to the active session with a single tap.

Access it from the snippets button in the terminal toolbar.

Snippet Vault
Searchable command library with folders.

Default snippets

meshTerm ships with two folders of pre-loaded snippets:

Linux — common admin commands including ls -lah, df -h, ps aux, ss -tuln, tail -f /var/log/syslog, systemctl status, and more.

OpenClaw — commands for OpenClaw including openclaw update, openclaw doctor, openclaw models list, openclaw gateway status, and openclaw memory index --force.

Using a snippet

Tap any snippet to send the command text directly to the terminal. The Vault closes automatically and the command is typed into your active session.

Adding snippets

  1. Tap + in the Snippet Vault toolbar.
  2. Enter a title and the command text.
  3. Optionally assign it to a folder and add tags.
  4. Tap Save.

Searching

Use the search bar at the top of the Vault. meshTerm searches across snippet titles, command text, and tags.

Folders

Tap New Folder to organise snippets. Tap a folder to view only its snippets. Deleting a folder does not delete its snippets — they move to the root level.

Terminal Macro Bar Pro

The Terminal Macro Bar is a scrollable row of one-tap commands that sits directly above the keyboard accessory, ready in every session. Put your most-used commands — git status, docker ps, tail a log, restart a service — on standby and fire them with a single tap.

Using macros

Scroll the macro row horizontally above the keyboard and tap a macro to send its command to the active terminal. Each tap sends the text followed by Return, so the command runs immediately.

The Macro Editor

Open Settings → Keyboard → Macros to manage your macro list. From the editor you can:

  • Add a macro — give it a short label (what appears on the bar) and the command text.
  • Edit an existing macro — tap a row to change its label or command.
  • Reorder macros by dragging rows. The order in the editor matches the order on the bar.
  • Delete a macro by swiping its row.
  • Restore defaults to bring back meshTerm's built-in macro set.

Default macros

meshTerm ships with a small starter set you can keep, edit, or replace entirely — use Restore defaults at any time to bring them back.

SFTP File Browser Pro

The SFTP browser lets you move files on and off your servers without leaving meshTerm. It runs over the same SSH transport as your terminal sessions — no additional credentials, no extra apps, no third-party cloud in the middle.

Opening the browser

  1. From the host list, tap the folder icon next to a host, or open the host's detail screen and tap Browse files.
  2. meshTerm opens an SFTP channel over the existing SSH connection and shows the contents of the home directory.
SFTP requires the server to support the SFTP subsystem (enabled by default in OpenSSH). Tailscale SSH nodes are supported the same way as any other host.

Navigating

  • Tap a folder to enter it. Tap Back in the navigation bar to go up a level.
  • Pull down to refresh the current directory listing.
  • The current path is shown in the title bar.

Downloading files

  1. Tap a file to start a download. A progress indicator shows bytes transferred.
  2. When the download completes, meshTerm offers to save the file via the iOS Files sheet — pick iCloud Drive, On My iPhone, or any Files-compatible location.
  3. A Saved to Files confirmation appears once the file is written.

Uploading files

  1. Tap Upload in the browser toolbar.
  2. Pick one or more files from the iOS Files sheet — iCloud Drive, Dropbox, On My iPhone, or any provider.
  3. meshTerm uploads the files to the current remote directory and shows progress per file.

File operations

Long-press a file or folder for options:

  • Rename — enter a new name; the server-side rename is atomic where supported.
  • Delete — confirm and meshTerm removes the file or folder. Non-empty folders are not deleted in one pass — empty them first.
  • New Folder (toolbar) — create a new directory in the current path.
All SFTP operations run over the active SSH session's encrypted channel. Credentials never leave your device, and nothing is routed through a third-party server.

Terminal Controls

Terminal UI
Active shell with modifier row.
Symbol Strip
The extended symbol strip.
Function Keys
F1–F12 and navigation keys.

Modifier keys

KeyDescription
CtrlOne-shot Ctrl modifier. Tap once, then press a key (e.g. C, D, Z, L). Releases automatically after one keystroke.
EscSends the Escape character. Use to exit insert mode in vim or cancel prompts.
AltOne-shot Alt/Meta modifier. Use for word navigation: Alt+F (forward word), Alt+B (back word).
TabSends Tab for shell autocompletion.

Common Ctrl sequences

SequenceAction
Ctrl + CInterrupt — stop the running command
Ctrl + DEnd of input — log out or close session
Ctrl + ZSuspend — background the current process
Ctrl + LClear — redraw the screen
Ctrl + AMove cursor to beginning of line
Ctrl + EMove cursor to end of line
Ctrl + RReverse history search
Ctrl + WDelete the word before the cursor

Arrow keys

  • ↑ / ↓ — Navigate command history; move cursor in full-screen apps (vim, htop)
  • ← / → — Move cursor; scroll through menus in full-screen apps

Extended keys

Tap the keyboard dismiss button to reveal the full extended key row:

  • F1–F12 — Function keys
  • Home / End — Jump to start/end of line
  • Page Up / Page Down — Scroll one screen at a time

Symbol strip

The symbol strip provides quick access to commonly used characters:

| ` ~ $ / \ { } [ ]

Hide Keyboard button

Tap the keyboard-dismiss button in the terminal toolbar to drop the on-screen keyboard entirely. Useful for reading long output (logs, man pages, build output) without an accessory row eating half the screen. Tap the terminal to bring the keyboard back.

Hardware keyboard auto-hide

Connect a Magic Keyboard, Smart Folio, or any Bluetooth keyboard and meshTerm's on-screen accessory bar disappears automatically, giving you a full-screen terminal. Disconnect and it reappears. There is no setting to toggle — meshTerm observes the connected keyboard and hides the accessory for you.

While a hardware keyboard is attached, the multi-session keyboard shortcuts (⌘T, ⌘K, ⌘1–9, ⌘[, ⌘]) are also available.

Security

Known Hosts (TOFU)

meshTerm uses Trust On First Use (TOFU) to verify server identity. The first time you connect to a host, meshTerm presents the server's host key fingerprint and asks you to confirm before proceeding.

  • Tap Trust & Connect to accept the fingerprint and save it.
  • Tap Cancel to abort the connection.

On subsequent connections, meshTerm checks the fingerprint automatically. If it has changed, the connection is blocked with a security warning (see Host key mismatch).

Viewing and managing known hosts

Go to Settings → Known Hosts to see all trusted hosts. Swipe left on an entry to delete it.

If a server's host key legitimately changes (e.g. after a rebuild), delete the old entry from Known Hosts and reconnect to accept the new fingerprint.

Credential storage

All sensitive data is stored in the iOS Keychain:

  • SSH private keys
  • SSH passwords
  • Tailscale API tokens

Nothing sensitive is written to iCloud backup, UserDefaults, or the filesystem.

App Lock

meshTerm can be locked with Face ID, Touch ID, or your device passcode. When enabled, the app locks automatically when it moves to the background and requires biometric or passcode authentication to reopen.

Enable app lock in Settings → App Lock.

App Lock requires a device passcode to be set. If no passcode is configured, you will be prompted to set one in iOS Settings → Face ID & Passcode.

Settings

SSH Keys

Manage your SSH key pairs. See SSH Key Management.

Keyboard → Macros

Add, edit, reorder, or delete the macros shown on the Terminal Macro Bar. Use Restore defaults to bring back the built-in starter set.

App Lock

Require Face ID, Touch ID, or the device passcode to open meshTerm. See App Lock. Requires an iOS passcode to be set on the device.

Security → Known Hosts

View and delete trusted host fingerprints. See Known Hosts.

Tailscale → API Token

Enter your read-only Tailscale API token to enable Tailnet device browsing. See Tailscale Integration.

About

Shows the current app version and links to the Privacy Policy and Terms of Use.

meshTerm Pro

meshTerm Pro unlocks the following features:

FeatureFreePro
Saved hosts1Unlimited
Password authenticationYesYes
SSH key authenticationYes
Generate / import SSH keysYes
Install key on a hostYes
Tailscale SSHYes
Tailscale device browsingYes
Snippet VaultYes
Terminal Macro BarYes
SFTP file browserYes
Multi-session tabsYesYes
Automatic tmux attach & reconnectYesYes
Known hosts managementYesYes
Terminal emulationYesYes
App LockYesYes

Subscribing

Tap Upgrade in Settings or the paywall prompt. Pro is available as a monthly or annual subscription — the annual plan is the best value.

Restoring purchases

Tap Restore Purchases in Settings if you reinstall the app or switch devices.

Troubleshooting

Connection issues

"Could not resolve '[hostname]'"

The device cannot look up the hostname via DNS.

  • Check the hostname is spelled correctly.
  • Check your device has a working internet connection.
  • If using a local hostname (e.g. myserver.local), ensure you are on the same local network.

"Could not connect to [host]:[port]"

The TCP connection was refused or timed out.

  • Verify the server is online and accessible.
  • Check the port number is correct (default SSH is 22).
  • Confirm SSH is running on the server: sudo systemctl status ssh.
  • If connecting to a local network address, ensure meshTerm has Local Network permission: go to iOS Settings → Privacy & Security → Local Network and enable meshTerm.

"The connection was closed"

The server terminated the session.

  • The server may have timed out an idle connection. Reconnect and consider setting ClientAliveInterval on the server.
  • The shell may have exited normally (e.g. you typed exit).

Connection hangs at "Connecting…"

  • Check your network connection.
  • If connecting via Tailscale, ensure the Tailscale app is open and connected to your Tailnet.
  • Try toggling Tailscale off and on.

Authentication issues

"No SSH key selected. Edit the host and choose a key."

The host is set to SSH key authentication but no key has been assigned.

  • Go to the host list, swipe left on the host, and tap Edit.
  • Under Authentication, select a key from the Key picker.
  • If no keys are listed, go to Settings → SSH Keys and generate or import one first.

SSH key auth fails silently or server rejects key

  • Confirm the public key is in ~/.ssh/authorized_keys on the server.
  • Ensure the ~/.ssh directory has permissions 700 and ~/.ssh/authorized_keys has permissions 600 on the server.
  • Check sshd_config on the server has PubkeyAuthentication yes.

Password auth fails

  • Double-check the username and password.
  • The server may require key-based auth only. Check /etc/ssh/sshd_config for PasswordAuthentication no.

Tailscale issues

"Enter your Tailscale API token in Settings first."

You opened the Tailnet browser without an API token configured.

"Invalid or expired token."

Your API token has expired or is invalid.

Tailnet devices are missing from the browser

  • Only authorised devices appear in the browser. Check your Tailnet's device authorisation settings.
  • Confirm the API token was generated for the correct Tailnet account.
  • Try pulling to refresh the device list.

Tailscale SSH connection fails

  • Confirm the Tailscale app is installed, open, and connected to your Tailnet.
  • Confirm the target device is online in your Tailnet (visible in the Tailscale admin console).
  • Confirm Tailscale SSH is enabled in your Tailnet ACLs for the target device. See Tailscale SSH docs.
  • Both your iPhone and the server must be on the same Tailnet.

Security warnings

Host key mismatch

⚠ Host key mismatch for [hostname]!
Stored: [expected fingerprint]
Received: [actual fingerprint]

The server's host key has changed since you last connected. This can indicate:

  • Legitimate change: the server was rebuilt or its SSH keys were regenerated.
  • Security issue: a man-in-the-middle attack.

If you are confident the key change is legitimate:

  1. Go to Settings → Known Hosts.
  2. Find the entry for the affected host and swipe left to delete it.
  3. Reconnect — you will be prompted to trust the new fingerprint.

If you are not sure, do not connect and investigate the server directly.

Key installation issues

"Connect via the terminal first to trust this host."

The host's key is not yet in your known hosts store. The Install on a Host flow uses strict verification and will not prompt you to trust an unknown host.

  • Tap the host in the main host list to open a normal terminal session.
  • Accept the host key fingerprint when prompted.
  • Return to Settings → SSH Keys, tap the key, and use Install on a Host again.

Installation fails with an authentication error

  • The credentials stored for the selected host may be incorrect or the account may not have permission to write to ~/.ssh/authorized_keys.
  • Try connecting to the host via the terminal to confirm the credentials work, then retry the installation.

Key appears to install but authentication still fails

  • Confirm the ~/.ssh directory has permissions 700 and ~/.ssh/authorized_keys has permissions 600 on the server.
  • Check that PubkeyAuthentication yes is set in /etc/ssh/sshd_config on the server.
  • If the file had incorrect permissions before installation, correct them and reconnect.

SSH key import errors

"The key format is not recognised."

  • Ensure you are pasting the entire private key file, including the -----BEGIN OPENSSH PRIVATE KEY----- and -----END OPENSSH PRIVATE KEY----- header and footer lines.
  • The key must be in OpenSSH format, not PEM/PKCS8. To convert: ssh-keygen -t ed25519 -m OpenSSH.

"Encrypted (passphrase-protected) keys are not supported."

meshTerm does not support passphrase-protected keys. To remove the passphrase from an existing key:

ssh-keygen -p -N "" -f ~/.ssh/id_ed25519

"Unsupported key type. Only Ed25519 keys are supported."

meshTerm supports Ed25519 keys only. To generate a compatible key:

ssh-keygen -t ed25519 -C "your label"

App Lock issues

"meshTerm requires a device passcode to protect your SSH credentials."

App Lock requires a device passcode to be set before it can be enabled.

  • Go to iOS Settings → Face ID & Passcode and set up a passcode.
  • Return to meshTerm and enable App Lock in Settings.

Snippet Vault

Snippets are not sent to the terminal

  • Ensure you have an active terminal session open before opening the Snippet Vault.
  • If the session was disconnected, reconnect and try again.

SFTP File Browser

"SFTP subsystem not available" or the browser fails to open

  • The server does not have the SFTP subsystem enabled. In OpenSSH, ensure /etc/ssh/sshd_config contains Subsystem sftp /usr/lib/openssh/sftp-server (the exact path varies by distro) and restart sshd.
  • The user's login shell may be restricted (e.g. /usr/sbin/nologin, rbash). SFTP needs a shell the SSH server can invoke.

Permission denied when renaming, deleting, or creating folders

  • Your account needs write permission on the target directory. Check with ls -la on the server.
  • Some SFTP servers deny rename across filesystems — keep the rename target in the same directory.

Uploads or downloads stall mid-transfer

  • If the SSH session itself drops, the transfer is cancelled. Check your connection and retry — automatic reconnection will restore the session and you can start the transfer again.
  • Very large transfers (multi-GB) are supported but depend on the stability of both endpoints and any firewall/NAT idle timeouts in between.

Terminal Macro Bar

Tapping a macro does nothing

  • You need an active terminal session — the macro bar sends text to the focused tab.
  • Confirm the macro's command text is not empty in Settings → Keyboard → Macros.

Purchases

"Purchase could not be verified."

There was a problem verifying your purchase with the App Store.

  • Ensure your device has a working internet connection.
  • Try Restore Purchases in Settings.
  • If the issue persists, contact Apple Support via the App Store.

meshTerm is developed by James Betchley. For support or feedback, please open an issue on GitHub.