# Hermes в телефоне: свой клиент вместо мессенджеров


Работать с Hermes через мессенджеры неудобно, поэтому я написал для него свой клиент под Android. Сегодня вышла первая сборка, `v0.1.0-rc1`[^release].

## Что такое Hermes

Hermes — открытый агент от Nous Research под лицензией MIT[^hermes]. Он работает на сервере, а не на ноутбуке: модель выбирается любая (OpenRouter, OpenAI, свой endpoint и другие), инструменты выполняются в выбранном окружении — локально, в Docker, по SSH. У агента есть память, навыки, которые он сам создаёт и правит, поиск по прошлым сессиям, планировщик cron и подключение MCP-серверов.

С агентом можно говорить из терминала (`hermes`), а можно запустить шлюз (`hermes gateway`) и писать ему из мессенджеров. Список каналов большой: Telegram, Discord, Slack, WhatsApp, Signal, Matrix, Mattermost, Email, SMS, Microsoft Teams и ещё десяток платформ[^messaging]. Шлюз — один процесс: он держит подключения ко всем каналам, ведёт сессии по каждому чату, запускает задачи cron и доставляет их результаты в нужный канал.

Третий способ — веб-панель `hermes dashboard`. В ней есть чат, а ещё настройки: модель, `config.yaml`, секреты, задачи cron, навыки, каналы, журналы.

У меня Hermes крутится в контейнере на домашнем сервере, каналов два: бот в Telegram и бот на моём Matrix-сервере. Память агенту даёт [memcue](/2026/10/27/memcue/), о ней я писал вчера.

## Чем неудобны мессенджеры

Неудобства сводятся к двум вещам: отдельный разговор трудно начать и потом трудно найти.

**Треды.** Каждой задаче нужна своя сессия, иначе контексты разных разговоров смешиваются. В личке с ботом мессенджер даёт для этого треды, но их надо создавать руками. В Telegram это темы в личке: режим включается командой `/topic`, а новая тема создаётся кнопкой «+»[^tg]. Эта схема у меня ещё и ломалась: мобильный клиент иногда присылает первое сообщение новой темы без номера темы, и ответ уходит в общий чат. Разбор этой истории — в [отдельном посте](/2026/10/17/telegram-dm-topic-thread-less-opener/). В Matrix Hermes по умолчанию не заводит треды в личке, их включает отдельная настройка, либо тред приходится начинать самому[^matrix].

**Поиск.** Через неделю нужно вернуться к разговору, а где он был? В Telegram или в Matrix, в какой теме или треде? Поиск мессенджера находит сообщение, но про сессии Hermes ничего не знает и ищет только в своём канале. Команда `/sessions search` фильтрует сессии лишь по названию или идентификатору[^messaging], а содержимое разговоров ей не видно.

## Hermes for Android

Приложение — клиент для `hermes dashboard`, проверенное на Hermes v0.22.5[^repo]. Сервер ставить отдельно не нужно: приложение пользуется тем же API, что и веб-панель. Код на Kotlin и Jetpack Compose, лицензия MIT.

### Чат

Чат устроен как в приложении ChatGPT. Список чатов — в боковой панели. Каждый чат — отдельная сессия, и новый открывается кнопкой с карандашом или если потянуть ленту вверх за последнее сообщение. Создавать тред руками больше не нужно. Ответ приходит потоком через WebSocket панели: Markdown, рассуждения модели над ответом, а вызовы инструментов свёрнуты в одну строку, которую можно раскрыть. Код в ответе копируется одним нажатием. На вопросы агента и запросы на подтверждение отвечают кнопками на панели, которая выезжает снизу чата.

В боковой панели чаты сгруппированы по дате и по источнику: свои, из Telegram, из Matrix. Закреплённые чаты сверху, архив и запуски cron — в отдельных разделах. Поиск идёт по полнотекстовому индексу на сервере, то есть по тексту разговоров, и находит в том числе то, что писалось из Telegram и Matrix.

Вложения: фото, камера, любой файл. Картинки, PDF, Markdown, текст и код, аудио и видео открываются внутри приложения, в том числе файлы, которые прислал сам агент. Диктовка отправляется в тот провайдер распознавания речи, который настроен в Hermes.

### Работа в фоне и уведомления

Ход агента не обрывается, если свернуть приложение: сокет держит foreground-сервис, а ответ приходит уведомлением. На запрос подтверждения можно ответить прямо из уведомления.

