Skip to main content
Glama
vait90
by vait90

SSH MCP сервер (paramiko)

SSH MCP сервер на базе Paramiko, который умеет выполнять команды на удалённых машинах и перемещать файлы через SFTP. Доступен два типа транспорта, выбираемые переменной окружения / флагом:

  • http – конечная точка MCP streamable-http на пути /mcp (сюда подключается Cherry Studio), плюс документированный интерфейс OpenAPI/Swagger (/docs, /openapi.json).

  • stdio – классический транспорт MCP stdio (для локального запуска / docker exec).

ВАЖНО о портах: 2222 — это порт MCP-сервера, к которому подключается Cherry Studio. Это НЕ SSH-порт удалённой машины! SSH-порт удалённой машины обычно 22 (SSH_PORT). Итак: Cherry Studio → http://<host-IP>:2222/mcp → MCP-сервер → paramiko → SSH-порт 22 удалённой машины.


Доступные MCP-инструменты

Инструменты без состояния (stateless) — простые разовые операции

Инструмент

Описание

ssh_test

Проверка соединения и аутентификации с удалённой машиной.

ssh_execute

Выполнение ОДНОЙ команды оболочки в свежем подключении (stdout / stderr / exit-код). Нет памяти: cd / export не сохраняются для следующего вызова и не могут ответить на интерактивный промпт.

ssh_upload

Загрузка локального файла на удалённую машину через SFTP.

ssh_download

Скачивание файла с удалённой машины через SFTP.

Инструменты с сохранением состояния (stateful), интерактивные сессии — живая оболочка

Они держат живую оболочку открытой, где состояние сохраняется между вызовами (смена каталога после cd, переменные через export, обработка интерактивных промптов: пароль sudo, ответ [Y/n] для apt и т.д.).

Инструмент

Описание

ssh_open_session

Шаг 1 — открыть новую интерактивную оболочку, возвращает session_id.

ssh_send

Шаг 2 — отправить текст (команду или ответ на промпт) в сессию. session_id необходимо передавать всегда.

ssh_read

Шаг 3 (необязательно) — читать дополнительный вывод без отправки (для медленных/долгих команд).

ssh_close_session

Шаг 4 — закрыть сессию. Обязательно закрывай, когда закончил.

ssh_list_sessions

Список открытых сессий (хост, пользователь, бездействие), например если потерял session_id.

Описания инструментов (docstring) намеренно содержат очень подробные, простые инструкции на английском — «USE THIS WOW...», чтобы потребляющая модель точно понимала, когда и как использовать каждый инструмент.

Параметры каждого инструмента (host, port, username, password, private_key, private_key_path, passphrase, timeout) можно указать:

  • при каждом вызовом отдельно, или

  • по умолчанию в файле .env (переменные SSH_*). То, что не указано в вызове, берётся системой из окружениячающих переменных.

Поддерживаемая аутентифиция: пароль и ключ (inline PEM или путь к файлу, с опциональной фразой). Неизвестные ключи хоста сервер принимает автоматически (AutoAddPolicy), чтобы автоматизация шла бесшовно.


Related MCP server: SSH MCP Server

Использование без состояния и с состоянием (интерактивное)

Что когда имользовать?

  • Одна самостоятельная команда (например, ls, uptime, df -h) → ssh_execute. Каждый вызов открывает свежное соединение, выполняет одну команду, затем закрывает. Без памяти: cd и export не выживают до следующего вызова и на интерактивный промпт отвечать не умеют.

  • Всё интерактивное или многошаговое (сохранение состояния после cd/export, ввод пароля sudo, ответ на apt [Y/n], последовательные зависимости команды) → интерактивная сессия: ssh_open_session → ssh_send → ssh_read → ssh_close_session.

Рекомендуемый процесс работы (сессия)

  1. ssh_open_session → получаешь session_id (и входной баннер / первый промпт в initial_output).

  2. ssh_send → вводишь команду или отвечаешь на промпт. session_id нужно передавать при каждом вызове. По умолчанию также отправляет Enter.

  3. ssh_read (опционально) → для медленных/долгих команд собирает дополнительный вывод без отправки.

  4. ssh_close_session → когда закончил, закрой сессию.

