Multi-Server Setup
Kitty turns multi-server management into an organized, keyboard-driven workflow. Combine named tabs, the SSH kitten, and file transfer kittens to manage any number of remote servers.
Learning Focus
Build a complete multi-server workflow: one-command SSH with terminfo, named tabs per server, file transfer over TTY, and remote file editing.
Pattern 1: Named Server Tabs
Open each server in its own named tab for quick switching:
~/bin/server-tabs.sh
#!/bin/bash
SERVERS=(
"web01:deploy@web01.example.com"
"web02:deploy@web02.example.com"
"db01:admin@db01.example.com"
"cache01:admin@cache01.example.com"
)
for SERVER_ENTRY in "${SERVERS[@]}"; do
TAB_NAME="${SERVER_ENTRY%%:*}"
SSH_TARGET="${SERVER_ENTRY#*:}"
kitty @ launch --type=tab --title "$TAB_NAME"
kitty @ send-text --match-title "$TAB_NAME" "kitty +kitten ssh $SSH_TARGET\n"
sleep 0.5
done
echo "Opened ${#SERVERS[@]} server tabs"
Navigate Between Servers
| Shortcut | Action |
|---|---|
Ctrl+Shift+Left | Previous tab (previous server) |
Ctrl+Shift+Right | Next tab (next server) |
Ctrl+Shift+1-9 | Jump to tab by number |
Ctrl+Shift+l | List all tabs |
Pattern 2: Multi-Server Command Broadcasting
Run the same command on all servers:
~/bin/broadcast-cmd.sh
#!/bin/bash
CMD="$*"
if [ -z "$CMD" ]; then
echo "Usage: $0 <command>"
echo "Example: $0 systemctl status nginx"
exit 1
fi
# Use broadcast kitten with pattern matching on tab names
kitty +kitten broadcast --match "web*" --match "db*" "$CMD"
Examples
# Check disk space on all web servers
~/bin/broadcast-cmd.sh "df -h"
# Restart nginx everywhere
~/bin/broadcast-cmd.sh "sudo systemctl restart nginx"
# Check kernel version
~/bin/broadcast-cmd.sh "uname -r"
Pattern 3: File Transfer Between Servers
Use the transfer kitten to move files without SCP:
# From your local machine to a remote server via SSH
kitty +kitten ssh deploy@web01
# Inside the SSH session:
kitty +kitten transfer receive /tmp/config-backup.tar.gz
# Send a config file to a remote
kitty +kitten transfer send ./nginx.conf
Transfer Between Remote Servers
# From server A's SSH session, pull a file from server B
scp user@server-b:/path/to/file /tmp/
# Or set up the transfer across sessions using kitty's piping
Pattern 4: Remote File Editing
Edit files on remote servers using your local kitty config:
# Quick edit a remote config
kitty +kitten remote_file admin@web01:/etc/nginx/nginx.conf
# Edit multiple remote files
kitty +kitten remote_file admin@web01:/etc/nginx/sites-enabled/default
kitty +kitten remote_file admin@db01:/etc/postgresql/postgresql.conf
The remote_file kitten:
- Downloads the remote file via SSH
- Opens it in your local
$EDITOR - Watches for save
- Uploads the changed file back
Pattern 5: Three-Server Monitoring Layout
A complete script that creates a three-server monitoring tab:
~/bin/three-server-monitor.sh
#!/bin/bash
# Creates a monitoring layout: 3 servers side by side
# Each server split into: system stats + logs
TAB_TITLE="server-monitor"
kitty @ launch --type=tab --title "$TAB_TITLE"
sleep 0.3
# First server: web01
kitty @ send-text --match-title "$TAB_TITLE" \
"kitty +kitten ssh deploy@web01.example.com\n"
sleep 0.8 # Wait for SSH connection
kitty @ send-text --match-title "$TAB_TITLE" "htop\n"
# Split bottom for logs on web01
kitty @ launch --type=window --location=vsplit
kitty @ send-text --match-title "$TAB_TITLE" \
"tail -f /var/log/nginx/access.log\n"
# Add second server column: web02
kitty @ launch --type=window --location=hsplit
kitty @ send-text --match-title "$TAB_TITLE" \
"kitty +kitten ssh deploy@web02.example.com\n"
sleep 0.8
kitty @ send-text --match-title "$TAB_TITLE" "htop\n"
# Split bottom for logs on web02
kitty @ launch --type=window --location=vsplit
kitty @ send-text --match-title "$TAB_TITLE" \
"tail -f /var/log/nginx/error.log\n"
# Add third server column: db01
kitty @ launch --type=window --location=hsplit
kitty @ send-text --match-title "$TAB_TITLE" \
"kitty +kitten ssh admin@db01.example.com\n"
sleep 0.8
kitty @ send-text --match-title "$TAB_TITLE" "htop\n"
echo "Three-server monitoring tab created"
SSH Kitten Tips for Multi-Server
~/.ssh/config
# SSH config works seamlessly with kitty +kitten ssh
Host web*
User deploy
IdentityFile ~/.ssh/deploy_key
ServerAliveInterval 60
Host db*
User admin
IdentityFile ~/.ssh/admin_key
ForwardAgent yes
# With the config above, this is all you need:
kitty +kitten ssh web01
# Expands to: ssh deploy@web01 -i ~/.ssh/deploy_key
Multi-Server Management Reference
| Task | Command | Kitten Used |
|---|---|---|
| Connect to server with terminfo | kitty +kitten ssh user@host | ssh |
| Send file to remote | kitty +kitten transfer send ./file | transfer |
| Receive file from remote | kitty +kitten transfer receive ./file | transfer |
| Edit remote file | kitty +kitten remote_file user@host:/path | remote_file |
| Run command on multiple servers | kitty +kitten broadcast --match "web*" "cmd" | broadcast |
| View image on remote | kitty +kitten icat image.png (over SSH) | icat |
| Diff files on remote | kitty +kitten diff file1 file2 | diff |
Common Pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
| SSH kitten prompt for password repeatedly | No SSH key cached | Run ssh-add or use ssh-agent |
| Transfer fails on large files | "Broken pipe" | Use rsync or scp for files > 100MB |
| Tab names not unique | Wrong tab matched by broadcast | Include server name or IP in tab title |
| Remote shell not recognizing kitty TERM | TERM=kitty: unknown terminal | Use kitty +kitten ssh for automatic terminfo |
sleep timing causes dropped keystrokes | Commands typed before SSH connected | Increase sleep or use expect for SSH |
Hands-On Practice
# Practice the three-server layout pattern locally
kitty @ launch --type=tab --title "practice-multi"
# Simulate three windows with local shells
kitty @ send-text --match-title "practice-multi" "echo 'Server 1: web01'\n"
kitty @ launch --type=window --location=hsplit
kitty @ send-text --match-title "practice-multi" "echo 'Server 2: web02'\n"
kitty @ launch --type=window --location=hsplit
kitty @ send-text --match-title "practice-multi" "echo 'Server 3: db01'\n"
# Verify all three windows
kitty @ ls
# Send a command to all three using broadcast
kitty +kitten broadcast --match "practice-multi" "hostname\n"
echo "Broadcast sent — all three windows received the command"