screenshot-mcp
by Bra1nZ
README.md
# screenshot-mcp
MCP-сервер для **KDE Plasma 6 / Wayland**: агент открывает настоящее окно консоли,
управляет им и снимает рабочий стол штатным средством системы (Spectacle — тем же,
что вызывается по PrintScreen).
Ключевая сложность в том, что под Wayland не работают привычные приёмы автоматизации
терминала: `xdotool` не вводит текст в нативные Wayland-приложения, `wmctrl` не
существует, а `tmux` умеет управлять сессией, но не окном на экране. Здесь ввод идёт
**прямо в псевдотерминал**, поэтому терминал показывает его так же, как ввод с
клавиатуры, — без эмуляции клавиш и без каких-либо следов в интерфейсе.
Возможности:
* новое отдельное окно консоли с **твоим** `~/.bashrc` — твой промпт, цвета, алиасы;
* ввод команд и чтение вывода с кодом возврата;
* интерактивные программы: ввод, `Ctrl+C`, `Ctrl+D`, стрелки, история команд;
* снимок всего рабочего стола с поднятием окна консоли на передний план;
* снимок возвращается агенту прямо в ответе (картинкой), так что он может сам
оценить, что попало в кадр.
## Как это устроено
```
MCP-сервер (server.py)
│ UNIX-сокет, JSON
▼
bridge.py — «насос»: переливает ввод и вывод
│ псевдотерминал (pty)
▼
bash ── запущен прямо в окне Konsole, наследует ~/.bashrc
```
* Настоящий `bash` работает **внутри** окна Konsole и подхватывает пользовательский
`.bashrc`. Заголовок окна при этом неотличим от обычного (`<каталог> : bash — Konsole`).
* Агент пишет байтами прямо в pty. Их обрабатывает tty-драйвер (отражение ввода) и
`readline` — то есть это буквально тот же путь, что и при наборе с клавиатуры.
Никакой эмуляции клавиш, поэтому в терминале не остаётся следов автоматизации.
* Код возврата берётся через хук `PROMPT_COMMAND`, который пишет маркер в служебный
файл: на экране ничего не появляется.
* Окно поднимается на передний план KWin-скриптом: окно находится по PID процесса
Konsole, активация — `workspace.activeWindow = client`.
* Снимок делает `spectacle -b -n -o <file>` — тот же бинарник, что Plasma запускает
по PrintScreen, поэтому картинка неотличима от сделанной вручную.
## Требования
* KDE Plasma 6 в сессии Wayland;
* `konsole` и `spectacle` (в Plasma 6 идут вместе с ней);
* `qdbus6` — для скриптинга KWin;
* Python 3.11+ и пакет `mcp`.
Проверено на Debian 13, KDE Plasma 6.3, Wayland.
## Установка
```bash
git clone git@github.com:Bra1nZ/screenshot-mcp.git
cd screenshot-mcp
pip install -r requirements.txt
```
## Подключение
### opencode
`~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"screenshot-mcp": {
"command": ["python3", "/путь/к/screenshot-mcp/server.py"],
"type": "local"
}
}
}
```
### Другие MCP-клиенты
Сервер говорит на stdio, поэтому подходит любому клиенту с поддержкой локальных
MCP-серверов. Команда запуска:
```bash
python3 /путь/к/screenshot-mcp/server.py
```
Сервер запускается **в графической сессии** и наследует `WAYLAND_DISPLAY` и
`DBUS_SESSION_BUS_ADDRESS`; если переменных нет, подставляются значения по умолчанию
для текущего пользователя.
## Инструменты
| Инструмент | Назначение |
|---|---|
| `console_open(cwd, cols, rows, title, terminal)` | открыть новое окно консоли, вернуть `console_id` |
| `console_exec(console_id, command, timeout, typing_delay_ms)` | напечатать команду и дождаться результата: `output`, `exit_code`, `timed_out` |
| `console_send(console_id, text, enter)` | напечатать текст без выполнения — для программ, ждущих ввода |
| `console_key(console_id, key)` | спецклавиши: `enter`, `tab`, `esc`, `up`/`down`, `ctrl+c`, `ctrl+d`, `f1`..`f12` |
| `console_read(console_id, cursor)` | дочитать новый вывод |
| `console_state(console_id)` / `console_list()` | состояние консолей |
| `console_close(console_id)` | закрыть окно |
| `desktop_screenshot(path, console_id, delay_ms, preview)` | снимок рабочего стола; `console_id` — сначала поднять окно; возвращает метаданные и уменьшенную копию картинки |
| `desktop_focus(console_id)` | поднять окно консоли на передний план |
| `desktop_active_window()` / `desktop_list_windows()` | что сейчас на переднем плане, список окон |
## Пример сессии
```
console_open(cwd="~/projects/lab") → console_id
console_exec(console_id, "make") → output, exit_code
console_exec(console_id, "ls -la build/") → убедиться, что артефакты на месте
desktop_screenshot(console_id=console_id) → PNG в ~/Pictures/Screenshots + картинка в ответе
```
## Ограничения
* **Только KDE Plasma 6 / Wayland.** Скриншоты и консоль работают и под X11, но
поднятие окна на передний план реализовано через KWin-скриптинг, то есть только
под KWin.
* **Экран должен быть разблокирован.** Пока активен lock screen, KWin не отдаёт
снимки — это защита композитора. `desktop_screenshot` в этом случае вернёт понятное
сообщение.
* Символ табуляции в командах не поддерживается: `bash` воспринимает его как запрос
автодополнения.
* `console_exec` ждёт нового промпта; для долгих задач нужен `timeout`, для
интерактивных программ — `console_send` и `console_key`.
## Безопасность
Сервер даёт подключённому агенту **полный контроль над консолью в графической сессии
и чтение содержимого экрана**. Это инструмент автоматизации, а не средство
изоляции: запускай его только с тем агентом, которому доверяешь, и не оставляй
незакрытые окна консоли с активными сессиями.
Скриншоты складываются в стандартную папку KDE для снимков и дублируются в
`screenshots/` рядом с сервером — помни, что они могут содержать чувствительные
данные с экрана.
## Тесты
Тесты живые: они открывают настоящие окна и снимают настоящий экран, поэтому
требуют запущенной сессии KDE Plasma.
```bash
pip install -r requirements-dev.txt
python3 tests/test_bridge.py # pty-мост: команды, вывод, код возврата
python3 tests/test_interactive.py # ввод в программу, ctrl+c, история
python3 tests/test_e2e.py # полный цикл: окно → команды → фокус → снимок
python3 tests/test_mcp_stdio.py # протокол MCP: список тулов и вызовы
```
В CI (`.github/workflows/ci.yml`) гоняются только линтер и проверка импорта —
живые тесты в контейнере без композитора не запустятся.
## Лицензия
MIT — см. [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues