Skip to main content
Glama
xcdd
by xcdd

Agent SSH MCP

MCP server for persistent SSH sessions with tmux integration, port forwarding, and SFTP file writes — built for AI agent workflows.

Based on ssh-mcp-sessions by Justin Fry (MIT), with significant enhancements for agent reliability.


What's improved over the original

The original fryjustinc/ssh-mcp-sessions provides 8 basic tools that execute commands directly in a hidden ssh2 shell buffer. This repo is a significant rework:

Architecture changes

Original

This repo

Commands run in a hidden ssh2 shell; output captured via in-memory buffer

Commands run inside a tmux session (ai); user can attach and watch live with tmux attach -t ai

Single end marker: printf '__MCP_DONE__%s%d\n' $? — no start marker, no polling

Dual start+end markers polled via capture-pane; output extracted between them

No reconnect logic — connection loss kills the session

Auto-reconnects on next command; keepalive every 30 s

No file transfer

SFTP: upload-file, download-file, write-remote-file

No port forwarding

forward-port / stop-forward via ssh2 forwardOut

New tools added

Tool

Purpose

setup-tmux

(Re)initialize tmux on an existing session

upload-file

Upload local file to remote via SFTP

download-file

Download remote file to local via SFTP

write-remote-file

Write text content directly via SFTP — no shell, no quoting issues, no heredoc

forward-port

Forward a local TCP port to a remote host:port

stop-forward

Stop a port forward tunnel

Reliability fixes

Issue

Root cause

Fix

Captured output contained entire pane history

End marker regex required a preceding \n; commands without trailing newline caused marker detection to fail → 30 s timeout → full pane returned as fallback

Regex changed to `endMarker(\d+)(?:\n

Long sessions accumulated large scrollback, slowing polling

capture-pane -S -1000 scanned 1000 lines on every poll

tmux clear-history before each command + window reduced to -S -200

heredoc (<< EOF) hung the session

tmux waits for EOF input that never arrives

Detected and rejected with a helpful error

exit code -1 was indistinguishable from a real command failure

Timeout and true failure both returned the same code

Timeout now returns [tmux capture timed out — command may still be running]


Related MCP server: mcp-remote-ssh

Installation

npm install -g agent-ssh-mcp

Or run without installing:

npx agent-ssh-mcp

MCP Client Configuration

Add to your MCP client config (Claude Desktop, Claude Code, Cursor, etc.):

{
  "mcpServers": {
    "ssh": {
      "command": "npx",
      "args": ["agent-ssh-mcp"]
    }
  }
}

Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)

Claude Code / VS Code.vscode/settings.json:

{
  "claude.mcpServers": {
    "ssh": { "command": "npx", "args": ["agent-ssh-mcp"] }
  }
}

Cursor~/Library/Application Support/Cursor/mcp.json (macOS)


Host Configuration

Hosts are stored in ~/.ssh-mcp/hosts.json, created automatically on first use.

Add a host

{
  "tool": "add-host",
  "host_id": "my-server",
  "host": "1.2.3.4",
  "port": 22,
  "username": "root",
  "password": "optional",
  "keyPath": "~/.ssh/id_rsa"
}

Authentication priority: password → private key → SSH agent (SSH_AUTH_SOCK).


Tools Reference

Session lifecycle

Tool

Parameters

Description

add-host

host_id, host, port, username, password?, keyPath?

Save SSH host config

list-hosts

List all saved hosts

edit-host

host_id + any field to change

Update host config

remove-host

host_id

Delete host config

start-session

host_id, sessionId?

Connect and auto-initialize tmux

list-sessions

Show active sessions with uptime

close-session

sessionId

Disconnect and clean up

setup-tmux

session_id

(Re)initialize tmux on an existing session

Command execution

Tool

Parameters

Description

exec

session_id, command

Run a command; auto-routes through tmux when available

Note: Do not use tmux send-keys manually — exec handles tmux routing automatically.

Avoid heredoc syntax (<< EOF). Use write-remote-file instead.

File transfer

Tool

Parameters

Description

upload-file

session_id, local_path, remote_path

Upload local file via SFTP (preferred for large/binary files)

download-file

session_id, remote_path, local_path

Download remote file via SFTP

write-remote-file

session_id, remote_path, content

Write text content directly via SFTP — handles special characters, no shell quoting issues

Port forwarding

Tool

Parameters

Description

forward-port

session_id, local_port, remote_host, remote_port, tunnel_id?

Forward 127.0.0.1:<local_port><remote_host>:<remote_port>

stop-forward

tunnel_id

Stop a port forward tunnel

Example — access a remote PostgreSQL locally:

{
  "tool": "forward-port",
  "session_id": "my-session",
  "local_port": 15432,
  "remote_host": "127.0.0.1",
  "remote_port": 5432
}

Then connect to postgresql://user:pass@127.0.0.1:15432/db.


Typical Agent Workflow

1. add-host       → save target server
2. start-session  → SSH connect + tmux init (returns session_id)
3. exec           → run commands (output is clean, no scrollback pollution)
4. write-remote-file / upload-file → write files reliably
5. forward-port   → expose remote services locally if needed
6. close-session  → clean up

Sessions auto-close after 2 hours of inactivity.


tmux Observability

Every command is executed inside a tmux session named ai. You (or the user) can attach to watch in real time:

ssh root@<host>
tmux attach -t ai

Building from Source

git clone https://github.com/xcdd/Agent-SSH-MCP
cd Agent-SSH-MCP
npm install
npm run build

Run tests:

npm test

Security Notes

  • ~/.ssh-mcp/hosts.json may contain passwords — treat it as sensitive (chmod 600).

  • Prefer key-based or SSH agent authentication.

  • Sessions inherit all privileges of the SSH user.


License

MIT — see LICENSE.

Original work © 2025 Justin Fry. Modifications © 2026 xcdd.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xcdd/Agent-SSH-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server