meshTerm

User Guide

Everything you need to connect, authenticate, and work in the terminal from your iPhone or iPad.
meshTerm User Guide
Version 1.0 · 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.

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.

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

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).

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 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:

| ` ~ $ / \ { } [ ]

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.

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
Tailscale SSHYes
Tailscale device browsingYes
Snippet VaultYes
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.

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.