cd /news/ai-agents/show-hn-shellink-let-ai-agents-run-c… · home topics ai-agents article
[ARTICLE · art-66876] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Show HN: Shellink – let AI agents run commands on servers behind jump hosts

Shellink, an open-source session middleware for AI agents and humans working with SSH and local terminal sessions, provides a stable CLI for connection profiles, interactive sessions, command execution, file transfer, remote editing, and session state. The tool, available on GitHub, includes a local daemon that owns sessions and exposes a Web UI plus HTTP and WebSocket APIs, designed to let AI agents run commands on servers behind jump hosts while supporting multi-hop login automation, PTY-based continuity, human supervision, and auditable operations.

read12 min views4 publishedJul 21, 2026
Show HN: Shellink – let AI agents run commands on servers behind jump hosts
Image: source

One stable CLI and daemon for SSH, local PTY sessions, file transfer, and remote editing — built for AI agents and humans alike.

Features · Quick Start · Documentation · Contributing · 中文文档

An AI agent hops through a jump host and runs commands on the target server — driven entirely through the Shellink CLI.

Shellink is an open-source session middleware for AI agents and humans working with SSH and local terminal sessions. It provides one stable CLI for connection profiles, interactive sessions, command execution, file transfer, remote editing, and session state. A local daemon owns the sessions and exposes a browser-friendly Web UI plus HTTP and WebSocket compatibility APIs.

Repository: https://github.com/jie123108/Shellink

Security warning:command

profiles execute their configured command as the server process user. Run Shellink only in a trusted environment and protectSHELLINK_TOKEN

. Shellink also lets an AI agent connect directly to production servers; this carries real operational risk, so prefer read-only, inspection, or analysis operations, or point the agent at non-production environments.

Shellink

Web UI dashboard (session list):

Web UI live session terminal (xterm.js), including a jump-host hop:

CLI/TUI session view (shellink cli

):

SSH and custom command sessions: Connect directly with SSH, or run a command/script inside a PTY.Multi-hop login automation:connectType: "command"

supportsexpect

and similar scripts for multi-level bastion hosts, jump-host menus, OTP prompts, and legacy authentication flows.Command execution and state handling: Execute commands, inspect state, provide interactive input, and wait for the session to become ready before the next operation.File transfer across jump hosts: Upload and download files through the existing PTY instead of requiring SFTP. This keeps transfers working through custom command chains and multi-hop connections.Remote file editing: Apply precise replacements withshellink session edit

.Audit history and supervision: Session input/output is retained as history for audit and replay, whileMANUAL

mode lets a human take control and supervise or answer prompts.CLI/TUI, Web UI, REST, and WebSocket: Use the interface that fits the workflow, with stable--json

output for automation.Encrypted profiles and optional single-file binaries: Credentials are protected in SQLite, and Bun builds are available for macOS and Linux.

Shellink is designed around the situations where an AI agent needs reliable access but should not guess or bypass human controls:

Scriptable multi-hop access: Agents can reuseexpect

or other custom login scripts for several bastion hops instead of implementing each site's authentication flow themselves.PTY-based continuity: Commands and file transfers use the same PTY path, so an agent can work through jump hosts even when no direct SFTP or SSH endpoint is available.Human supervision:AUTO

mode is for agent actions;MANUAL

mode hands the terminal to a person for approval, OTP entry, or intervention before automation continues.Auditable operations: Session input/output history and daemon logs give operators a record for reviewing what the agent saw and did.Observable progress: Explicit session states and machine-readable CLI output let an agent decide whether to execute, send input, wait, or ask for human help.

The repository is an npm workspace monorepo with one additional non-workspace directory for agent skills:

Path Type Responsibility
protocol/
npm workspace Versioned RPC methods, MessagePack frames, and Zod schemas
cli/
npm workspace shellink CLI, daemon lifecycle commands, and terminal UI
server/
npm workspace Unix-socket daemon, session engine, services, HTTP, and WebSocket gateway
web/
npm workspace Vue 3 browser console with xterm.js
skills/
plain directory Agent skills for remote operations and iTerm2 profile import

The runtime flow is:

flowchart LR
  Client["CLI / TUI"] -->|Unix socket, MessagePack RPC| Daemon["Daemon services"]
  Daemon --> Sessions["SSH / local PTY sessions"]
  Daemon --> Storage["SQLite state and encrypted credentials"]
  Daemon --> Gateway["HTTP REST / WebSocket gateway / Web UI"]

The Unix socket is the primary local interface. HTTP, WebSocket, and the Web UI are compatibility and browser layers. New local automation should use the CLI rather than implementing the socket protocol directly.

Runtime: Node.js>=22.19.0

; Bun is optional for compiled binaries.Language: TypeScript with npm workspaces.Server: Fastify,ssh2

,node-pty

,ws

, SQLite viabetter-sqlite3

and Drizzle ORM.Protocol: MessagePack framing and Zod validation.Web: Vue 3, Vite, Naive UI, Pinia, and xterm.js.Testing: Vitest with V8 coverage and Docker-backed end-to-end fixtures.

Using an AI coding agent?Paste this prompt into your agent's chat:

Please help me install Shellink and its skills by following https://raw.githubusercontent.com/jie123108/Shellink/main/AGENTS_INSTALL.md

Prebuilt binaries are published for macOS and Linux (darwin-arm64

, darwin-x64

, linux-arm64

, linux-x64

). Windows is not supported; build from source instead (see below).

curl -fsSL https://raw.githubusercontent.com/jie123108/Shellink/main/install.sh -o /tmp/shellink-install.sh
cat /tmp/shellink-install.sh
sh /tmp/shellink-install.sh

Pin a release tag if needed:

curl -fsSL https://raw.githubusercontent.com/jie123108/Shellink/main/install.sh -o /tmp/shellink-install.sh
cat /tmp/shellink-install.sh
sh /tmp/shellink-install.sh --version v0.1.0

For a system-wide install into /usr/local/bin

(already on PATH

on most systems), run with sudo

:

sudo sh /tmp/shellink-install.sh --dir /usr/local/bin

The script downloads the matching asset from GitHub Releases, verifies SHA256SUMS.txt

, and installs shellink

to $HOME/.local/bin

by default. If that directory is not on PATH

, the installer appends an export PATH=...

line to your shell profile (~/.zshrc

, ~/.bashrc

, etc.). Open a new shell (or re-export PATH

), then verify:

shellink -V

Requirements:

  • Node.js 22.19 or newer.
  • npm.
  • Docker, only if you want to run the Docker-backed end-to-end tests.
  • Bun, only if you want to build a standalone binary.
git clone https://github.com/jie123108/Shellink.git
cd Shellink
npm install
npm run build

The built CLI is available at ./node_modules/.bin/shellink

. To build a standalone executable for the current platform:

npm run build:binary
mkdir -p "$HOME/.local/bin"
cp dist/shellink "$HOME/.local/bin/shellink"
export PATH="$HOME/.local/bin:$PATH"

Cross-build scripts are available for macos-arm64

, macos-x64

, linux-arm64

, and linux-x64

.

Start the interactive terminal UI. It starts the user-level daemon automatically when necessary:

shellink cli

Check the daemon and print the machine-readable agent reference:

shellink server status --json
shellink agent-doc

Create a command profile and session without putting credentials in shell history:

shellink profile create --input - --json <<'JSON'
{"name":"local-shell","connectType":"command","command":"/bin/sh"}
JSON

shellink profile list --query local --json
shellink session create --profile <profile-id> --json
shellink session exec <session-id> --command 'uname -a' --json
shellink session close <session-id> --json

For SSH profiles, pass passwords, passphrases, and private keys through --input FILE

or stdin. Never put them in command-line arguments.

When running from source, npm run dev

starts the server and Vite development UI. Open http://localhost:5173

. A built daemon serves the embedded UI at http://127.0.0.1:7070/shellink/ui/

by default; the exact URL is shown by shellink server run

or shellink server status --json

.

Custom command profiles are intended for connections that cannot be represented by a single direct SSH login. Set connectType

to command

and provide any command available on the server host, for example:

