Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

purple

Your ssh config, synced with your cloud.

crates.iodownloadsstarsmitbuilt with ratatuiWebsite

purple is a free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide.

Spin up a VM on AWS, GCP, Azure, Hetzner, Proxmox or 13 other cloud providers and it's in your host list before the console catches up. Kill one and purple marks it stale, so your list never lies. No more hand-editing ~/.ssh/config after every Terraform run, no more digging through cloud consoles for the right IP.

Everything else you do over SSH lives in the same terminal: fuzzy search across hundreds of hosts, visual file transfer, multi-host SSH key push, short-lived HashiCorp Vault SSH certificates and an MCP server for AI agents. Keyboard-driven. Single binary. MIT licensed.

purple terminal SSH client demo: searching hosts, monitoring live tunnels, managing containers, running snippets and inspecting keys

Install

curl -fsSL getpurple.sh | sh
brew, cargo, nix, AUR or from source
brew install erickochen/purple/purple
cargo install purple-ssh
nix profile install github:erickochen/purple
paru -S purple-bin
yay -S purple-bin
git clone https://github.com/erickochen/purple.git
cd purple && cargo build --release

Claude Desktop users can install the .mcpb bundle for one-click MCP integration (read-only by default). Setup details on the MCP Server wiki. No data leaves your machine. See PRIVACY.md.

Run purple. Press ? on any screen for help. That's it.

Contents

Why I built this

My SSH config was fine. Proper aliases, ProxyJump chains, organized by provider. Not the problem.

The problem was everything around it. Need to check a container? ssh host docker ps. Copy a file? scp with the right flags. Run the same command on ten hosts? Write a loop or boot up Ansible for a one-liner. Spin up a VM on Hetzner? Open the console, grab the IP, edit config, save. Someone asks which box runs what? Good luck.

I wanted one place for all of that. So I built it.

What you get

Your ssh config tracks your infra

Drop in one API token per provider. New machines land in ~/.ssh/config the moment they boot, IPs follow instances as they move and decommissioned hosts grey out instead of lingering. 18 providers including AWS, GCP, Azure, Hetzner, DigitalOcean, Proxmox, Teleport and NetBox, multiple accounts each. See the wiki for the full list.

purple cloud provider list close-up: per-provider sync status with host counts and stale markers

One panel answers the questions you actually have. Is it up. How do I reach it. When was I last on it. What runs there. Connection info, jump route, a year of SSH activity, tags, tunnels and containers per host, with live health dots.

purple host list with the detail panel: connection info, jump route, activity sparkline, tags, tunnels and containers

Jump to anything with one keystroke

Press : and type four letters. Any host, tunnel, container, snippet or action, ranked by how often you use it. It searches the SSH User, ProxyJump and Vault SSH role too, so typing your username finds every server you log in as. Field prefixes (user:, proxy:, vault:, tag:) cut straight to one directive. Like Linear's Cmd+K, but in your terminal.

purple Jump bar close-up: universal fuzzy search across hosts, tunnels, containers, snippets and actions

Manage Docker and Podman on every server, over SSH

Your whole fleet's containers in one list, grouped per host. Shell in, stream logs, restart, stop, exec or kick a whole compose stack member by member. No agent on the remote, no web UI, no extra ports. Just SSH.

purple Containers tab close-up: containers across multiple hosts grouped per host with state and uptime

Monitor SSH tunnels in real time

Forwards run blind. purple doesn't: every Local, Remote and Dynamic SOCKS forward with live throughput, channel activity and uptime, down to the exact app behind each connection.

purple tunnel detail close-up: per-client process roster with live throughput sparklines and a channel swimlane

Run one command across your fleet

Save a command once, run it on any set of hosts. purple shows the blast radius before you fan out and keeps the track record per snippet. "28 of 29 host runs ok" is a number you want to see before production.

purple snippet detail close-up: command with parameters, a blast-radius impact card and a host-run track record

Push any SSH key to your fleet, no ssh-copy-id loop

Every key in ~/.ssh, scored and fingerprinted, with the hosts it unlocks and the last time it was used. Push one to your whole fleet with p. Vault-managed hosts skip automatically, so cert-managed stays cert-managed.

purple key detail close-up: randomart fingerprint, strength score, agent status and per-key activity

Short-lived certificates from the HashiCorp Vault SSH secrets engine get a TTL strip of their own, so an expiring cert never surprises you.

purple Vault SSH close-up: signed certificates with remaining TTL bars per host

And more

  • Visual file transfer with a split-pane local and remote explorer.
  • Automatic password retrieval from OS Keychain, 1Password, Bitwarden, pass, the HashiCorp Vault KV secrets engine and Proton Pass.
  • Short-lived SSH certificates signed via the HashiCorp Vault SSH secrets engine.
  • MCP server for AI agents like Claude Code and Cursor, with a read-only mode and a JSON Lines audit log.
  • Your own ssh wrapper for interactive logins, such as kitty's kitten ssh, via one preference or PURPLE_SSH_COMMAND.
  • XDG Base Directory support: set XDG_CONFIG_HOME and friends (or PURPLE_CONFIG_DIR and friends) and purple splits its files into config, data, state and cache. Unset, everything stays in ~/.purple.

See the wiki for details.

How purple compares

purpleTermiussshsLazydocker
Open sourceYes (MIT)NoYesYes
LanguageRustElectronRustGo
Multi-cloud SSH sync18 providersLimitedNoNo
Containers over SSHDocker and Podman, fleet-wideNoNoLocal host only
Live tunnel monitoringYesNoNoNo
MCP server for AI agentsYesNoNoNo
Account requiredNoYesNoNo
PriceFreeFreemiumFreeFree

purple keeps your SSH config local and editable: it edits ~/.ssh/config in place with round-trip fidelity. Use Lazydocker for single-host local Docker, purple for fleet-wide remote management.

How it works

purple reads ~/.ssh/config directly. No database, no daemon, no account. Comments, indentation, include files, unknown directives: all preserved through every edit, so the config you wrote stays the config you have.

Written in Rust. Single binary. 7300+ tests. MIT license.

Links

Wiki · Cloud Providers · MCP Server · FAQ · Troubleshooting · Security · llms.txt

Credits

Screenshots and the demo are generated from the live TUI in Berkeley Mono by U.S. Graphics Company, recorded with VHS. They regenerate on release, so what you see here always matches the current build.

Feedback

Bug or feature request? Open an issue.

About

Free, open-source terminal SSH manager and SSH config editor in Rust for macOS and Linux that keeps ~/.ssh/config in sync with 18 cloud providers, monitors live SSH tunnels and manages Docker and Podman containers fleet-wide. Plus scp, Vault SSH certs and an MCP server for AI agents.

Topics

Resources

Contributing

Security policy

Stars

669 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages