Skip to main content

vk-platform

❖ Communityv0.2.3★ 1

VK Messenger gateway with community Long Poll, media attachments, allowlists, and project-lane routing.

Open in Hermes Desktop
hermes plugins install vk-platform

What it adds

Environment variables it needs 2

VK_GROUP_TOKENVK_GROUP_ID

README

From the reviewed commit f922a0f ↗; it updates when the author re-pins.

Hermes VK Platform Plugin

VK Messenger / VK community bot platform adapter for Hermes Agent.

This plugin lets Hermes receive messages from VK community messages via VK Group Long Poll and reply through the VK messages.send API.

Features

  • Inbound VK message_new and message_edit events through Group Long Poll.
  • Outbound replies with messages.send.
  • Direct messages and VK group conversations (peer_id = 2000000000 + chat_id).
  • Safe allowlist controls for VK users, peers, and peer+user policies.
  • TTL dedupe for repeated Long Poll message_new events after reconnect.
  • Optional cron/home-channel delivery through VK_HOME_CHANNEL.
  • Message editing for Hermes tool-progress bubbles through messages.edit.
  • Inbound media handling for photos, documents, voice messages, audio, video messages, and direct video files with bounded downloads.
  • Outbound media upload for image files, documents, voice files, and videos.
  • If VK video.save rejects an MP4 with auth/permission errors under group-token auth, video delivery falls back to sending the MP4 as a document attachment.
  • Markdown-style Hermes output is converted to VK-readable plain text because the regular VK messages.send API has no Telegram-like parse_mode for Markdown/HTML.
  • Optional per-channel prompts and skill bindings through Hermes config.
  • Optional Telegram-style message-reaction acks (VK_REACTIONS_ENABLED): a progress reaction while the agent works, then 👍/👎 on completion.
  • No mandatory third-party Python dependency; the adapter uses Python stdlib for VK HTTP calls.

Documentation

Requirements

  • Hermes Agent with plugin support.
  • A VK community/group.
  • Community messages enabled in VK.
  • VK Group Long Poll API enabled for message_new, message_edit and message_event (callback buttons).
  • A VK community access token with messages permission.

Hermes registration compatibility

Requires Hermes Agent >=0.21.3. PyPI 0.19.0 is not supported. The tested released baseline is GitHub tag v2026.9.14, commit 345cd2b057a452236de401d3534b8502a7465e8d, whose package version is 0.21.3. This is a supported baseline, not a claim about the earliest commit containing every API. Unreleased main is not required.

GitHub release tags and PyPI packages may differ: at verification, PyPI still published 0.19.0. Check the installed version and installation channel before upgrading; do not migrate a production deployment just to try the plugin. Version 0.2.2 declares the minimum in its manifest and rejects missing MessageEvent.allow_gateway_control or BasePlatformAdapter._event_session_key before registering VK, including on hosts that ignore the manifest requirement.

Hermes Agent v2026.9.14 includes the PlatformEntry.parse_target_ref_fn contract used for project-lane outbound targets. Plugin version 0.2.1 also supports registration when only that field is absent and the remaining host API matches: all base registration, configuration, access-control, and direct-peer send callbacks remain registered. The plugin logs a compatibility warning in that case.

Lane-qualified outbound targets such as 2000000042:lane:alpha require a Hermes build with parse_target_ref_fn. On a build without it, use a direct numeric peer target or update Hermes. Do not redirect a lane target by guessing or removing its lane suffix.

Registration compatibility is not a full VK end-to-end check. After an install or Hermes update, use this smoke checklist:

  1. hermes plugins list --enabled shows vk-platform enabled.
  2. hermes gateway status shows VK configured/connected after the gateway is started with valid credentials.
  3. Fresh gateway logs contain no VK plugin load or registration exception.
  4. If the compatibility warning appears, test only a direct numeric peer target; update Hermes before using project-lane outbound targets.

These checks prove plugin loading and connection state, not VK delivery. A full end-to-end check additionally requires an authorized live VK message and reply.

Install

From GitHub:

hermes plugins install web3blind/hermes-vk-platform --enable

Or with a full URL:

hermes plugins install https://github.com/web3blind/hermes-vk-platform.git --enable

Then configure and restart the gateway:

hermes gateway setup
hermes gateway restart

If you prefer manual setup, edit ~/.hermes/.env as shown below.

VK setup checklist

  1. Create or choose a VK community.
  2. Open community settings and enable community messages.
  3. Enable bot capabilities for conversations:
    • allow messages from users;
    • allow adding the community bot to chats/conversations;
    • enable the option usually named like chat bot, bot can work in conversations, or messages in conversations.
    • In VK's Russian UI this is often under Управление сообществом → Сообщения → Настройки для бота → Возможности ботов: set Возможности ботов to enabled and enable Разрешать добавлять сообщество в чаты.
  4. Enable Long Poll API for the community.
  5. Enable the message_new, message_edit, and message_event event types. message_event delivers callback button clicks: Allow Once / Deny, slash-command confirmations, clarification choices (including Other), and inline project selection, pagination, pin/unpin and command buttons. Without it, buttons can appear but never reach Hermes; message-history fallback cannot recover these clicks. The persistent menu next to the message input remains a text keyboard. Typed commands and replies remain supported. After updating the plugin, restart the gateway and request a fresh keyboard: buttons in older messages keep their original action type.
  6. Create a community token with messages permission.
  7. If using group conversations, allow adding the community bot to chats and add it to the target chat.
  8. Configure allowlists before starting the gateway.

VK documentation entry points:

Configuration

Required environment variables

Store these in ~/.hermes/.env:

VK_GROUP_TOKEN=vk1.a.your-community-token
VK_GROUP_ID=123456789

VK_GROUP_ID is the numeric community id without a leading minus sign.

Multiple profiles in one gateway

Version 0.2.3 reads VK credentials, allowlists and environment settings through Hermes' active profile secret scope. A missing scoped value does not fall back to the default profile's process environment. Set credentials and access controls for each independently connected profile; a profile without its own VK connection settings must not inherit another profile's community token. Profile-specific configuration remains a valid fallback within that profile.

The legacy YAML bridge keeps values on the current profile's configuration instead of writing them to process-global environment variables when a profile scope is active. Both dictionary and object configuration forms are supported. Outside a profile scope, the existing single-profile environment behavior is preserved.

On connection, the adapter also invokes native handler factories registered by other Hermes plugins through register_platform_handler. This enables that existing extension surface; VK itself still registers no tools, hooks or middleware.

Recommended allowlist

Do not run a personal Hermes agent open to all VK users. Configure at least one allowlist:

# Allow specific VK user ids:
VK_ALLOWED_USERS=123456,789012

# And/or allow specific VK peers/chats:
VK_ALLOWED_PEERS=123456,2000000001

By default the access policy is backward-compatible:

allowed user OR allowed peer

That means VK_ALLOWED_PEERS=2000000001 allows every participant of that VK chat to talk to Hermes. This can be useful for a small private chat whose membership you fully control, but it is risky for larger or public group conversations.

For stricter access, choose an explicit policy:

# Backward-compatible default: allowed user OR allowed peer.
VK_ACCESS_POLICY=any

# Only users from VK_ALLOWED_USERS may talk to Hermes.
VK_ACCESS_POLICY=user_only

# Only peers/chats from VK_ALLOWED_PEERS may talk to Hermes.
# Warning: in group chats, this allows every participant of the chat.
VK_ACCESS_POLICY=peer_only

# Sender must be in VK_ALLOWED_USERS AND chat must be in VK_ALLOWED_PEERS.
VK_ACCESS_POLICY=peer_and_user

You can also restrict particular chats to particular users:

# Format: peer:user|user;peer:user
VK_ALLOWED_USERS_BY_PEER=2000000001:123456|789012;2000000002:123456

VK_ALLOWED_USERS_BY_PEER takes precedence for the listed peer. If a peer is listed there, only the listed users are accepted in that peer.

For VK group conversations, peer id is:

peer_id = 2000000000 + chat_id

Example: VK chat id 1 becomes peer id 2000000001.

Global group invocation gate (optional)

Off by default. To require an invocation in all VK group conversations handled by this adapter, add non-secret settings to config.yaml:

vk:
  require_mention: true
  mention_patterns:
    - '(?<![\w@])(?:ИИЛада|курсор)\b'

Patterns are Python regular expressions, compiled case-insensitively with Unicode word boundaries. This example accepts КУРСОР: помоги and ИИЛада?, not суперкурсор, курсорный, ИИЛада2, ИИЛада_тест or @курсор. Use YAML single quotes to preserve backslashes. Invalid patterns are ignored with a warning; a malformed list does not disable the gate. No custom names are hardcoded into the plugin.

The same keys are accepted under gateway.vk or platforms.vk.extra (the latter overrides the shorthand). Use one configuration location to avoid ambiguity. DMs are unaffected. A direct reply whose raw VK reply_message.from_id identifies this bot community, or an explicit @club<ID> / [club<ID>|label] mention, also invokes it. Quoted/forwarded text and attachment summaries never supply a trigger. If a raw update lacks reply identity, it fails closed rather than fetching history to discover a possible invocation.

This gate is not authorization: existing sender/peer ACLs run first, including per-peer overrides. It adds no global owner-only rule and changes no other chat's membership permissions. Restrict a particular chat with allowed_users_by_peer, not a global user-only policy when other chats must retain their current access.

Non-control slash commands also require a name/native mention or a direct reply to this bot (for example, reply /help to its message). /stop remains available without a name; /approve and /deny bypass addressing only while the exact routed session has a blocking approval. Existing button controls remain available. Callback nonce, peer, prompt and request checks remain in force. The core's exact bare-word approval replies (such as yes / no) are promoted to slash controls only when the exact routed session has a blocking approval; the core still authorizes and resolves that request. An exact routed-session pending clarification accepts an unaddressed text answer; the checked route and answer are preserved without API enrichment or project selection. Merely being busy is not an invocation: unaddressed conversation is dropped before downloads, reactions or agent dispatch.

Unsafe testing mode

Only for isolated test communities:

VK_ALLOW_ALL_USERS=true

Do not use this for a personal Hermes instance with tools enabled.

Optional settings

# Default VK peer for cron/home delivery:
VK_HOME_CHANNEL=2000000001

# Download all inbound attachments to Hermes cache, not only file-like direct URLs:
VK_DOWNLOAD_ATTACHMENTS=false

# Maximum inbound attachment download size in bytes. Default: 25 MiB.
VK_MAX_ATTACHMENT_BYTES=26214400

# In-memory duplicate event TTL in seconds. Default: 1800.
VK_DEDUPE_TTL_SECONDS=1800

# Recurring message-history fallback. Default: enabled.
# Set this ENV value explicitly to false to disable the extra VK API reads.
VK_FALLBACK_POLL_ENABLED=true

# Poll timing and per-peer conversation-message-id batch. Defaults shown.
# Runtime minimum interval: 5 seconds. Batch size is clamped to 1..100.
VK_FALLBACK_POLL_INTERVAL_SECONDS=15
VK_FALLBACK_POLL_BATCH_SIZE=25

# Optional user token for video metadata fallback. Not needed for normal chat usage.
VK_USER_TOKEN=

Message-history fallback polling

Fallback polling is enabled by default. In addition to Group Long Poll, the adapter makes recurring messages.getByConversationMessageId reads for peers present in VK_ALLOWED_PEERS, the configured home channel, or project-lane configuration. This recovers ordinary user messages that Long Poll missed; it does not recover message_event callback clicks.

To avoid these additional recurring VK reads, set VK_FALLBACK_POLL_ENABLED=false explicitly in the environment and restart the gateway. Do not rely on YAML boolean false for this toggle in version 0.2.3. The runtime currently treats that YAML value as absent and keeps the default enabled behavior.

Message reactions (👌 → 👍/👎)

Optional Telegram-style processing acks. When enabled, the bot reacts to the incoming message with a "seen, working on it" reaction as soon as processing starts, and swaps it for a final 👍 (success) or 👎 (failure) reaction when the agent finishes. Reactions are cosmetic: API failures never break message flow.

VK_REACTIONS_ENABLED=true

VK identifies reactions by numeric id, not emoji. The default community set: 1=❤️ 2=🔥 3=😂 4=👍 8=😡 10=👌 16=🎉. Defaults: progress 10 (👌 — there is no 👀 in the VK default set), OK 4 (👍), FAIL 8. If your community rearranged reactions, override any step:

# Defaults shown:
VK_REACTION_PROGRESS=10
VK_REACTION_OK=4
VK_REACTION_FAIL=8

Set a step to 0 to disable it (e.g. VK_REACTION_PROGRESS=0 to only mark final outcomes). On cancelled/interrupted turns the progress reaction is removed. Requires the community token to have the messages permission; some very old API versions do not expose messages.deleteReaction — the adapter probes support lazily and degrades gracefully.

Optional YAML config

The plugin can also bridge a top-level vk: block from ~/.hermes/config.yaml into the platform config.

vk:
  group_id: "123456789"
  allowed_users:
    - "123456"
  allowed_peers:
    - "2000000001"
  access_policy: "peer_and_user"
  allowed_users_by_peer:
    "2000000001":
      - "123456"
  max_attachment_bytes: 26214400
  dedupe_ttl_seconds: 1800
  home_channel: "2000000001"
  channel_prompts:
    "2000000001": "This is a trusted VK chat. Keep replies concise."
  channel_skill_bindings:
    - id: "2000000001"
      skills:
        - research

Secrets such as group_token are better stored in .env, not config YAML.

Optional VK project lanes

VK community bots do not have Telegram-style topics or bot-managed Messenger folders. If one physical VK chat should host several Hermes project contexts, configure virtual project lanes as a VK plugin feature:

platforms:
  vk:
    extra:
      project_lanes:
        enabled: true
        chats:
          "2000000001":
            base_folder: ai-projects
            default_skills:
              - coding
            lanes:
              - id: rialo
                name: Rialo
                description: ретродроп и аналитика проекта Rialo
                folder: rialo
                skills:
                  - blockchain-project-research
                  - coding
                aliases:
                  - rialo

The legacy vk.project_lanes shape is still read for backward compatibility, but new automatic writes and imports use platforms.vk.extra.project_lanes.

Behavior:

  • one VK peer_id remains the physical chat container;
  • each lane is routed as a Hermes synthetic thread with thread_id=lane:<id>;
  • active lane selection is stored per peer_id + user_id;
  • the lane transcript is shared inside the synthetic thread, like Telegram topics / Discord threads;
  • /new while a lane is active resets only that lane session;
  • /project search <query> searches configured and chat-created lanes;
  • /project new <name> <skills_csv> <context...> creates a lane immediately when the id is safe and persists it to the approved VK project-lane config path;
  • /project new and Новый проект create parseable labeled/free-form lanes immediately, or fall back to a normal Hermes agent turn for ambiguous input;
  • /project edit <id> <what to change...> edits an existing lane immediately when the requested field changes can be parsed safely and persists the updated lane;
  • /project edit starts the same lightweight guided flow for the active lane: parseable field changes are applied immediately, ambiguous text falls back to a normal Hermes agent turn with edit context;
  • /project pin and /project unpin pin or unpin the active lane for that VK chat; pinned lanes stay above session-recency sorting;
  • /invite returns the current VK chat invite link from the bot using messages.getInviteLink(peer_id=<current>, reset=0);
  • Команды / /commands shows a screen-reader-friendly text list of VK chat commands with clickable text-command buttons;
  • /project off returns that user to the root VK chat context;
  • VK_HOME_CHANNEL is not changed by project lanes.

Commands and buttons:

/project                  show current project/menu
/project list             show project list
/project search <query>   search configured and chat-created lanes
/project off              disable active lane for you in this VK chat
/project <alias-or-id>    switch active lane
@alias <text>             send one message to a lane without switching
/project new              start conversational project creation
/project new <name> <skills_csv> <context...>
                          fast fallback creation draft
/project edit             start editing the active lane
/project edit <id> <what to change...>
                          fast fallback edit of an existing lane
/project pin              pin active project first in this VK chat
/project unpin            unpin active project
/invite                   show the current VK chat invite link
/commands                 show all VK chat commands

