Skip to content
 
 

Latest commit

 

History

41 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hermes MAX Platform Plugin

MAX Messenger platform adapter for Hermes Agent.

This plugin lets Hermes receive and send messages through MAX (max.ru) using either webhook delivery or long polling. It supports text, markdown formatting, attachments, images, files, voice/audio, video, inline keyboards, callback events, typing/read actions, and cron notification delivery to a default chat.

Features

  • Inbound messages through webhook or polling.
  • Outbound text with automatic chunking for MAX message limits.
  • Markdown-compatible formatting for bold, italic, strikethrough, code, links, and headings.
  • Images, files, audio/voice, and video delivery.
  • Inline keyboard attachments from send metadata.
  • Callback event handling.
  • Optional allow-list for permitted MAX user IDs.
  • Optional default chat for cron and notification delivery.

Requirements

  • Hermes Agent with platform plugin support.
  • Python package: aiohttp.
  • A MAX bot token.

platform-api2.max.ru's TLS cert chains to the Russian Ministry of Digital Development's own root CA, which isn't in the standard system/Mozilla trust store. The ca/ directory bundles the official root+sub certs (from gu-st.ru, the Mintsifry-operated distribution host) and the adapter extends (not replaces) the default trust store with them — no extra system CA installation needed on the host running Hermes.

Install the runtime dependency in the same environment that runs Hermes:

pip install aiohttp

Installation

This is a third-party (Plugin Path) adapter, not a bundled/core one — per Hermes's own gateway/platforms/ADDING_A_PLATFORM.md, third-party plugins belong directly under ~/.hermes/plugins/<name>/, not ~/.hermes/plugins/platforms/<name>/ (that platforms/ subdirectory is reserved for adapters bundled with Hermes itself — the plugin scanner keys a user-installed plugin by its directory name one level down from ~/.hermes/plugins/, so installing under platforms/max registers a platform key of platforms/max instead of max, and the adapter silently never loads).

The simplest correct install is via the Hermes CLI, which handles the path for you:

hermes plugins install <your-repo-url-or-owner/repo>
hermes plugins enable max

Equivalent manual install:

git clone <your-repo-url> ~/.hermes/plugins/max
hermes plugins enable max

Then restart the gateway (hermes gateway restart) for it to pick up the newly enabled platform.

Configuration

The plugin reads configuration from Hermes platform config and from environment variables. Environment variables take precedence for deployment-specific values.

Required:

Variable Description
MAX_BOT_TOKEN MAX bot token used as the API Authorization header.

Optional:

Variable Description
MAX_TRANSPORT webhook or polling. Defaults to webhook when MAX_WEBHOOK_URL is set, otherwise polling.
MAX_WEBHOOK_URL Public HTTPS webhook URL registered with MAX, for example https://example.com/max/webhook. MAX expects external HTTPS on port 443.
MAX_WEBHOOK_SECRET Secret validated against X-Max-Bot-Api-Secret on webhook requests.
MAX_WEBHOOK_HOST Local webhook bind host. Defaults to 0.0.0.0.
MAX_WEBHOOK_PORT Local webhook listen port. Defaults to 8650.
MAX_WEBHOOK_PATH Local webhook path. Defaults to /max/webhook.
MAX_UPDATE_TYPES Comma-separated update types. Defaults to message_created,message_callback,bot_started.
MAX_API_BASE_URL MAX Bot API base URL. Defaults to https://platform-api2.max.ru (the pre-2026-07-19 host, platform-api.max.ru, is retired — override only for tests, proxies, or compatible endpoints).
MAX_ALLOWED_USERS Comma-separated MAX user IDs allowed to talk to the bot.
MAX_ALLOW_ALL_USERS Set to true to allow any MAX user. Intended for development only.
MAX_HOME_CHANNEL Default chat ID for cron and notification delivery.
MAX_HOME_CHANNEL_NAME Optional display name for the home channel.
MAX_HOME_CHANNEL_THREAD_ID Optional thread ID for home channel delivery metadata.

Webhook Mode

Webhook mode starts a local aiohttp server and registers the public webhook URL with MAX.

Typical deployment shape:

  1. Run Hermes with MAX_TRANSPORT=webhook.
  2. Bind the plugin locally, for example 0.0.0.0:8650/max/webhook.
  3. Put a reverse proxy in front of it.
  4. Expose the public URL over HTTPS on port 443.
  5. Set MAX_WEBHOOK_URL to that public URL.

Example:

export MAX_BOT_TOKEN="..."
export MAX_TRANSPORT="webhook"
export MAX_WEBHOOK_URL="https://example.com/max/webhook"
export MAX_WEBHOOK_SECRET="change-me"
export MAX_WEBHOOK_HOST="0.0.0.0"
export MAX_WEBHOOK_PORT="8650"
export MAX_WEBHOOK_PATH="/max/webhook"

Polling Mode

Polling mode does not require a public endpoint. It periodically reads updates from the MAX API.

export MAX_BOT_TOKEN="..."
export MAX_TRANSPORT="polling"

If MAX_TRANSPORT is omitted and MAX_WEBHOOK_URL is not set, polling is used.

Outbound Media

Hermes can send local files through platform adapters. When replying through MAX, use an absolute local file path in a MEDIA: directive when Hermes needs to deliver a generated file:

MEDIA:/absolute/path/to/file.png

Audio files such as .mp3, .wav, .m4a, and .ogg are best delivered as files/documents when preserving sound quality matters.

Inline Keyboards

The adapter supports inline keyboards in two ways.

Use inline keyboards when the user needs to choose a short action or open a link. Keep them compact, usually 2-4 buttons. Do not add buttons to ordinary informational replies.

Hermes clarify prompts with choices are rendered as native MAX inline buttons automatically. Button taps unblock the waiting agent turn through the standard Hermes clarify flow.

For ordinary Hermes replies, include a MAX-specific directive in the outgoing text. The adapter removes the directive before sending and converts it to a native MAX inline_keyboard attachment:

Choose an action:
<!-- max_buttons: [[{"text":"Continue","payload":"continue"}],[{"text":"Open","url":"https://example.com"}],[{"text":"Copy","copy":"text for clipboard"}]] -->

Button shorthands:

  • { "text": "Continue", "payload": "continue" } → MAX callback button
  • { "text": "Open", "url": "https://example.com" } → MAX link button
  • { "text": "Copy", "copy": "text for clipboard" } → MAX clipboard button
  • raw MAX button objects also pass through, e.g. { "type": "clipboard", "text": "Copy", "payload": "text for clipboard" }

For manual testing, the same JSON can be written as a fenced block:

Choose an action:
```max_buttons
[[{"text":"Continue","payload":"continue"}]]
```

Programmatic sends can also pass MAX-specific metadata. Supported metadata shapes include:

{
    "max_inline_keyboard": [
        [{"text": "Open", "url": "https://example.com"}],
        [{"text": "Pick", "payload": "resume:123"}],
    ]
}

or raw MAX attachments:

{
    "max_attachments": [
        {"type": "inline_keyboard", "payload": {"buttons": [[...]]}}
    ]
}

Localization

The native command menu (/help, /model, etc. — see MAX_NATIVE_COMMANDS in adapter.py) ships with Russian descriptions by default; the command names stay English on purpose. MAX's command menu only stores a name + description pair — name is the literal slash-command trigger, and Hermes's gateway dispatcher (gateway/run.py) matches incoming text against a fixed set of canonical English command names. Translating name would show a nice Russian trigger in MAX's UI, but tapping it sends text the dispatcher doesn't recognize and the command silently no-ops. Only description — pure display text with no effect on dispatch — is safe to translate, so that's the only field this plugin localizes.

For a full reference of every Hermes gateway command (not just the 12 in MAX's menu) with Russian descriptions, see COMMANDS.ru.md.

For everything Hermes says beyond the command menu — approval prompts, restart/drain notices, and the replies of several built-in slash commands — Hermes ships its own translation catalog (agent/i18n.py, locales/<lang>.yaml), independent of this plugin, and Russian (ru) is already a supported, essentially complete catalog (as of this writing, locales/ru.yaml is 416 lines against 428 in locales/en.yaml). It's not wired to MAX specifically — it recolors every platform Hermes talks on at once (Telegram, Discord, CLI, MAX, ...). Because it's global rather than MAX-specific, this plugin does not turn it on for you at install time; opt in yourself by adding to ~/.hermes/config.yaml:

display:
  language: ru

Restart the gateway (hermes gateway restart) afterward. Note /whoami's reply specifically is not yet migrated into this catalog (it's an f-string in gateway/slash_commands.py), so it stays English even with language: ru set — everything else covered by the catalog will switch.

Development

Useful checks:

python -m py_compile adapter.py __init__.py
git status --short

This repository is maintained as an independent MAX platform plugin for Hermes. The earliest implementation was imported from the public MaZzZilka/hermes-max-plugin repository and then substantially reworked for webhook support, media delivery, callbacks, chunking, and Hermes gateway integration.

About

MAX Messenger platform plugin for Hermes Agent

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages