Skip to content

Hivemind ↔ Chatalot integration

This is the operator runbook for letting Hivemind agents post messages into your chatalot channels. It uses chatalot's existing webhook system — no chatalot code changes, no admin tokens, no E2E client crypto. The webhook posts a single plaintext system message (MessageType::Webhook) into one specific channel that you create the webhook for.

This is the right pattern for: - Daily ops summaries — a hivemind agent posts a thread digest each morning into #ops. - Alert relays — when something pages, a hivemind agent posts the raw alert + its own commentary into #alerts. - Scheduled announcements — release notes, status updates, customer-facing messages. - Chatbot answers in a designated channel — the support agent echoes its answers into #support-log for transparency.

It is not the right pattern for: - Two-way conversations (the bot posting and reading replies). Webhooks are output-only. Inbound message subscription is a separate feature on the roadmap (CHAT bot-API + event-stream tickets). - Posting into E2E-encrypted private DMs. Webhooks live in regular channels only.

What you'll wire up

Hivemind agent
  → Hivemind's chatalot connector
    → POST https://chat.example.com/api/webhooks/execute/<token>
      → chatalot stores message_type=Webhook, broadcasts to channel

The token is created once per channel in chatalot's admin UI and stored in Vaultwarden. Hivemind looks it up by name when an agent calls chatalot post_message.

Step 1 — Create a webhook in chatalot

As an admin, in the chatalot web UI:

  1. Open the channel you want hivemind to post into (say #ops).
  2. Channel settings → WebhooksCreate webhook.
  3. Name it something the operator will recognize (e.g. hivemind-ops-relay).
  4. Save. Chatalot generates a 64-char token; the full URL looks like https://chat.example.com/api/webhooks/execute/<token>.
  5. Copy the URL.

You'll get one webhook URL per channel. Repeat this for every channel you want hivemind to post into.

Step 2 — Store the URL in Vaultwarden

Hivemind looks up webhook URLs by a predictable item name:

Chatalot Webhook - <instance> - <channel>

Where <instance> is a short slug for the chatalot instance (for example, separate slugs for your own dev and production instances, or a slug per customer) and <channel> is whatever you call the channel (loose convention — match the channel name in chatalot for clarity).

Examples of valid item names:

Chatalot Webhook - dev - test
Chatalot Webhook - prod - ops
Chatalot Webhook - prod - announcements
Chatalot Webhook - support - support-log

In Vaultwarden:

  1. Create a new login item with that exact name.
  2. Paste the full webhook URL into the password field.
  3. Save into the Infrastructure collection (or wherever the rest of your chatalot creds live).

Hivemind fetches the URL from your secret manager by that name when an agent posts, so no new credentials are embedded in the agent config.

Step 3 — Use it from Hivemind

Once an item exists, an operator (or an authorized hivemind agent) can post via the Hivemind:

chatalot action=post_message instance=prod channel=ops content="Daily ops summary: 3 alerts cleared, 2 customers ingested, 0 outages."

Optional flags on the same call:

  • username="Hivemind Ops Bot" — overrides the webhook's display name per message.
  • avatar_url=https://… — overrides the webhook avatar.

Returned JSON looks like:

{
  "ok": true,
  "instance": "prod",
  "http_status": 200,
  "url": "https://chat.seglamater.app/api/webhooks/execute/<token>"
}

For ad-hoc testing without Vaultwarden setup, pass the URL directly:

chatalot action=post_message webhook_url=https://chat.example.com/api/webhooks/execute/<token> content="hello"

Step 4 — Wire a hivemind agent to call it

Hivemind agent profiles (admin-tier) can invoke MCP tools when the operator has granted that permission. To let an agent post into chatalot:

  1. In Hivemind admin, edit the agent profile (e.g. ops-summary).
  2. Grant MCP access to chatalot.post_message. (Tier-1 public agents should NOT have this — webhook posts are operator-side automation, not customer-facing chat.)
  3. The agent's system prompt should specify which instance and channel to use, and any default username/avatar_url for branding.

When the agent runs (cron-driven directive, manual trigger, or reaction to another agent's output), it calls chatalot action=post_message ... and the message lands in chatalot in real-time, broadcast to all connected clients in that channel.

Rate limits + character limits

  • 1 message per second per webhook. Bursting beyond that returns HTTP 400 from chatalot ("webhook rate limited"). Hivemind doesn't retry; the agent should pace itself or batch into one message.
  • 1 to 4000 characters per message. Empty content and >4000 chars both fail validation.
  • 64-char username cap. Anything longer is rejected.

Operational notes

  • Tokens are sensitive. Anyone who has the URL can post into the channel. Treat them like deploy tokens. If a webhook leaks, delete it in chatalot's admin UI and create a fresh one.
  • Messages are plaintext on the server. This is intentional — bot output isn't end-to-end encrypted. Don't post anything in webhook messages that you wouldn't be comfortable having in chatalot's database in cleartext.
  • No inbound path. The bot can't read messages or react to user replies via this mechanism. That's tracked separately as the bot-API
  • event-subscription work.
  • Per-instance trust. A dev instance with a self-signed certificate can run with TLS verification disabled; production instances should verify normally. Configure each instance (name, base URL, and TLS verification) in your Hivemind connector settings.

Appendix — request shape

Hivemind wraps the underlying HTTP call so agents don't need to think about it, but for completeness:

POST /api/webhooks/execute/<token> HTTP/1.1
Host: chat.example.com
Content-Type: application/json

{
  "content": "your message body, 1-4000 characters",
  "username": "optional display-name override",
  "avatar_url": "optional avatar URL override"
}

Successful execution returns 201 with a JSON body — {message_id, channel_id, created_at, status} — so the caller can confirm delivery (prior to v0.25.23 this was an empty 200). Validation errors return 422/400 with a plaintext error reason.