Project-list page navigation uses visible Предыдущая / Следующая text buttons. The hidden payload still carries the exact fallback command such as /project list 2; if VK sends only the visible label, the adapter falls back to saved per-user page state and moves relative to the last shown list page. Lists are ordered as pinned lanes first, then lanes with the newest Hermes synthetic-thread session activity, then lanes without activity in stable config/import order.

The Команды response includes an inline command keyboard with text buttons for copy-hostile commands such as /project list, /project new, /project edit, /project off, and /invite. These buttons deliberately use text actions so screen readers expose the command label and VK sends the same text a user could type manually.

VK keyboard actions useful for this plugin:

  • text — sends a visible button label as message text and may also carry payload. This is the preferred accessible/default action for project controls.
  • callback — sends a callback event without normal message text. Avoid for core navigation in VK desktop/browser because it can be exposed unreliably or remain stuck as loading.
  • open_link — opens a URL, useful for external resources, not for chat commands.
  • platform-specific actions such as location/app/payment are not appropriate for the project-lane command menu.

Example fallback draft command:

/project new Rialo blockchain-project-research,coding ретродроп и аналитика проекта Rialo

/project new without arguments and the Новый проект button start a normal Hermes agent-mediated creation flow. The VK adapter only records short-lived pending state and injects a strict project-creation instruction into the next ordinary Hermes turn; it does not directly call a model inside the VK callback path.

Configured/imported lanes live in platforms.vk.extra.project_lanes. Runtime UI state such as active lane, pinned lanes, pending create/edit prompts, editable list-message ids, and delivered-message lane anchors remains in ~/.hermes/vk_project_lanes_state.json. When a user creates or edits a lane from VK and the field changes are deterministic, the adapter writes the lane to the canonical config path automatically, similar to Hermes' topic/thread persistence model, so users do not need to remember a separate export step. If config writing fails, the adapter keeps a state overlay as a fail-safe and logs a warning.

Cron jobs can target a VK project lane with the explicit target form vk:<peer_id>:lane:<lane_id> or by using deliver=origin when the job origin is a VK synthetic thread. Cron-delivered VK messages are remembered by message id, so replying to the cron message routes into that lane even if the user's currently active project in the same physical VK chat is different.

To import existing mappings into a VK chat:

python plugins/platforms/vk/setup_helper.py lanes import --to-peer 2000000001 --from legacy,telegram,discord --telegram-chat-id -1001234567890 --dry-run
python plugins/platforms/vk/setup_helper.py lanes import --to-peer 2000000001 --from legacy,telegram,discord --telegram-chat-id -1001234567890

The importer reads Telegram topics from platforms.telegram.extra.group_topics and dm_topics (optionally filtered by --telegram-chat-id), legacy VK lanes from vk.project_lanes, and Discord thread mapping sections when present. It writes platforms.vk.extra.project_lanes.enabled: true and upserts lanes under chats.<peer>.lanes.

Persistent technical menu

By default, normal text and attachment replies in already eligible VK chats and DMs attach the persistent Проекты / Новый проект / Команды / Новая сессия keyboard. Eligibility is unchanged: an allowed peer/user ID, home channel, configured project peer, or allow_all_users. This is a UI convenience, not an authorization grant. Explicit project-menu responses retain their existing behavior by default.

To hide this menu in one chat without changing permissions or project routing, merge these non-secret settings into your existing config.yaml:

platforms:
  vk:
    extra:
      persistent_keyboard_enabled: true  # global default; false disables the menu
      persistent_keyboard_by_peer:
        "2000000042": false  # hide only in this example conversation
        "123456789": true   # optional DM override, even if the global default is false

Per-peer values override the global switch. Missing peer entries inherit it; the global default is true. Use YAML booleans (true / false), not quoted strings. Invalid global values fall back to true; invalid overrides are ignored. Numeric YAML peer keys are accepted, but quoted IDs are recommended. Setting true never makes an otherwise ineligible peer receive an automatic keyboard or grants access. Legacy vk / gateway.vk settings are also accepted; canonical platforms.vk.extra values take precedence.

Disabling applies to every new attachment of this persistent menu, including project commands, old cmd / new_session button payloads and their replies. It does not disable typed commands, project lanes, ACL checks, invocation rules, or inline project lists, command buttons, approvals, confirmations and clarify choices. No empty keyboard is sent automatically: VK clients may retain a keyboard already shown before the change. Clearing that existing keyboard is a separate explicit operator action. Activate configuration changes with your normal gateway restart; this setting does not modify running gateway state by itself.

Project lists are sorted by latest Hermes thread-session activity for that VK peer. The most recently used project appears first; lanes without sessions stay below in config order.

Usage

Start or restart the Hermes gateway after configuration:

hermes gateway restart

Then send a message to the VK community or an allowed VK chat.

Hermes will create sessions keyed by VK platform, chat type, peer id, and sender id. This keeps different VK chats isolated.

Cron/home delivery

If VK_HOME_CHANNEL is set, cron jobs and messaging deliveries can target VK by platform name where Hermes supports plugin platform delivery.

VK_HOME_CHANNEL=2000000001

VK_HOME_CHANNEL is only the default peer for home/cron/notification delivery. It is not the per-chat conversation context, and it should not be moved when a new thematic VK chat is created unless the operator explicitly says to make that new peer the default Home channel.

When creating a new thematic chat such as "content", "style", or "research":

  1. Create or choose the new VK conversation.
  2. Add its peer id to VK_ALLOWED_PEERS or the relevant peer allowlist.
  3. Add any matching vk.channel_prompts / vk.channel_skill_bindings for that peer if a special context is needed.
  4. Restart the gateway.
  5. Send a test message in the new chat.

Do not rewrite VK_HOME_CHANNEL as part of that flow unless the user asks to move Home/default delivery. Keep the existing Home peer stable.

If an agent is asked to "create a content chat", it should confirm whether the request means:

  • create/configure a separate allowed VK peer for content work; or
  • move the default Home channel to that peer.

The safe default is the first option: create/configure a separate chat and leave Home unchanged.

Troubleshooting

Hermes does not answer

Check:

  1. Gateway is running: hermes gateway status.
  2. Plugin is enabled: hermes plugins list --enabled.
  3. VK_GROUP_TOKEN and VK_GROUP_ID are set in ~/.hermes/.env.
  4. VK Long Poll is enabled and message_new events are selected.
  5. The sender or peer is allowlisted.
  6. Gateway was restarted after changing .env.

Logs:

grep -i 'VK:' ~/.hermes/logs/gateway.log | tail -80

Unauthorized sender in logs

A log line like this means the adapter deliberately ignored the message:

VK: ignoring unauthorized sender=<user_id> peer=<peer_id>

Add the exact user id to VK_ALLOWED_USERS or the exact peer id to VK_ALLOWED_PEERS, then restart the gateway. If VK_ACCESS_POLICY=peer_and_user, both must match. If the peer is listed in VK_ALLOWED_USERS_BY_PEER, the sender must be listed for that peer.

Group chat peer id confusion

VK group conversation peer ids start at 2000000000.

If VK chat id is 42, use:

VK_ALLOWED_PEERS=2000000042

VK API error 912: This is a chat bot feature

This usually means the VK community exists and the bot may even be present in the chat, but the community is not yet allowed to work as a chat bot in group conversations.

Open the VK community settings and enable the conversation bot settings. VK's UI labels vary, but look for options like:

  • Messages / community messages;
  • Bot capabilities / Chat bot;
  • Bot can work in conversations;
  • Allow adding the community to chats/conversations;
  • Long Poll API with message_new enabled.

In VK's Russian UI, the exact path is commonly:

Управление сообществом
→ Сообщения
→ Настройки для бота
→ Возможности ботов

There enable:

  • Возможности ботов;
  • Разрешать добавлять сообщество в чаты.

If you are using Hermes with browser access to a logged-in VK admin account, Hermes can help navigate this UI and turn the setting on after you explicitly approve that account action. The plugin installer itself does not silently change VK community settings.

After changing VK settings, restart Hermes and test the peer again:

hermes gateway restart

Tool progress creates multiple messages or does not update

This plugin implements edit_message() via VK messages.edit. If progress editing fails, check that VK returned an editable conversation_message_id for sent messages and inspect gateway logs for VK API errors.

