A lightweight CLI tool that enables AI agents to execute commands across local and remote (SSH) sessions with seamless context switching.
| Platform | Architecture | Status |
|---|---|---|
| Linux | x86_64 (amd64) | ✅ Fully Supported |
| Linux | arm64 | ✅ Fully Supported |
| macOS | x86_64 (Intel) | ✅ Fully Supported |
| macOS | arm64 (Apple Silicon) | ✅ Fully Supported |
| Windows | - | ❌ Not Supported |
The Go implementation is tested on Linux and macOS via CI.
- Multi-session support: Manage multiple SSH connections alongside your local shell
- SSH config integration: Automatically reads
~/.ssh/configfor host aliases - Context switching: Switch between sessions with simple slash commands
- Proxy mode: Use as a SHELL for AI agents like Claude Code
- MCP server: Built-in Model Context Protocol server for AI agent integration
- State persistence: Maintains working directory and environment across commands
- Shell completions: Tab completion for bash, zsh, and fish
go build -o thop ./cmd/thop
sudo mv thop /usr/local/bin/# Bash (add to ~/.bashrc)
eval "$(thop --completions bash)"
# Zsh (add to ~/.zshrc)
eval "$(thop --completions zsh)"
# Fish
thop --completions fish > ~/.config/fish/completions/thop.fish# Start interactive mode
thop
# You'll see a prompt like:
(local) $ ls -la
(local) $ /connect myserver
Connecting to myserver...
Connected to myserver
(myserver) $ pwd
/home/user
(myserver) $ /local
Switched to local
(local) $# Execute a single command
thop -c "ls -la"
# Use as SHELL for Claude Code
SHELL="thop --proxy" claude
# Read commands from stdin
echo "ls -la" | thop --proxy# Start as MCP server
thop --mcp
# Configure in Claude Desktop
# See docs/MCP.md for full configurationCreate ~/.config/thop/config.toml:
[settings]
default_session = "local"
command_timeout = 300
log_level = "info"
[sessions.local]
type = "local"
shell = "/bin/bash"
[sessions.prod]
type = "ssh"
host = "prod.example.com"
user = "deploy"
port = 22
identity_file = "~/.ssh/prod_key"
[sessions.staging]
type = "ssh"
host = "staging" # Uses ~/.ssh/config alias
[sessions.dev]
type = "ssh"
host = "dev.example.com"
user = "developer"
startup_commands = [
"cd ~/project",
"source venv/bin/activate"
]For servers requiring password authentication, you can provide the password in several ways:
Via environment variable:
[sessions.legacy]
type = "ssh"
host = "legacy.example.com"
user = "admin"
password_env = "LEGACY_SSH_PASSWORD" # Reads from $LEGACY_SSH_PASSWORDVia password file (must have 0600 permissions):
[sessions.legacy]
type = "ssh"
host = "legacy.example.com"
user = "admin"
password_file = "~/.ssh/legacy_password" # File must be chmod 0600Interactively via /auth command:
(local) $ /auth legacy
Password:
Password set for legacy
(local) $ /connect legacyYou can configure commands to run automatically when connecting to a session:
[sessions.myserver]
type = "ssh"
host = "myserver"
startup_commands = [
"cd ~/workspace",
"source ~/.bashrc",
"export PATH=$PATH:/custom/bin"
]thop automatically reads ~/.ssh/config to resolve host aliases:
# ~/.ssh/config
Host myserver
HostName actual.server.com
User deploy
Port 2222
IdentityFile ~/.ssh/mykey
Then in your thop config:
[sessions.myserver]
type = "ssh"
host = "myserver" # Will resolve from SSH configthop supports connecting through jump hosts (bastion servers). You can configure this in two ways:
Via thop config:
[sessions.internal]
type = "ssh"
host = "internal.server.com"
user = "deploy"
jump_host = "bastion.example.com" # Simple hostname
# Or with full details:
# jump_host = "jumpuser@bastion.example.com:2222"Via SSH config (ProxyJump):
# ~/.ssh/config
Host internal
HostName internal.server.com
User deploy
ProxyJump bastion.example.com
Host bastion.example.com
User jumpuser
IdentityFile ~/.ssh/bastion_key
Then in thop config:
[sessions.internal]
type = "ssh"
host = "internal" # Will use ProxyJump from SSH configThe jump host connection is established first, then the target connection is made through the jump host tunnel.
thop supports SSH agent forwarding, which allows the remote server to use your local SSH keys for authentication (useful for git over SSH, chained SSH connections, etc.).
Via thop config:
[sessions.dev]
type = "ssh"
host = "dev.example.com"
user = "developer"
agent_forwarding = trueVia SSH config (ForwardAgent):
# ~/.ssh/config
Host dev
HostName dev.example.com
User developer
ForwardAgent yes
Then in thop config:
[sessions.dev]
type = "ssh"
host = "dev" # Will use ForwardAgent from SSH configWith agent forwarding enabled, you can use git over SSH, SSH to other servers, or any other operation that requires your SSH keys on the remote server.
THOP_CONFIG: Path to config file (default:~/.config/thop/config.toml)THOP_STATE_FILE: Path to state file (default:~/.local/share/thop/state.json)THOP_LOG_LEVEL: Log level (debug, info, warn, error)THOP_DEFAULT_SESSION: Default session name
| Command | Shortcut | Description |
|---|---|---|
/connect <session> |
/c |
Connect to an SSH session |
/switch <session> |
/sw |
Switch to a session |
/local |
/l |
Switch to local shell |
/status |
/s |
Show all sessions |
/close <session> |
/d |
Disconnect from SSH session |
/auth <session> |
Set password for SSH session | |
/trust <session> |
Trust host key for SSH session | |
/copy <src> <dst> |
/cp |
Copy file between sessions |
/add-session <name> <host> |
/add |
Add new SSH session to config |
/read <path> |
/cat |
Read file contents from current session |
/write <path> <content> |
Write content to file on current session | |
/env [KEY=VALUE] |
Show or set environment variables | |
/shell <command> |
/sh |
Run interactive command with PTY (vim, top) |
/bg <command> |
Run command in background | |
/jobs |
List background jobs | |
/fg <job_id> |
Wait for job and show output | |
/kill <job_id> |
Kill a running background job | |
/help |
/h |
Show help |
/exit |
/q |
Exit thop |
| Flag | Description |
|---|---|
--proxy |
Run in proxy mode (for AI agents) |
--mcp |
Run as MCP server (Model Context Protocol) |
-c <cmd> |
Execute command and exit |
--status |
Show status and exit |
--config <path> |
Use alternate config file |
--json |
Output in JSON format |
--completions <shell> |
Generate shell completions (bash, zsh, fish) |
-v, --verbose |
Verbose output |
-q, --quiet |
Quiet output |
-h, --help |
Show help |
-V, --version |
Show version |
| Code | Description |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Authentication failed |
| 3 | Host key verification failed |
Important: Copy the agent documentation to your project directory:
# Copy Claude-specific guide to your project
cp /path/to/thop/docs/THOP_FOR_CLAUDE.md ~/myproject/
# Or for other AI agents
cp /path/to/thop/docs/THOP_FOR_AGENTS.md ~/myproject/This gives Claude complete instructions on how to use thop when working in that project.
To use thop as the shell for Claude Code:
SHELL="thop --proxy" claudeThis allows Claude to:
- Execute commands on your local machine
- Connect to and execute commands on remote servers
- Switch between sessions seamlessly
- Maintain working directory state across commands
# Start Claude with thop as shell
SHELL="thop --proxy" claude
# Claude can now:
# 1. Run local commands
ls -la
# 2. Connect to remote server
/connect prod
# 3. Run commands on prod
pwd
cat /var/log/app.log
# 4. Switch back to local
/localSee the docs/ directory for comprehensive guides:
- docs/THOP_FOR_CLAUDE.md - Complete guide for Claude Code with workflows and examples
- docs/THOP_FOR_AGENTS.md - Platform-agnostic guide for any AI agent
- docs/MCP.md - MCP server integration guide
- docs/AGENT_README.md - How to use the agent documentation
Copy these files to your project directories so Claude has access to the instructions when working on those projects.
thop maintains state in ~/.local/share/thop/state.json:
- Active session name
- Per-session working directory
- Per-session environment variables
- Connection status
State is preserved across thop restarts and uses file locking for safe concurrent access.
-
Authentication failed: Ensure your SSH key is loaded in ssh-agent or specified in config
ssh-add ~/.ssh/mykey -
Host key verification failed: The host key is not in
~/.ssh/known_hostsssh-keyscan hostname >> ~/.ssh/known_hosts
-
Connection refused: Check the host and port are correct
thop --status # Shows configured sessions
-
Check config syntax:
cat ~/.config/thop/config.toml -
Use verbose mode:
thop -v
go build ./cmd/thopgo test ./...thop/
├── cmd/thop/ # Main entry point
├── internal/
│ ├── cli/ # CLI handling (interactive, proxy, completions)
│ ├── config/ # Configuration parsing
│ ├── mcp/ # MCP server implementation
│ ├── session/ # Session management (local, SSH)
│ ├── sshconfig/ # SSH config parsing
│ └── state/ # State persistence
└── go.mod
Apache License 2.0 - see LICENSE file for details.
Scott Glover scottgl@gmail.com