Чтобы узнавать о готовых ответах без постоянного соединения, в репозитории лежит плагин `hermes-push` для сервера. Он отправляет Web Push после каждого хода в приложении, в Telegram, в Matrix или в cron. Доставка идёт через UnifiedPush, например через ntfy. Сообщение шифруется ключами телефона (RFC 8291), так что сервер push видит только шифротекст. Без плагина приложение проверяет новости периодически, не чаще раза в 15 минут, или держит постоянное соединение, если его включить: своего push у панели нет.

### Управление сервером

Раздел сервера показывает состояние и позволяет менять то, ради чего раньше открывался SSH: шлюз, модель, `config.yaml` (по схеме или сырым YAML), секреты `.env`, задачи cron, навыки, наборы инструментов, MCP-серверы и каналы. Здесь же журналы и расход токенов. Всё, что может сломать или удалить что-то на сервере, сначала спрашивает подтверждение.

### Соединение

У каждого сервера свой маршрут:

| Маршрут | Когда |
|---|---|
| Напрямую | Телефон видит панель сам: публичный адрес, приложение Tailscale, домашний Wi-Fi |
| Встроенный Tailscale | Приложение само входит в tailnet через `tsnet`, слот VPN не нужен |
| SOCKS5, HTTP | Есть прокси, который видит сервер; логин по желанию |

Встроенный Tailscale — это узел Tailscale, собранный из Go через gomobile и запущенный внутри процесса приложения. `VpnService` он не использует, поэтому работает рядом с любым другим VPN. Узлу нужен адрес control-сервера Tailscale или Headscale и, по желанию, pre-auth ключ; без ключа приложение покажет ссылку для входа. Журналы узла остаются на телефоне.

Сервер можно добавить по ссылке, чтобы не набирать ключ на телефоне:

```text
org.evsyukov.hermes://add-server?url=hermes.example.org&route=tailscale&control=https://hs.example.org&key=<pre-auth key>
```

Вход идёт через поток `native_pkce` панели. Если сервер доступен напрямую, вход открывается в Custom Tab, и там работают passkey. Если сервер за прокси или во встроенном tailnet, страница входа открывается во WebView, чей трафик идёт тем же маршрутом.

### Интерфейс и язык

Интерфейс на английском с русским переводом. На Android 13 и новее язык приложения можно выбрать отдельно от системного.

## Ограничения и статус

Это первая сборка, и пока выходят только release candidate. Приложение совсем новое, и проверено оно пока на одном сервере — моём. Известные ограничения перечислены в README:

- без плагина `hermes-push` новости приходят с задержкой или требуют постоянного соединения;
- на обычном `hermes dashboard` REST-методы сессий не трогают сессии, созданные в процессе панели. Поэтому переименование, архив и удаление идут через сокет, а закрепить такой чат может не получиться: метода для этого в сокете нет;
- режим панели со шлюзом (`session_authority`) поддержан только для основных вызовов.

APK подписан, собран для arm64 и требует Android 12 или новее. Скачать можно на странице релизов[^release].

## Попробуйте

Если вы держите Hermes у себя и пишете ему с телефона, поставьте приложение и скажите, что не так. Что неудобно, чего не хватает, на каком сервере и маршруте что-то сломалось — всё это лучше всего оставлять в issue в [juev/hermes](https://github.com/juev/hermes/issues). Пожелания по функциям туда же: приложение только начинается, и сейчас самое время решить, каким оно будет.

[^hermes]: [NousResearch/hermes-agent](https://github.com/NousResearch/hermes-agent), README и [документация](https://hermes-agent.nousresearch.com/docs/).
[^messaging]: [Messaging Gateway](https://hermes-agent.nousresearch.com/docs/user-guide/messaging), список платформ и команд внутри чата, в том числе `/sessions`, `/resume`, `/approve`, `/deny`.
[^tg]: [Telegram](https://hermes-agent.nousresearch.com/docs/user-guide/messaging/telegram), раздел про темы в личке и режим `/topic`.
[^matrix]: [Matrix](https://hermes-agent.nousresearch.com/docs/user-guide/messaging/matrix): треды в личке включают `MATRIX_DM_AUTO_THREAD` или `MATRIX_DM_MENTION_THREADS`, по умолчанию обе выключены.
[^repo]: [juev/hermes](https://github.com/juev/hermes), README.
[^release]: [Hermes 0.1.0-rc1](https://github.com/juev/hermes/releases/tag/v0.1.0-rc1), pre-release, файл `hermes-0.1.0-rc1.apk`.

