AI-native SSH toolkit. Not a human terminal. Not an OpenSSH wrapper. A programmable backend that speaks JSON β built for agents, works for humans.
AgentSSH talks SSH directly through libssh2. No shell wrappers. No screen scraping. No heuristics.
Drop SKILL.md into your agent's skill directory to give it SSH superpowers. Different agents use different paths β follow your agent's documentation for where to install skills.
The agent gains: exec, file upload/download, session management, port forwarding, SOCKS5 proxy β all via structured JSON. See SKILL.md for the full capability definition.
| Traditional SSH | AgentSSH | |
|---|---|---|
| π― Output | Raw ANSI terminal text | Structured JSON with status codes |
| π Connection | Connect β run β disconnect | Long-lived daemon, session reuse |
| π‘ Port forwarding | ssh -L / ssh -D per terminal |
Daemon-managed tunnels & SOCKS5 proxy |
| ποΈ File transfer | Separate scp/sftp binary |
Built-in SFTP β SCP β exec fallback chain |
| π Auth config | ~/.ssh/config (custom grammar) |
JSON profiles, machine-writable |
| πͺ Windows | Works but clunky | Auto-detects & uses PowerShell fallback |
| π Output nav | Scroll back in terminal | Cursor-based paging with --offset / --limit |
# Prerequisites
brew install libssh2 # macOS
# apt install libssh2-dev # Linux
# Install from crates.io (recommended)
cargo install agentssh
# Or build from source
cargo build --release
# β target/release/agentsshagentssh profile add prod \
--host example.com \
--username root \
--private-key-path ~/.ssh/id_ed25519
agentssh profile list
# tencent root@82.157.147.224:22
# prod root@example.com:22agentssh --json exec --profile prod --retry 3 -- uptime
# {"ok":true,"data":{"exit_status":0,"stdout":"21:03:01 up 42 days\n","stderr":""}}Commands run through /bin/sh -c β pipes, redirects, and shell chains work natively:
# Pipe and filter
agentssh --json exec --profile prod -- grep ERROR /var/log/syslog \| tail -5
# Redirect output to remote file
agentssh --json exec --profile prod -- cat \> /etc/config \</dev/null
# Chain commands
agentssh --json exec --profile prod -- ls /etc \&\& systemctl status nginxTip: Escape
|,>,&&with backslashes so your local shell doesn't eat them.
agentssh connect --profile prod --reconnect
# β session_id: s1 (auto-reconnect on disconnect)
# Clean command execution (no PTY echo β structured JSON)
agentssh session exec --session-id s1 -- uname -a
# β {"exit_status":0, "stdout":"Linux ...\n", "stderr":""}
# Interactive PTY mode
agentssh session send --session-id s1 --input "ls -la\n"
agentssh session send --session-id s1 \
--input "sudo systemctl restart nginx\n" \
--expect "[sudo] password" \
--respond "mypassword\n"
agentssh session read --session-id s1 # latest output
agentssh session read --session-id s1 --follow # stream live
agentssh session spawn --from s1 # new PTY on same SSH conn
agentssh session ping --session-id s1
agentssh session close --session-id s1# Default auto: SFTP β SCP β exec (works on Linux, macOS, and Windows!)
agentssh file upload --profile prod --local ./app --remote /opt/app
agentssh file download --profile prod --remote /var/log/syslog --local ./syslog
agentssh file ls --profile prod --remote /var/www
# Force a specific protocol
agentssh file upload --profile windows --method scp --local ./app --remote C:/app# Local port forward: localhost:9999 β remote internal :8080
agentssh proxy create --profile prod \
--local 127.0.0.1:9999 \
--remote 127.0.0.1:8080
# SOCKS5 dynamic proxy: route all traffic through remote host
agentssh proxy create --profile prod --socks5 127.0.0.1:1080
curl --socks5 127.0.0.1:1080 http://internal-service/
agentssh proxy list
agentssh proxy ping --proxy-id p1
agentssh proxy close --proxy-id p1
agentssh proxy close --allββββββββββββββββ Unix Socket ββββββββββββββββββββ
β CLI client β ββββββββββββββββββββΊ β Daemon (serve) β
β (one-shot) β JSON-line IPC β β
ββββββββββββββββ β βββββββββββββββ β
β β sessions β β
ββββββββββββββββ β β proxies β β
β CLI client βββββββββββββββββββββββΊβ β connections β β
β (session) β β βββββββββββββββ β
ββββββββββββββββ βββββββββ¬βββββββββββ
β
SSH (libssh2)
β
βββββββββββΌββββββββββ
β Remote servers β
β Linux Β· macOS Β· β
β Windows β
βββββββββββββββββββββ
Daemon β auto-starts on first session/proxy command. Survives CLI invocations. Handles heartbeat, session health, connection pooling.
Connection pooling β sessions can share one TCP/SSH connection. session spawn --from <id> opens a fresh PTY on the same underlying connection.
Proxy threads β each proxy create spawns a listener thread inside the daemon. Accepted connections get their own handler thread with non-blocking bidirectional forwarding.
# β‘ One-shot
agentssh exec # Run command β stdout + exit code
agentssh shell # Interactive PTY (human use)
# π Sessions
agentssh connect # Open PTY β session_id
agentssh session send # Send input (Β± expect/respond pairs)
agentssh session spawn --from s1 # New PTY on s1's SSH connection
agentssh session read # Read output from cursor
agentssh session resize # Change PTY dimensions
agentssh session signal # Send signal (INT, TERM, KILLβ¦)
agentssh session status # Get session metadata
agentssh session ping # Check if session is alive
agentssh session list # List sessions + connection groups
agentssh session close # Close session
# π Files
agentssh file upload # Upload (SFTP β SCP β exec)
agentssh file download # Download (SFTP β SCP β exec)
agentssh file ls # List remote directory
# π Proxy & tunnels
agentssh proxy create # -L forward or -D SOCKS5
agentssh proxy list # List active proxies
agentssh proxy ping # Check proxy health
agentssh proxy close # Close one or --all
# π Profiles
agentssh profile list | read | add | write | delete
# βοΈ Daemon
agentssh daemon serve # Start daemon (auto-started)
agentssh daemon shutdown # Stop daemon + cleanup| Path | Purpose |
|---|---|
~/.config/agentssh/profiles.json |
SSH connection profiles |
$XDG_RUNTIME_DIR/agentssh-{user}.sock |
Daemon Unix socket |
/tmp/agentssh-daemon.log |
Daemon log (override: AGENTSSH_LOG) |
{
"profiles": {
"prod": {
"host": "example.com",
"port": 22,
"username": "root",
"private_key_path": "~/.ssh/id_ed25519",
"retry": 3,
"retry_delay_ms": 250
}
}
}- Rust β₯ 1.85 (edition 2024)
- libssh2 system library (
brew install libssh2/apt install libssh2-dev) - Unix only (uses Unix domain sockets)
cargo build --release
# β target/release/agentsshMIT