С помощью ssh_list_sessions в любой момент можно посмотреть открытые сессии (хост, пользователь, бездействие), если потерял session_id.

Примеры (через REST-эндпоинты)

Открытие сессии:

curl -X POST http://localhost:2222/api/ssh/session/open \
  -H "Content-Type: application/json" \
  -d '{"host":"192.168.1.100","username":"user","password":"secret"}'
# -> {"ok":true,"session_id":"<ID>", "initial_output":"...prompt..."}

Смена каталога, которая сохраняется (сохранение состояния):

curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"cd /var/log && pwd"}'
# a következő ssh_send már a /var/log-ban futna

Команда sudo + ответ на промпт пароля:

# 1) elindítod a sudo parancsot
curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"sudo apt-get update"}'
# 2) a kimenetben megjelenik a "[sudo] password for user:" prompt -> beküldöd a jelszót
curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"my_sudo_password"}'

Ответ на вопрос [Y/n] от apt:

curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"sudo apt-get install htop","read_timeout":5}'
# amikor jön a "Do you want to continue? [Y/n]" kérdés:
curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"Y"}'

Закрытие сессии:

curl -X POST http://localhost:2222/api/ssh/session/close \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>"}'

Таймаут / бездействие / ошибки: каждая операция с сессией оппортунистически закрывает сессии, которые бездействуют дольше отпущенного SSH_SESSION_IDLE_TIMEOUT (по умолчанию 600 сек.), а также те, у которых питание канала умерло. Одновременно может быть открыто не более SSH_MAX_SESSIONS (по умолчанию 20) сессий — достижение лимита ясно сообщается об ошибке. Если session_id уже не существует, ответ точно говорит, что сделать (открыть новую или посмотреть через ssh_list_sessions).


Структура проекта

ssh-mcp-server/
├── app/
│   ├── __init__.py
│   ├── ssh_ops.py     # paramiko SSH/SFTP műveletek (közös logika)
│   └── server.py      # MCP tool-ok + FastAPI/OpenAPI + transport választás
├── requirements.txt
├── Dockerfile
├── docker-compose.yml # 2222:2222 publikálás
├── .env.example
└── README.md

1. Быстрый запуск с Docker (рекомендуется)

Подготовка

cd ssh-mcp-server
cp .env.example .env
# szerkeszd a .env-et: add meg a távoli gép adatait (SSH_HOST, SSH_USERNAME, stb.)

Сборка и запуск (HTTP-режим)

docker compose up -d --build

Это запускает сервер в HTTP-режиме и публикует порт 2222 на хосте (ports: "2222:2222").

Проверка

curl http://localhost:2222/health
# {"status":"ok","service":"ssh-mcp-server","mcp_endpoint":"/mcp"}
  • Swagger UI (в браузере): http://localhost:2222/docs

  • OpenAPI JSON: http://localhost:2222/openapi.json

  • MCP-эндпоинт (Cherry Studio): http://<host-IP>:2222/mcp

Остановка

docker compose down

2. HTTP-режим вручную (без Docker, для разработки)

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export TRANSPORT=http HOST=0.0.0.0 PORT=2222
python -m app.server

3. Режим stdio

Для сервера, работающего в контейнере, через docker exec:

docker exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.server

Или напрямую, без Docker:

TRANSPORT=stdio python -m app.server

4. Интеграция с Cherry Studio

A) HTTP (streamable-http) режим — рекомендуется, работает и через сеть

Контейнер работает в Docker у тебя на ноутбуке, а Cherry Studio использует IP хоста и порт 2222.

  1. Запусти сервер: docker compose up -d --build Docker

  2. Определи IP-адрес машины (хоста), на котором работает Docker:

    • Linux: hostname -I → например 192.168.1.50

    • Если Cherry Studio работает на той же машине, подойдёт и localhost / 127.0.0.1.

  3. Cherry Studio → Настройки (Settings) → MCP Servers → Add / Новый сервер.

  4. Укажи следующее:

    • Type / Тип: Streamable HTTP (если нет — SSE / HTTP)

    • URL / Endpoint: http://<host-IP>/2222/mcp

      • например http://192.168.1.50:2222/mcp

      • на той же машине: http://localhost:2222/mcp

  5. Сохрани и включи (Enable) сервер. Cherry Studio загрузит инструменты ssh_test, ssh_execute, ssh_upload, ssh_download.

