Integration

Setup Unbo with Hermes Agent

Two ways to connect Unbo to the Hermes agent — pull email on demand over MCP, or push every message to Hermes with webhooks.

6 min read Beginner

Hermes is a self-improving agent from Nous Research that runs tools, connects to messaging platforms, and learns skills as it works. There are two ways to wire Unbo into it, and you can use either or both:

MCP — pullWebhook — push
DirectionHermes reads Unbo, on demandUnbo posts to Hermes, on arrival
Best forInteractive reading, search, triageReal-time automation & auto-replies
TriggerYou or the agent asksA new email arrives
Wiringmcp_servers + OAuthGateway + subscription + Unbo webhook

Two ways to connect

Reach for MCP when you want Hermes to fetch mail while reasoning — “summarise what’s in my support inbox” during a chat or task. Reach for webhooks when you want Hermes to act the moment an email lands, with no human in the loop. The rest of this guide sets up each.

Method 1 · Pull with MCP

Unbo exposes every inbox through a single MCP server. Hermes connects to it as a remote tool and negotiates a scoped token over OAuth — nothing to paste but the endpoint.

https://mcp.unbo.dev/mcp

Install MCP support

MCP is an optional extra in Hermes. Install it once:

terminal
cd ~/.hermes/hermes-agent
uv pip install -e ".[mcp]"

Register Unbo as an MCP server

Add Unbo under mcp_servers in ~/.hermes/config.yaml. The auth: oauth line tells Hermes to run the OAuth 2.1 flow rather than expect a static token.

config.yaml
# ~/.hermes/config.yaml
mcp_servers:
  unbo:
    url: "https://mcp.unbo.dev/mcp"
    auth: oauth

Authenticate

Log in once; Hermes stores and refreshes the token for you. Tools are discovered at startup, or on demand with /reload-mcp.

terminal
hermes mcp login unbo       # opens Unbo's OAuth consent screen
# inside a chat session, pick up new tools with:
/reload-mcp

Unbo’s tools register under the mcp_unbo_ prefix — mcp_unbo_list_inboxes and mcp_unbo_poll_emails. To keep the toolset tight, whitelist just what you need:

config.yaml
# ~/.hermes/config.yaml
mcp_servers:
  unbo:
    url: "https://mcp.unbo.dev/mcp"
    auth: oauth
    tools:
      include: [list_inboxes, poll_emails]

Verify

Start Hermes and ask something that requires reading the inbox:

Hermes

I found 3 recent messages in support@yourdomain.com via mcp_unbo_poll_emails. Two are refund requests referencing order #4471, and one is a partnership enquiry from acme.io. Want me to draft replies?

Method 2 · Push with webhooks

Here Unbo drives the agent: each incoming email is POSTed to Hermes’s webhook gateway, which renders your prompt template and triggers an agent run. This mirrors the webhook-subscriptions skill.

Enable the webhook gateway

Turn on the webhook platform and give it a secret. Reuse this value as your Unbo webhook signing secret so signatures line up.

config.yaml
# ~/.hermes/config.yaml
platforms:
  webhook:
    enabled: true
    extra:
      host: "0.0.0.0"
      port: 8644
      secret: "$UNBO_WEBHOOK_SECRET"
terminal
hermes gateway setup                 # or edit config.yaml as above
hermes gateway run                   # start the gateway
curl http://localhost:8644/health    # -> {"status":"ok"}

Subscribe to email events

Create a subscription whose prompt template pulls fields straight from Unbo’s payload using dot notation ({from}, {subject}, {text_body}). Attach skills and a delivery target so Hermes can act and report back.

terminal
hermes webhook subscribe unbo-email \
  --events "email.received" \
  --prompt "New email from {from} — {subject}

{text_body}" \
  --skills "inbox-triage" \
  --deliver telegram \
  --deliver-chat-id "-100123456789" \
  --secret "$UNBO_WEBHOOK_SECRET"

Subscriptions persist to ~/.hermes/webhook_subscriptions.json and hot-reload on each request — list them with hermes webhook list.

Point your Unbo inbox at the gateway

In Unbo, open your inbox’s webhook settings and set the delivery URL to the gateway’s subscription endpoint (expose localhost:8644 with a tunnel like cloudflared or ngrok during development). Set the inbox’s signing secret to the same value as the subscription’s --secret.

Unbo delivers a structured JSON payload — these are the fields your prompt template can reference:

POST body from Unbo
{
  "event": "email.received",
  "from": "customer@example.com",
  "to": ["support@yourdomain.com"],
  "subject": "Where is my order?",
  "text_body": "Hi, I still haven't received order #4471...",
  "spf": "pass",
  "dkim": "pass",
  "dmarc": "pass"
}

Test it

Fire a sample payload through the subscription without waiting for real mail:

terminal
hermes webhook test unbo-email \
  --payload '{"from":"customer@example.com","subject":"Where is my order?","text_body":"..."}'

A successful run returns 200 OK; delivery failures return 502 so Unbo retries. When a real email lands, Hermes triages it automatically:

Hermes

🚨 New support email from customer@example.com“Where is my order?”. This references order #4471, which shipped 6 days ago and is now overdue. I’ve drafted an apology with the tracking link and flagged it for a refund check.

Which should you use?

Use MCP for interactive, on-demand work — reading, searching, and triaging mail inside a conversation or task. Use webhooks for hands-off automation that reacts to mail in real time. Many setups run both: MCP for exploration, webhooks for the always-on pipeline.