# Ssh Chat Mcp

> Zero-config SSH/SFTP MCP server. All connection data is passed from chat - never from config files, env vars, or disk. Built by AI Platforms (aiplatforms.ru).

- **Type:** MCP server
- **Install:** `agentstack add mcp-aiplatforms-ru-ssh-chat-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [aiplatforms-ru](https://agentstack.voostack.com/s/aiplatforms-ru)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [aiplatforms-ru](https://github.com/aiplatforms-ru)
- **Source:** https://github.com/aiplatforms-ru/ssh-chat-mcp
- **Website:** https://aiplatforms.ru/

## Install

```sh
agentstack add mcp-aiplatforms-ru-ssh-chat-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

ssh-chat-mcp

  Zero-config SSH/SFTP MCP server.
  All connection data is passed from chat — never from config files, env variables, or disk.

  
  
  
  
  
  
  

---

  English · Русский

---

## English

`ssh-chat-mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server that
lets an LLM client open temporary SSH/SFTP sessions to remote hosts, run commands
(including `sudo -iu`), and upload/download files — **without** the MCP server
holding any pre-baked credentials, hosts, paths, or environment secrets.

You start the server with no arguments. Then, in chat, you give the model a host
plus credentials, it calls `connect`, does its work, calls `disconnect`, and the
credentials are wiped from RAM.

> Built by **[AI Platforms](https://aiplatforms.ru/)** — on-premises LLM and computer-vision systems for enterprises that need their AI to stay inside their own server room.

### Why zero-config

Most SSH automation wants you to put `~/.ssh/config`, `inventory.yml`,
`HOST=…`, `SSH_PRIVATE_KEY=…` or similar on disk. That's fine for one stable
production target and a CI worker. It's wrong when:

- You want an LLM client to *occasionally* SSH into a box you set up yesterday,
  deploy a thing, and walk away.
- You don't want a hostname / username / key visible to anything that reads
  your MCP config — including extensions, IDE integrations, or other MCP
  servers.
- You don't want the LLM client to remember anything about your infrastructure
  once the chat ends.

`ssh-chat-mcp` keeps the MCP layer pure and pushes every connection detail into
the conversation, where you (the user) can see it explicitly and where it dies
with the connection.

### Install

Requires **Node.js 20 or newer** (22 recommended).

**Option A — npx (recommended, zero install).** Point your MCP client at
`npx -y ssh-chat-mcp`. The first run downloads the package; later runs are
instant from cache. Nothing to clone or build. See [Integrations](#integrations).

```bash
# verify it runs (starts silently; Ctrl+C to stop)
npx -y ssh-chat-mcp
```

**Option B — global install.**

```bash
npm install -g ssh-chat-mcp
ssh-chat-mcp        # starts the stdio server
```

**Option C — from source (for development).**

```bash
git clone https://github.com/aiplatforms-ru/ssh-chat-mcp.git
cd ssh-chat-mcp
npm install
npm run build
node build/index.js
```

In all cases the server starts silently and must not print anything to stdout
(stdout is reserved for MCP JSON-RPC traffic). Press `Ctrl+C` twice quickly to
stop. A single `Ctrl+C` only cancels in-flight commands/jobs so MCP clients can
interrupt a tool call without killing the whole stdio transport. No output is
expected during normal operation.

### Quick start

In your MCP client (Claude Code / Codex / Kilo / LM Studio / Cursor / etc.),
register the server (see [Integrations](#integrations) below), then say:

> Use the `ssh-chat` MCP. Call `connect` with connectionName=`t1`,
> host=`203.0.113.10`, username=`deploy`, password=``. Then run
> `exec` with command `whoami && hostname`. Then `disconnect`.

That's the whole workflow: connect → do stuff → disconnect.

---

### Tools

All inputs are validated with [zod](https://github.com/colinhacks/zod). All
outputs and error messages pass through a redaction layer that removes:

- Field values for keys named `password`, `passphrase`, `privateKey`,
  `sudoPassword`, `token`, `apiKey`, `Authorization`, `secret`.
- `password=`, `*_PASSWORD=`, `token=`, `secret=`, `Authorization: Bearer …`
  patterns in text.
- PEM-encoded private key blocks.

| Tool | What it does |
|------|--------------|
| `connect` | Open an SSH session. Requires `connectionName`, `host`, `username`, plus `password` or `privateKey` (PEM). Optional `port` (default 22), `passphrase`, `readyTimeoutMs`, `keepaliveIntervalMs`. Credentials live only in RAM. |
| `disconnect` | Close the SSH+SFTP session and wipe credentials from memory. |
| `list_connections` | Return non-sensitive metadata for all active connections. |
| `diagnose` | Local MCP/SSH diagnostics. With no args it proves the MCP server is alive and lists connections/jobs. With `connectionName`, it runs a short SSH probe and returns `ok`, `ssh_unresponsive`, `ssh_error`, `connection_missing`, etc. |
| `exec` | Run a shell command. With `cwd`, wraps as `cd  && `. Returns `stdout, stderr, exitCode, signal, timedOut`. |
| `exec_start` | Start a long-running command and return immediately with `jobId`. Use for `git clone`, `pip install`, `apt install`, builds, and reboot waits that may outlive the MCP client's tool timeout. |
| `exec_as` | Run as another Linux user via `sudo -S -p '' -iu  -- bash -lc `. `runAs` is strictly validated (`^[a-z_][a-z0-9_-]{0,31}$`). `sudoPassword` is piped via stdin and never logged. |
| `exec_as_start` | Long-running version of `exec_as`; returns `jobId` immediately and stores rolling stdout/stderr buffers in memory. |
| `exec_status` | Read a command job status plus stdout/stderr slices. Pass returned `nextOffset` values back as `stdoutOffset`/`stderrOffset` for incremental log reads. |
| `exec_jobs` | List known command jobs without logs. |
| `exec_cancel` | Best-effort cancellation for a job. If the remote PID is known, sends the signal to the remote process group and closes the SSH channel. |
| `exec_remove` | Remove a completed/cancelled/failed job and drop its buffered logs. |
| `upload_file` | SFTP upload one file. Optional `mode`, `mkdirParents`. |
| `upload_directory` | Recursive SFTP upload. Caller-supplied `exclude` list. Symlinks not followed by default. |
| `download_file` | SFTP download to local disk. |
| `read_remote_file` | Read remote file as UTF-8 text, up to `maxBytes`. Content is redacted. |
| `write_remote_file` | Write text to a remote file via SFTP. Useful for staging systemd/nginx configs into `/tmp` and then `sudo mv`-ing them in place. |

---

### Long-running commands

For commands that can exceed your MCP client's tool timeout, prefer:

1. `exec_start` or `exec_as_start` with the long command.
2. `exec_status` every so often, using `stdout.nextOffset` and
   `stderr.nextOffset` from the previous response.
3. `exec_cancel` if the job must be stopped.
4. `exec_remove` after completion if you want to drop the in-memory log buffers.

This keeps the MCP transport responsive: the first call only opens the SSH
channel and returns a `jobId`; stdout/stderr are held in rolling in-memory
buffers and read later by job id. If a job times out or is cancelled, the server
tries to signal the remote process group before closing the SSH channel.

---

### Integrations

All snippets below use the **npx** form (`npx -y ssh-chat-mcp`) — no install,
no paths. If you installed from source instead, replace
`{ "command": "npx", "args": ["-y", "ssh-chat-mcp"] }` with
`{ "command": "node", "args": ["/abs/path/to/ssh-chat-mcp/build/index.js"] }`.
On Windows, npx-based clients sometimes need the launcher wrapped as
`"command": "cmd", "args": ["/c", "npx", "-y", "ssh-chat-mcp"]`.

#### Claude Code (CLI)

```bash
claude mcp add ssh-chat --scope user -- npx -y ssh-chat-mcp
```

Verify with `/mcp` inside Claude Code.

#### Claude Desktop

Edit:

- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "ssh-chat": {
      "command": "npx",
      "args": ["-y", "ssh-chat-mcp"]
    }
  }
}
```

Fully restart the Claude Desktop app (quit from tray, not just close the window).

#### OpenAI Codex CLI

Edit `~/.codex/config.toml` (Windows: `%USERPROFILE%\.codex\config.toml`):

```toml
[mcp_servers.ssh-chat]
command = 'npx'
args = ['-y', 'ssh-chat-mcp']
startup_timeout_sec = 30
tool_timeout_sec = 120
enabled = true
```

#### Kilo Code

Edit `~/.config/kilo/kilo.jsonc`:

```jsonc
{
  "mcp": {
    "ssh-chat": {
      "type": "local",
      "command": ["npx", "-y", "ssh-chat-mcp"],
      "enabled": true,
      "timeout": 120000
    }
  }
}
```

#### LM Studio

Edit `%USERPROFILE%\.lmstudio\mcp.json` (Windows) or the equivalent on your OS:

```json
{
  "mcpServers": {
    "ssh-chat": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "ssh-chat-mcp"]
    }
  }
}
```

macOS / Linux:

```json
{
  "mcpServers": {
    "ssh-chat": {
      "command": "npx",
      "args": ["-y", "ssh-chat-mcp"]
    }
  }
}
```

#### Cursor

`~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "ssh-chat": {
      "command": "npx",
      "args": ["-y", "ssh-chat-mcp"]
    }
  }
}
```