Если подключаешься с удалённой машины, убедись, что порт 2222 доступен (брандмауэр должен разрешить), а Docker слушает на 0.0.0.0 (так настроено по умолчанию).

B) Режим stdio

Если Cherry Studio ожидает stdio MCP-сервер (запускает команду):

  • Command: docker

  • Arguments:

    exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.server

(Для этого контейнер ssh-mcp-server должен работать — docker compose up -d.)


5. Конфигурация .env

Переменная

Описание

По умолчанию

TRANSPORT

http или stdio

http

HOST

Адрес привязки MCP HTTP

0.0.0.0

PORT

Порт MCP HTTP (к нему подключается Cherry Studio)

2222

SSH_HOST

Адрес удалённой машины

–

SSH_PORT

SSH-порт удалённой машины

22

SSH_USERNAME

Пользователь SSH

–

SSH_PASSWORD

Пароль SSH (или используй ключ)

–

SSH_PRIVATE_KEY

Простой ключ (PEM)

–

SSH_PRIVATE_KEY_PATH

Путь к файлу приватного ключа (в контейнере)

–

SSH_PASSKEY

Парольная фраза приватного ключа

–

SSH_CONNECTION_TIMEOUT

таймаут подключения (сек.)

15

SSH_SESSION_IDLE_TIMEOUT

Автоматическое закрытие бездействующей интерактивной сессии через N сек. (0 = нет)

600

SSH_MAX_SESSION_COUNT

Максимум одновременно открытых интерактивных сессий

20

Аутентификация по ключу в Docker

Подмонтируй ключи в контейнер и задай путь. В docker-compose.yml раскомментируй строку volumes:

    volumes:
      - ./keys:/keys:ro

затем в .env:

SSH_PRIVATE_KEY_PATH=/keys/id_ed25519

6. REST-эндпоинты для тестирования (OpenAPI)

HTTP-режим, помимо MCP-эндпоинта Cherry Studio, предоставляет также REST-эндпоинты — они выполняют те же SSH-операции и удобны в использовании через curl / Swagger UI:

Метод

Путь

Операция

GET

/health

Статус

GET

/

Информация о сервере

POST

/api/ssh/test

Тест подключения

POST

/api/ssh/execute

Выполнение команды

POST

/api/ssh/upload

Загрузка файла (SFTP)

POST

/api/ssh/download

Скачивание файла (SFTP)

POST

/api/ssh/session/open

Открытие интерактивной сессии (шаг 1)

POST

/api/ssh/session/send

Отправка ввода в сессию (шаг 2)

POST

/api/ssh/session/read

Чтение вывода без отправки (шаг 3)

POST

/api/ssh/session/close

Закрытие сессии (шаг 4)

GET

/api/ssh/session/list

Список открытых сессий

Пример (разовое выполнение без сохранения состояния):

curl -X POST http://localhost:2222/api/ssh/execute \
  -H "Content-Type: application/json" \
  -d '{"host":"192.168.1.100","username":"user","password":"secret","command":"uname -a"}'

Замечания по безопасности

  • Секретов никогда нет в коде — всё читается из .env / параметра вызова.

  • Файл .env исключается файлами .dockerignore и обычно .gitignore — не коммить его в систему контроля версий.

  • Сервер использует AutoAddPolicy (автоматическое принятие неизвестных ключей хоста). В закрытой сети это удобно; в более строгой среде стоит использовать известные ключи хоста.

  • Открывай порт MCP 2222 только в доверенной сети.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.
    183 npm
    37
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables remote server management via SSH, including command execution, file transfer (SFTP), and interactive shell sessions, with support for multiple hosts.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to securely execute commands on remote hosts via SSH and SFTP, with persistent shells, file transfers, screenshots, and an audit log.
    4
    MIT