sshacp is a lightweight, high-performance terminal wrapper and SSH session broker for Linux. It enables local AI coding agents (such as gemini-cli, codex-cli, antigravity, claude-code) to inspect terminal state, stream output, and execute commands on remote servers over SSH.
Zero Remote Installation: The remote SSH server does not need any AI agents, Python, Node.js, or special software installed. All AI agent logic remains local on your machine.
- 🖥️ Zero-Dependency Remote Execution: Works over standard SSH sessions (
sshd). - 🤖 Dual AI Agent Protocols:
- Agent Control Protocol (ACP REST API): Query screen, read scrollback, execute commands, send keystrokes over Unix Domain Socket (
/tmp/sshacp.sock) or HTTP (http://127.0.0.1:9090). - Model Context Protocol (MCP): Native JSON-RPC MCP server endpoint (
/mcp) supporting tool calls (sshacp_read_screen,sshacp_execute_command,sshacp_send_input).
- Agent Control Protocol (ACP REST API): Query screen, read scrollback, execute commands, send keystrokes over Unix Domain Socket (
- 🔐 AES-256-GCM Encrypted Profiles: Includes an interactive wizard (
sshacp -init) that prompts for server details and encrypts stored passwords with PBKDF2 + AES-256-GCM so credentials are never stored in plaintext on disk. - 🔑 Automated Sudo Password Injection: Detects remote
sudopassword prompts in real time and automatically injects password from local configuration (-sudo-passorSSHACP_SUDO_PASS), allowing seamless agent execution of privileged commands. - ⚡ Token-Efficient ESC Stripper: Advanced multi-stage ANSI/OSC/DCS/Kitty-graphics parser that strips terminal control codes, title annotations, and graphics noise for minimal LLM token consumption.
- 🐚 Full TTY Interactivity: Transparent raw TTY pass-through supporting colors, interactive tools (
vim,htop), and dynamicSIGWINCHwindow resizing.
flowchart TD
subgraph Local Machine
U["User Terminal / TTY"] <-->|"Raw TTY I/O"| S["sshacp Wrapper & PTY Engine"]
S <--> VT["In-Memory VT100 & Token Optimizer"]
S <--> ACP["ACP / MCP Server (Unix Socket & HTTP)"]
A["Local AI Agent (gemini-cli, codex, antigravity)"] <-->|"ACP / MCP JSON-RPC"| ACP
end
subgraph Remote Server
S <-->|"Standard SSH Connection"| R["Remote SSH Server / Shell"]
end
Clone the repository and build the binary:
git clone https://github.com/Blackmanx/sshacp.git
cd sshacp
go build -o bin/sshacp ./cmd/sshacpRun the interactive wizard to set up server profiles with encrypted passwords:
./bin/sshacp -init
# or
./bin/sshacp configThe wizard will prompt for:
- Profile Name (e.g.
dev-server) - Remote Host & User
- Master Passphrase (used to derive AES-256-GCM encryption key)
- Passwords (hidden inputs)
It saves the profile into sshacp.json with passwords formatted as "enc:v1:salt:nonce:ciphertext". When connecting (./bin/sshacp dev-server), sshacp prompts for your master passphrase once to decrypt credentials securely in RAM.
./bin/sshacp user@remote-host.comPass your remote sudo password using .env file, -sudo-pass CLI flag, or environment variable SSHACP_SUDO_PASS (stored securely in local memory only):
# Via .env file (copy from .env.example)
cp .env.example .env
# Edit .env and set SSHACP_SUDO_PASS=my_remote_password
# Via Environment Variable
export SSHACP_SUDO_PASS="my_remote_password"
./bin/sshacp user@remote-host.com
# Via CLI flag
./bin/sshacp -sudo-pass "my_remote_password" user@remote-host.comWhen an AI agent (or you) runs a command like sudo apt update, sshacp detects the prompt and automatically injects the password into the remote session without agent intervention.
sshacp supports connecting using aliases from your ~/.ssh/config or custom server profiles defined in sshacp.json (see sshacp.json.example):
{
"profiles": {
"dev-server": {
"host": "192.168.1.100",
"user": "ubuntu",
"port": 22,
"password": "my_password",
"sudo_password": "my_password"
}
}
}Connect directly using profile names:
./bin/sshacp dev-serverList all configured SSH hosts and profiles:
./bin/sshacp -hostsNote on Password Reuse: If
sudo_passwordis omitted from a profile or environment variable,sshacpautomatically reuses the SSH login password forsudoprompt injection!
Running sshacp without arguments automatically presents an interactive connection menu listing all your configured profiles (sshacp.json) and SSH host aliases (~/.ssh/config):
./bin/sshacp
==============================================
sshacp Target Connection Menu
==============================================
[1] dev-server (profile: ubuntu@192.168.1.100:22)
[2] prod-server (profile: admin@203.0.113.5:2222)
[3] my-ssh-alias (ssh config: root@my-domain.com)
[4] Local Shell
Select target [1-4]: 1./bin/sshacp -localsshacp exposes a local REST / Unix Socket server at /tmp/sshacp.sock (and optionally http://127.0.0.1:9090).
| Endpoint | Method | Description |
|---|---|---|
/api/v1/screen |
GET |
Returns clean, formatted text of the current visible screen. |
/api/v1/scrollback |
GET |
Returns recent scrollback history (?lines=100). |
/api/v1/execute |
POST |
Injects a shell command, waits for prompt return, and returns output. |
/api/v1/input |
POST |
Sends raw keystrokes / text into the active session. |
/api/v1/status |
GET |
Returns connection status, target host, and socket path. |
# Read current visible screen via Unix Socket
curl --unix-socket /tmp/sshacp.sock http://localhost/api/v1/screen
# Execute command on remote SSH session via HTTP
curl -X POST -H "Content-Type: application/json" \
-d '{"command": "uname -a", "timeout_ms": 5000}' \
http://127.0.0.1:9090/api/v1/executeConnect your local AI agent to http://127.0.0.1:9090/mcp (or via Unix socket /mcp). sshacp exposes the following tools:
sshacp_read_screen: Reads visible terminal text.sshacp_execute_command: Sends command and captures command output.sshacp_send_input: Injects raw keystrokes or control signals (Ctrl+C, etc.).
This project is licensed under the MIT License - see the LICENSE file for details.