{
  "name": "Bastion menu",
  "connectType": "command",
  "command": "expect /opt/shellink/login-through-bastion.exp"
}

Shellink starts the command in a PTY and exposes the same command, input, history, file-transfer, and editing APIs used by SSH sessions. An expect

script can therefore drive several bastion hosts and authentication steps as one Shellink session. The script, its dependencies, and its credentials run on the server host as the daemon user; only execute trusted commands.

Note:Shellink itself does not handle a host's automatic login process. For automated login (multi-hop hops, jump-host menus, OTP prompts, and other interactive authentication flows), use an[script driven by a]expect

command

profile. Other tools such assshpass

(password-only logins) orssh

with key-based authentication andProxyJump

/ProxyCommand

can also work, depending on your environment.

The shellink

executable is the client. TUI commands and resource commands (profile

, session

, and webhook

) connect to the local daemon through a Unix socket. If the socket is unavailable, the client starts a detached daemon, waits for it to become ready, and then sends the request. Add --json

for stable, one-line machine-readable output.

shellink server start                 # Start in the background
shellink server status --json         # Inspect health and active sessions
shellink server logs --lines 100      # Read recent daemon logs
shellink server restart               # Restart the daemon
shellink server stop                  # Stop the daemon
shellink server run                   # Run in the foreground

server run

is suitable for development or a process manager. The daemon always starts its Unix socket. HTTP/WebSocket support is enabled by default and can be disabled with SHELLINK_HTTP_ENABLED=false

. HTTP binds to 127.0.0.1

by default; set SHELLINK_HOST=0.0.0.0

only when remote access is intentional.

Local requests from localhost

or 127.0.0.1

can omit authentication, including permanent session-record deletes. Remote HTTP and WebSocket requests require Authorization: Bearer <SHELLINK_TOKEN>

(or the WebSocket token query parameter used by existing clients). The Web UI probes GET /shellink/api/auth/sensitive-ops

to decide whether a token is required for delete/purge actions.

When nginx (or another reverse proxy) sits in front, the backend usually sees a loopback TCP peer but a public Host

header. That is treated as remote access: sensitive ops still require a token. X-Forwarded-For

/ X-Real-IP

are not trusted for the local bypass.

All HTTP, WebSocket, and Web UI routes are served under the /shellink

prefix:

Path Description
/shellink/ui/
Embedded Web UI (browser console)
/shellink/api/*
REST compatibility API (profiles, sessions, webhooks, auth)
/shellink/ws/sessions/{id}
Per-session terminal WebSocket stream
/shellink/ws/events
Global session-state event WebSocket stream
/shellink/agent.md , /shellink/llms.txt
Machine-readable agent reference (same content as shellink agent-doc )
/shellink/healthz
Liveness probe

Use the installed reference before integrating:

shellink agent-doc

The recommended flow is to search profiles, create a session, wait for WAITING_INPUT

, execute commands, inspect history when needed, and close the session. Session states are CONNECTING

, OUTPUTTING

, WAITING_INPUT

, IDLE

, and DISCONNECTED

; interaction modes are AUTO

and MANUAL

.

Important commands include:

shellink profile list --query '<name, host, or command>' --json
shellink session create --profile <profile-id> --json
shellink session state <session-id> --json
shellink session exec <session-id> --command 'ls -la' --json
shellink session input <session-id> --text 'yes' --json
shellink session history <session-id> --since 0 --json
shellink session download <session-id> --path /remote/file --output ./file --json
shellink session upload <session-id> --input ./file --path /remote/file --json
shellink session edit <session-id> --input edits.json --json
shellink session close <session-id> --json

Remote editing accepts exact, non-overlapping replacements and requires an AUTO

session in WAITING_INPUT

.

The repository includes two skills under skills/

. Install with the skills CLI (

npx

). Always pass --skill

so only the matching subdirectory is installed (the repo contains more than one skill).

npx skills add jie123108/Shellink --list

npx skills add jie123108/Shellink --skill shellink-cli --agent codex
npx skills add jie123108/Shellink --skill shellink-cli --agent codex -g

npx skills add jie123108/Shellink --skill shellink-iterm2-import --agent codex

npx skills update shellink-cli
npx skills update shellink-iterm2-import

Per-agent install and update commands (Cursor, Claude Code, Codex, Pi, Trae, Antigravity, OpenClaw) are documented in skills/shellink-cli/README.md.

Use this skill for profiles, SSH or command sessions, interactive input, file transfer, and remote editing. It requires a working shellink

executable on PATH

.

Use this skill on macOS to scan and import iTerm2 Profiles and DynamicProfiles:

python3 skills/shellink-iterm2-import/scripts/import_iterm2.py --json
python3 skills/shellink-iterm2-import/scripts/import_iterm2.py --dry-run --name "Production"
python3 skills/shellink-iterm2-import/scripts/import_iterm2.py --guid <guid>

It requires Python 3.9 or newer and an available shellink

executable. Review scan results before using --all

. Re-imports match by uniqueId

(iTerm2 Guid) first, then by name; matching profiles are updated by default. iTerm2 passwords are not exported; add them later through the Web UI when necessary.

Variable Description Default
SHELLINK_HOME
Data, master-key, and PID directory $HOME/.Shellink
SHELLINK_SOCKET
Unix socket path Platform-specific runtime path
SHELLINK_LOG
Daemon log path $SHELLINK_HOME/shellink.log
SHELLINK_HTTP_ENABLED
Enable HTTP/WebSocket compatibility services true
SHELLINK_HOST
HTTP bind address 127.0.0.1
SHELLINK_PORT
HTTP port 7070
SHELLINK_TOKEN
API and Web UI token for remote access change-me
SHELLINK_REQUIRE_TOKEN_FOR_SENSITIVE_OPS
Force token for session delete/purge (true /false ); unset derives from local vs remote
derived from request
SHELLINK_MASTER_KEY
32-byte key as 64 hex characters Generated on first start
SHELLINK_DB
SQLite database path override $SHELLINK_HOME/shellink.db
SHELLINK_MAX_FRAME_BYTES
Maximum RPC payload 16777216
SHELLINK_SOCKET_MAX_QUEUE_BYTES
Maximum buffered bytes per Unix-socket client before backpressure 4194304
SHELLINK_SILENCE_MS
Quiet-period threshold for state detection 800
SHELLINK_EXEC_TIMEOUT_MS
Default command timeout 30000
SHELLINK_TRANSFER_MAX_BYTES
Maximum upload/download size 6291456
SHELLINK_TRANSFER_TIMEOUT_MS
Default transfer timeout 120000
SHELLINK_EDIT_TIMEOUT_MS
Default remote-edit timeout 60000
SHELLINK_SSH_READY_TIMEOUT_MS
SSH readiness timeout 30000

For production, set SHELLINK_MASTER_KEY

explicitly and keep it stable for the lifetime of the database. The generated key is stored as $SHELLINK_HOME/master.key

with restrictive permissions.

npm run dev                 # Server and Web UI
npm run dev:server         # Server only
npm run dev:web            # Web UI only
npm run build              # Production runtime build

The project has unit, integration, protocol, CLI/TUI, WebSocket, and Docker-backed end-to-end tests.

npm run test:protocol
npm run test:server
npm run test --workspace=cli
npm run test:server:coverage
npm run test:coverage:full --workspace=server

Server coverage uses Vitest's V8 provider and enforces these thresholds:

Metric Threshold
Lines 98%
Statements 98%
Functions 97%
Branches 90%

test:server:coverage

excludes the long-running extreme

and abnormal

E2E suites. Use test:coverage:full

when Docker and the full integration environment are available. HTML and JSON coverage reports are written under server/coverage/

.

Bug reports, feature proposals, tests, and documentation improvements are welcome. Please keep credentials out of commits, run the relevant test and build commands before submitting changes, and keep protocol changes synchronized across protocol/

, cli/

, and server/

. Every code submission must include corresponding unit tests, and must not lower any of the coverage thresholds listed above.

Shellink is licensed under the MIT License.

── more in #ai-agents 4 stories · sorted by recency
── more on @shellink 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-shellink-let…] indexed:0 read:12min 2026-07-21 ·