No description
  • Go 84.6%
  • TypeScript 8.9%
  • HTML 4.9%
  • SCSS 1.2%
  • Dockerfile 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ymnuk 0e2166cd0a
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
fix: keep-alive — любой ответ на проб считается живым звеном
Реальные OpenSSH-серверы отвечают на неизвестные глобальные запросы
REQUEST_FAILURE (включая keepalive@openssh.com), а прежняя проверка
требовала именно success. Из-за этого здоровые сессии — и прямые, и
цепочные — вылетали из пула после трёх циклов проб (~90 секунд при
keepalive_interval 30s) независимо от idle_timeout/ssh.timeout: у MCP
после очереди в несколько минут connect возвращал session_not_found.

Живость теперь доказывает любой протокольный ответ (success или
failure), как и ожидает собственный ping клиента OpenSSH; пропуском
считаются только молчание дольше probe-timeout или разрыв соединения —
эвикция по-прежнему срабатывает при настоящем NAT-drop. Мок testutil
по умолчанию отвечает failure, повторяя поведение реального сервера
(опционально KeepAliveSuccess); новый тест гарантирует выживание прямой
сессии через ~20 циклов проб.

Локально; push/tag/деплой — по стандартной схеме пользователя.
2026-09-23 13:31:40 +03:00
cmd/mcp-ssh feat: §10.3 этап 4 — поэлементная диагностика цепочки (links[]) в check_host 2026-09-19 10:17:43 +03:00
deploy build: убрать Windows-сборку из CI; выкинуть мёртвую MCP_SSH_AUTH_TOKEN_FILE из юнита 2026-09-10 13:09:02 +03:00
docs doc: §10.3 этап 7 — синхронизация доков с реализацией цепочных подключений 2026-09-19 13:41:09 +03:00
examples/mcp-client docs: синхронизировать документацию с реализацией и добавить пример MCP-клиента 2026-09-09 20:58:24 +03:00
internal fix: keep-alive — любой ответ на проб считается живым звеном 2026-09-23 13:31:40 +03:00
testutil fix: keep-alive — любой ответ на проб считается живым звеном 2026-09-23 13:31:40 +03:00
.dockerignore fix: CI 2026-09-15 10:56:39 +03:00
.gitignore feat: добавить веб-интерфейс (Angular 22) и встроить через go:embed 2026-09-09 13:44:54 +03:00
.golangci.yml feat: §10.3 этап 2 — цепочный диалер direct-tcpip, known_hosts на каждое звено, keep-alive по всем звеньям 2026-09-19 09:23:19 +03:00
.woodpecker.yml fix: CI 2026-09-15 11:01:47 +03:00
config.example.yaml feat: фильтр опасных команд (exec_guard) — отказ до отправки на хост 2026-09-18 21:48:12 +03:00
docker-compose.yml build: добавить Dockerfile (node→go→scratch), docker-compose и health-подкоманду 2026-09-09 15:52:33 +03:00
Dockerfile fix: CI 2026-09-15 10:47:23 +03:00
Dockerfile.ci fix: CI 2026-09-15 10:52:38 +03:00
go.mod feat: добавить MCP-сервер и tools (Streamable HTTP, /mcp) 2026-09-09 09:32:35 +03:00
go.sum feat: добавить MCP-сервер и tools (Streamable HTTP, /mcp) 2026-09-09 09:32:35 +03:00
README.md build: добавить Dockerfile (node→go→scratch), docker-compose и health-подкоманду 2026-09-09 15:52:33 +03:00

mcp-ssh

Единый самодостаточный Go-сервис: один статический бинарник (CGO_ENABLED=0, работает в контейнере scratch без внешних утилит), который предоставляет:

  • MCP-сервер (Streamable HTTP, эндпоинт /mcp) — управление удалёнными серверами по SSH / SFTP / sudo для LLM-агентов;
  • REST API (/api/) и веб-интерфейс (Angular + Material, встроен через go:embed, раздаётся на /) — управление подключениями, генерация/импорт SSH-ключей, развёртывание ключей.

Вся логика SSH/SFTP/sudo — на чистом Go (golang.org/x/crypto/ssh, github.com/pkg/sftp); ssh/scp/sftp/ssh-copy-id из окружения не вызываются.

Подробности — в docs/: SPEC, CONFIG, API, MCP, DEPLOYMENT, SECURITY.


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

Docker (рекомендуется)

# 1) токен для /api/ (обязательный секрет)
export MCP_SSH_AUTH_TOKEN="$(openssl rand -hex 32)"

# 2) сборка и запуск (multi-stage: node → go → scratch)
docker compose up -d --build

# 3) проверка
curl -s localhost:3000/api/health
open  localhost:3000            # веб-интерфейс

Данные (ключи, connections.yaml, known_hosts) хранятся в томе mcp-ssh-data и переживают перезапуск.

Бинарник

# сборка
cd internal/web && npm ci && npm run build && cd ..
rm -rf internal/webui/dist && mkdir internal/webui/dist
cp -r internal/web/dist/web/browser/. internal/webui/dist/
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o bin/mcp-ssh ./cmd/mcp-ssh

# запуск
cp config.example.yaml config.yaml   # и заполните auth.token
./bin/mcp-ssh --config config.yaml

Проверка:

curl -s localhost:3000/api/health          # {"status":"ok",...}
curl -s -o /dev/null -w '%{http_code}\n' localhost:3000/   # 200 (SPA)
./bin/mcp-ssh --version

MCP-клиент

Эндпоинт: http://localhost:3000/mcp (Streamable HTTP). Пример подключения — в docs/MCP.md.


Управление без веб (CLI)

mcp-ssh key generate --id ed25519-web-1 --type ed25519
mcp-ssh host add --id web-1 --host 203.0.113.10 --user root --auth key --key ed25519-web-1
mcp-ssh deploy web-1
mcp-ssh host test web-1

Полный список — mcp-ssh help и docs/CONFIG.md §7.