#### Continue.dev / Hermes / VS Code MCP extensions

Most MCP-capable extensions follow the same shape:

```json
{
  "name": "ssh-chat",
  "command": "npx",
  "args": ["-y", "ssh-chat-mcp"],
  "transport": "stdio"
}
```

Consult your client's docs for where this JSON lives.

#### Any stdio-capable MCP client

If your client supports stdio servers at all, point it at:

- **command:** `npx`
- **args:** `["-y", "ssh-chat-mcp"]`
- **env / cwd:** not needed
- **transport:** stdio

There is intentionally nothing else to configure.

---

### Example chat workflow

> Use the `ssh-chat` MCP. Connect to `203.0.113.10:22` as `deploy` with the
> password I just gave you. Upload `D:\Projects\myapp` to `/tmp/myapp`,
> excluding `.git` and `node_modules`. As `appuser`, create a venv and install
> `requirements.txt`. Write a systemd unit to `/tmp/myapp.service` and
> `sudo mv` it to `/etc/systemd/system/`. Reload systemd, enable and start
> `myapp.service`. Write an nginx site to `/tmp/myapp.nginx` and install it to
> `/etc/nginx/sites-available/`, symlink it into `sites-enabled/`, run
> `nginx -t`, reload nginx. Then `disconnect`.

Typical tool sequence:

1. `connect` — credentials enter memory.
2. `upload_directory` — SFTP the project to `/tmp/myapp`.
3. `exec` — `cd /tmp/myapp && ...` for unprivileged setup.
4. `exec_as` — `runAs: "appuser"` for app-user steps (venv, pip).
5. `write_remote_file` — stage `/tmp/myapp.service`.
6. `exec` — `sudo mv /tmp/myapp.service /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl enable --now myapp`.
7. `exec` — `sudo nginx -t && sudo systemctl reload nginx`.
8. `disconnect` — credentials wiped.

---

### Security

See [SECURITY.md](SECURITY.md) for the full threat model. Short version:

- ✅ Credentials never touch disk.
- ✅ Tool output and error messages pass through redaction.
- ✅ `sudo` password is piped via stdin, never on a command line.
- ✅ POSIX shell quoting on every `cwd`/`command` interpolation.
- ✅ Strict Linux-username validation on `runAs`.
- ⚠️ Host-key checking is **off** by design (zero-config means no on-disk known_hosts). The calling user is responsible for trusting the host.
- ⚠️ There is **no destructive-command blacklist**. Your MCP client's tool approval flow is the only checkpoint.
- ⚠️ Passing a password or private key into chat means it's visible in your chat client's transcript and may be logged by your model provider. Prefer local/private clients (LM Studio, Claude Code locally), and rotate credentials after the session if you have any doubt.

---

### Development

```bash
npm install
npm run typecheck
npm test
npm run build
```

Project layout:

```
src/
  index.ts                  MCP stdio server + tool registration
  types.ts                  shared types
  ssh/
    connectionManager.ts    in-memory Map
    exec.ts                 exec, exec_as (sudo -iu)
    sftp.ts                 upload/download/read/write
  security/
    redact.ts               redact strings, values, errors
    shellQuote.ts           POSIX quoting, Linux-username validation
test/
  redact.test.ts
  shellQuote.test.ts
  errors.test.ts
```

---

## Русский

