# franc417/tailscale-ssh architecture

> Architecture diagram of the GitHub repository franc417/tailscale-ssh, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/franc417/tailscale-ssh
- Repository: https://github.com/franc417/tailscale-ssh

## Overview

Tailscale SSH is a single-file CLI for discovering tailnet devices, checking SSH readiness, and connecting to a selected device. Its documented workflow also includes setup, account management, diagnostics, and configuration. The sampled source confirms monitoring and connection behavior; several command implementations and integrations are documented in the README but were not sampled, so their internal wiring is shown only where the command dispatcher owns it.

Main entry points: [`tailscale_ssh.py`](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py) (Command dispatcher)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_commands["CLI workflows"]
  node_cli["Command dispatcher<br/>[tailscale_ssh.py]"]
  node_picker["Device picker<br/>[tailscale_ssh.py]"]
  node_views["List and watch<br/>[tailscale_ssh.py]"]
  node_doctor["Diagnostics<br/>[tailscale_ssh.py]"]
end

subgraph group_discovery["Discovery and state"]
  node_monitor["Tailnet monitor<br/>[tailscale_ssh.py]"]
  node_discovery_fetch["Device discovery<br/>[tailscale_ssh.py]"]
  node_probe["SSH port probe<br/>[tailscale_ssh.py]"]
  node_config[("Configuration<br/>[tailscale_ssh.py]")]
  node_devices[("Device preferences<br/>[tailscale_ssh.py]")]
end

subgraph group_connection["SSH connection"]
  node_connect["SSH connection<br/>[tailscale_ssh.py]"]
  node_key_setup["SSH key setup<br/>[tailscale_ssh.py]"]
end

subgraph group_management["Setup and management"]
  node_setup["Device setup<br/>[tailscale_ssh.py]"]
  node_accounts["Account profiles<br/>[tailscale_ssh.py]"]
  node_update["Engine update<br/>[tailscale_ssh.py]"]
end

node_user(("User"))
node_tailscale["Tailscale CLI or API"]
node_ssh["SSH client and server"]
node_github["GitHub"]

node_user -->|"runs command"| node_cli
node_cli -->|"dispatches"| node_picker
node_cli -->|"dispatches"| node_views
node_cli -->|"dispatches"| node_doctor
node_cli -->|"dispatches"| node_connect
node_cli -->|"dispatches"| node_setup
node_cli -->|"dispatches"| node_accounts
node_cli -->|"dispatches"| node_update
node_picker -->|"starts"| node_monitor
node_views -->|"starts"| node_monitor
node_doctor -->|"checks tailnet"| node_discovery_fetch
node_monitor -->|"refreshes devices"| node_discovery_fetch
node_monitor -->|"checks SSH"| node_probe
node_discovery_fetch -->|"fetches status"| node_tailscale
node_discovery_fetch -->|"reads profiles"| node_config
node_probe -->|"probes ports"| node_ssh
node_connect -->|"resolves devices"| node_discovery_fetch
node_connect -->|"checks SSH"| node_probe
node_connect -->|"reads and saves"| node_devices
node_connect -->|"offers key setup"| node_key_setup
node_connect -->|"invokes client"| node_ssh
node_key_setup -->|"installs public key"| node_ssh
node_setup -->|"installs or signs in"| node_tailscale
node_setup -->|"starts server"| node_ssh
node_setup -->|"generates key"| node_key_setup
node_accounts -.->|"switches account"| node_tailscale
node_accounts -->|"reads and writes profiles"| node_config
node_update -->|"fetches engine"| node_github

click node_cli "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_picker "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_views "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_doctor "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_monitor "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_discovery_fetch "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_probe "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_config "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_devices "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_connect "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_key_setup "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_setup "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_accounts "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"
click node_update "https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_picker,node_views,node_doctor,node_user,node_ssh toneBlue
class node_monitor,node_discovery_fetch,node_probe,node_config,node_devices toneAmber
class node_connect,node_key_setup,node_tailscale toneMint
class node_setup,node_accounts,node_update toneRose
class node_github toneIndigo
```

## Components

### CLI workflows

- [Command dispatcher](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Device picker](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [List and watch](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Diagnostics](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`

### Discovery and state

- [Tailnet monitor](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Device discovery](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [SSH port probe](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Configuration](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Device preferences](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`

### SSH connection

- [SSH connection](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [SSH key setup](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`

### Setup and management

- [Device setup](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Account profiles](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`
- [Engine update](https://github.com/franc417/tailscale-ssh/blob/main/tailscale_ssh.py): `tailscale_ssh.py`

### Other components

- **User**
- **Tailscale CLI or API**
- **SSH client and server**
- **GitHub**

## Connections

- User → Command dispatcher: runs command
- Command dispatcher → Device picker: dispatches
- Command dispatcher → List and watch: dispatches
- Command dispatcher → Diagnostics: dispatches
- Command dispatcher → SSH connection: dispatches
- Command dispatcher → Device setup: dispatches
- Command dispatcher → Account profiles: dispatches
- Command dispatcher → Engine update: dispatches
- Device picker → Tailnet monitor: starts
- List and watch → Tailnet monitor: starts
- Diagnostics → Device discovery: checks tailnet
- Tailnet monitor → Device discovery: refreshes devices
- Tailnet monitor → SSH port probe: checks SSH
- Device discovery → Tailscale CLI or API: fetches status
- Device discovery → Configuration: reads profiles
- SSH port probe → SSH client and server: probes ports
- SSH connection → Device discovery: resolves devices
- SSH connection → SSH port probe: checks SSH
- SSH connection → Device preferences: reads and saves
- SSH connection → SSH key setup: offers key setup
- SSH connection → SSH client and server: invokes client
- SSH key setup → SSH client and server: installs public key
- Device setup → Tailscale CLI or API: installs or signs in
- Device setup → SSH client and server: starts server
- Device setup → SSH key setup: generates key
- Account profiles → Tailscale CLI or API: switches account
- Account profiles → Configuration: reads and writes profiles
- Engine update → GitHub: fetches engine