Long messages

VK messages are chunked according to the adapter max message length. The default is 4096 characters.

Inbound attachments and responsiveness

Attachment downloads run outside the Long Poll intake path. Each message keeps its original project/session routing, caption and media types. Ordinary messages in the same session wait for earlier attachments to be ready; another project can continue independently. Hermes still owns agent execution and busy/steering behavior.

Downloads use at most three worker slots. Pending delivery is bounded, with reserved room for controls; ordinary overflow receives a retry notice instead of silently disappearing. Completed cache files are published atomically. A failed repeated download cannot truncate or remove a completed file already handed to an agent. Download errors retain the existing URL fallback rather than pretending a partial file is ready.

Approval/clarification controls and callbacks do not wait behind downloads. /stop, /new and /reset cancel earlier queued work in their session; later messages follow the control operation. Controls sent as replies to media do not download that media or treat attachment summaries as command arguments. Disconnect joins download cleanup before releasing worker slots; an outstanding socket read may take up to its network timeout to finish.

Security model

  • The adapter enforces its own allowlist before passing messages to Hermes.
  • VK_ALLOWED_PEERS permits every participant in the listed group chat unless you use VK_ACCESS_POLICY=peer_and_user or VK_ALLOWED_USERS_BY_PEER.
  • Repeated Long Poll events are deduplicated in memory by peer_id + conversation_message_id for VK_DEDUPE_TTL_SECONDS.
  • Inbound attachment downloads are streamed to cache and capped by VK_MAX_ATTACHMENT_BYTES.
  • Tokens are redacted from adapter errors.
  • VK_ALLOW_ALL_USERS=true is intentionally treated as unsafe.
  • Remote image URLs are sent as URLs instead of silently downloading arbitrary remote image data for outbound sends.
  • Inbound downloadable attachments are stored under the Hermes cache directory for gateway media processing.

Development

See docs/development.md.

License

MIT. See LICENSE.

VK project lanes accessibility note: /project list must include project names and /project <id> fallback as plain text, not only VK keyboard buttons. Project selection buttons use VK text actions with visible labels, not callback-only actions; some VK desktop/browser clients hide or poorly expose callback/inline keyboards from the accessible tree.

deferred-questions❖ Community★ 0

Durable non-blocking questions with exact answer binding and gateway continuation. Disclosure — its pre_gateway_dispatch hook sees every gateway message and consumes only `dq <id> …` answers from the stored recipient; with `enable_tool` on, the model can send questions to any chat the gateway already authorizes, and a question marked continue_agent resumes that chat's agent with the user's answer; questions and answers are stored unencrypted in $HERMES_HOME/deferred-questions/questions.sqlite3; it calls private gateway and adapter methods, so a Hermes update can break delivery until it is re-pinned.

Automation
secure-env-ingress❖ Community★ 0

One-use HTTPS forms for missing environment secrets, native encrypted Browser Vault logins/TOTP setup keys and payment cards, protected hosted payment-field filling, nested HTTPS verification codes/passcodes, and approved secret operations outside chat and LLM input. Disclosure — /senv setup supplies a skill using sudo for host packages and TLS setup after approval; the TLS listener binds all interfaces by default; pre_gateway_dispatch observes gateway messages to bind commands to their sender. In interactive Telegram sessions, secure_env_vault saves logins or fills a code field through the captured browser supervisor without explicitly submitting the site form. Explicit parent payment/nested-code targeting requires compatible host task/profile ownership and browser-generation evidence and fails closed without it; this is not a general fix for native Vault named-tab selection. Payment filling requires separate native consent and exact document/control guards; explicit resume requires existing nonempty values to match Vault. Site input callbacks, especially 3-D Secure, may authorize or auto-submit an operation. Unknown outcomes require external verification before retry. secure_operation executes administrator-allowlisted, SHA-256-pinned external Python consumers with gateway privileges; consumers are trusted, not sandboxed, and none are enabled by default. Secret input is not persisted by this mode; consumers must enforce their own handling policy. Links are bearer authorization, not submitter identity; cancellation cannot stop an already-running consumer.

Tools

← Back to the catalog · catalog built Oct 14, 2026