`ssh-chat-mcp` — это [MCP](https://modelcontextprotocol.io)-сервер, который
позволяет LLM-клиенту открывать временные SSH/SFTP-сессии к удалённым хостам,
выполнять команды (включая `sudo -iu`), загружать и скачивать файлы — **без
каких-либо предзаписанных в конфиге кредов, хостов, путей и переменных окружения**.

Сервер запускается без аргументов. Дальше в чате модель получает от тебя host
и креды, вызывает `connect`, делает работу, вызывает `disconnect` — и креды
стираются из памяти.

> Сделано в **[AI Platforms](https://aiplatforms.ru/)** — внедрение приватных LLM и систем компьютерного зрения для предприятий, которым нужно, чтобы ИИ оставался в их собственной серверной.

### Зачем zero-config

Большинство SSH-автоматизаций просит положить на диск `~/.ssh/config`,
`inventory.yml`, переменные `HOST=…`, `SSH_PRIVATE_KEY=…`. Это нормально для
одной стабильной прод-машины и CI-раннера. Это неправильно, когда:

- Ты хочешь, чтобы LLM-клиент *иногда* зашёл по SSH на машину, которую ты
  поднял вчера, что-то задеплоил и забыл.
- Ты не хочешь, чтобы hostname / username / ключ были видны всему, что читает
  твой MCP-конфиг — расширениям IDE, интеграциям, другим MCP-серверам.
- Ты не хочешь, чтобы LLM-клиент вообще что-либо помнил про твою
  инфраструктуру после окончания чата.

`ssh-chat-mcp` держит MCP-слой чистым и пушит все детали подключения в
переписку, где они видны тебе явно и умирают вместе с соединением.

### Установка

Требуется **Node.js 20+** (рекомендуется 22).

**Вариант A — npx (рекомендуется, без установки).** Укажи MCP-клиенту
`npx -y ssh-chat-mcp`. Первый запуск скачает пакет, дальше — мгновенно из кэша.
Ничего клонировать и собирать не нужно. См. [Интеграции](#интеграции-ru).

```bash
# проверка запуска (стартует молча; Ctrl+C для остановки)
npx -y ssh-chat-mcp
```

**Вариант B — глобальная установка.**

```bash
npm install -g ssh-chat-mcp
ssh-chat-mcp        # запускает stdio-сервер
```

**Вариант C — из исходников (для разработки).**

```bash
git clone https://github.com/aiplatforms-ru/ssh-chat-mcp.git
cd ssh-chat-mcp
npm install
npm run build
node build/index.js
```

Во всех случаях сервер запускается молча и не должен ничего писать в stdout
(stdout зарезервирован под MCP JSON-RPC). Для остановки нажми `Ctrl+C` два раза
быстро. Один `Ctrl+C` только отменяет активные команды/jobs, чтобы MCP-клиенты
могли прервать tool call без убийства всего stdio-транспорта. В штатной работе
вывода быть не должно.

### Быстрый старт

В твоём MCP-клиенте (Claude Code / Codex / Kilo / LM Studio / Cursor / …)
зарегистрируй сервер (см. [Интеграции](#интеграции-ru)) и скажи в чате:

> Используй MCP `ssh-chat`. Вызови `connect` с connectionName=`t1`,
> host=`203.0.113.10`, username=`deploy`, password=``. Потом
> запусти `exec` с command=`whoami && hostname`. Потом `disconnect`.

Весь цикл: connect → работа → disconnect.

---

### Инструменты

Все входы валидируются через [zod](https://github.com/colinhacks/zod). Все
выходы и ошибки проходят через redaction-слой, который убирает:

- Значения полей с именами `password`, `passphrase`, `privateKey`,
  `sudoPassword`, `token`, `apiKey`, `Authorization`, `secret`.
- Паттерны `password=`, `*_PASSWORD=`, `token=`, `secret=`,
  `Authorization: Bearer …` в тексте.
- PEM-блоки приватных ключей.

| Инструмент | Что делает |
|-----------|-----------|
| `connect` | Открывает SSH. Обязательно: `connectionName`, `host`, `username` + `password` или `privateKey` (PEM). Опционально: `port` (по умолчанию 22), `passphrase`, `readyTimeoutMs`, `keepaliveIntervalMs`. Креды только в RAM. |
| `disconnect` | Закрывает SSH+SFTP, стирает креды из памяти. |
| `list_connections` | Возвращает нечувствительные метаданные активных соединений. |
| `diagnose` | Локальная диагностика MCP/SSH. Без аргументов доказывает, что MCP-сервер жив, и показывает соединения/jobs. С `connectionName` делает короткий SSH probe и возвращает `ok`, `ssh_unresponsive`, `ssh_error`, `connection_missing` и т.п. |
| `exec` | Выполняет shell-команду. Если задан `cwd`, оборачивает в `cd  && `. Возвращает `stdout, stderr, exitCode, signal, timedOut`. |
| `exec_start` | Запускает долгую команду и сразу возвращает `jobId`. Для `git clone`, `pip install`, `apt install`, сборок, ожидания reboot и всего, что может пережить timeout MCP-клиента. |
| `exec_

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [aiplatforms-ru](https://github.com/aiplatforms-ru)
- **Source:** [aiplatforms-ru/ssh-chat-mcp](https://github.com/aiplatforms-ru/ssh-chat-mcp)
- **License:** MIT
- **Homepage:** https://aiplatforms.ru/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-aiplatforms-ru-ssh-chat-mcp
- Seller: https://agentstack.voostack.com/s/aiplatforms-ru
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
