Notifications

The gateway tells you when it needs you — where you work, over your own infrastructure.

That is the whole promise of this surface. The gateway runs agents autonomously; the moments where a human has to step in are rare, and the worst place for them to surface is silently in a dashboard nobody opens. When a connection breaks, when a policy fires, when a refresh token needs human re-authorization — you want to find out before your users do.

The Notifications layer is the delivery side of that. The detection logic lives in the gateway's own monitoring and audit code. This page is about where the alert goes once something has decided it is worth raising.

The delivery chain

Three channels in a fixed fallback order:

  1. Slack DM via your workspace bot — first in line
  2. Microsoft Teams via your own bot — second
  3. Email (SMTP) via your own mail relay — baseline

The dispatcher walks the chain top-to-bottom and stops at the first configured channel that accepts the message. So an instance with a Slack workspace gets an instant DM; an instance with only SMTP configured still gets the alert reliably; an instance with all three configured uses Slack first and never spams the other two for the same event.

A per-event cooldown sits in front of the chain (Redis-backed where available, in-memory otherwise). The same alert for the same context inside a one-hour window does not re-fire. So a repeating OAuth error during a vendor outage produces one notification on the first occurrence, not a flood.

Where it lives in the admin panel

Sidebar → General → Notifications — at /admin/notifications on your gateway. The page shows every channel as its own card, with current configuration state, the relevant secrets fields, and a Send test notification button per channel that fires a real message through the dispatcher restricted to that one channel (so a working Slack does not mask a broken Teams or Email setup during verification).

Values persist through the same persistent_config layer as the setup wizard: changes save to /data/gateway.env, sync to os.environ, and hot-reload across containers via Redis pub/sub. Secrets are never echoed back into the form; an empty save keeps the stored value, an empty save on a non-secret deletes the key.

Setup per channel

Slack

The Slack channel uses your workspace's own bot — same credential mcpgate uses for the Slack connector and magic-link delivery, so a single bot covers all three.

  1. Create a Slack app (From scratch) in api.slack.com/apps.
  2. Under OAuth & Permissions add the bot scopes chat:write, users:read and users:read.email, then install the app to the workspace.
  3. Copy the Bot User OAuth Token (xoxb-…) into the field on the admin page.
  4. Copy the Signing Secret from Basic Information into the same form.

Save, click Test. The alert recipient gets a DM from your bot.

Microsoft Teams

The Teams channel posts an Adaptive Card via your own bot — Entra application plus Azure Bot registration, both in your own tenant. Nothing relays through a third-party service: the message goes Tenant → Bot Connector → Teams.

  1. Register an Entra app (single tenant), create a client secret and a service principal — or run scripts/teams_bot_bootstrap.sh, which does all of this in one go.
  2. Create an Azure Bot resource (free F0 tier) for that app id, set its messaging endpoint to the URL the admin page shows ({BASE_URL}/api/messages on your gateway), and enable the Microsoft Teams channel.
  3. Fill in Bot App ID, Client Secret and Tenant ID on the admin page and save.
  4. Download the Teams app package the page offers and upload it to your Teams org app catalog (or sideload it), then add the app in Teams.
  5. Conversation ID and Service URL fill themselves automatically when the app is installed — the gateway captures them from the installation event.

The Teams bot is two-way and runs at full parity with the Slack bot: it shows a typing indicator while a request is in flight, posts an Adaptive Card whenever Slack would post Block Kit, and routes button clicks through the same channel-agnostic interaction dispatch. The result is the same operator experience on either platform — alert action buttons (Approve / Keep blocked), write-confirmation cards (Execute / Cancel), and the clarification-choice picker all render natively on Teams and travel through one shared handler registry. Channels differ at the edges only (rendering, identity resolution); the decision logic lives once per interaction kind.

Email (SMTP)

The baseline channel. The gateway speaks plain smtplib against any submission endpoint, so any provider works: M365, Google Workspace, SES, Postmark, a self-hosted Postfix relay. The same SMTP config is also used for welcome emails and magic-link delivery.

  1. Use the SMTP submission settings of your mail provider (typically port 587 with STARTTLS, or 25 inside a trusted network).
  2. Username and password are only needed for authenticated relays. Leave them empty for unauthenticated internal relays.
  3. The From address must be a sender your provider accepts (matching SPF, if enforced).

What triggers an alert today

The dispatcher is the delivery layer. What feeds it grows as the gateway wires more events to it. As of this writing:

  • OAuth refresh failures. When a refresh token expires or is revoked on a connected service, the affected user can no longer reach that service through their agent. The alert names the service, the user and the upstream error so the operator can ask the user to re-authorize. This is the silent-failure class: without an alert, the operator finds out when the user complains. With Notifications wired, the operator finds out first.

That is the only event class delivered through this dispatcher today. More will land here as use cases firm up — destructive-action blocked attempts (the queue described in destructive-action governance) is the obvious next candidate; PII redaction warnings and audit anomalies are likely follow-ups. We will wire them in deliberately rather than blasting every event class through the chain.

What about throughput threshold alerts?

The throughput dashboard's threshold-breach Slack alerts (configured per workspace, post to a chosen channel) are a separate, older delivery path. They have not yet migrated to this dispatcher. The user-visible behavior is the same — Slack posts when a per-user/per-tool 1 h or 24 h volume threshold is crossed — but the configuration lives on the Throughput page, not here, and the alerts go to a channel post rather than a DM. Migrating throughput to the unified dispatcher is on the list, not yet done.

Why over your own infrastructure

Every channel in the chain runs through your own bot, your own tenant, your own mail relay. The gateway does not maintain a relay service of its own and never forwards alert content through a third-party endpoint. The Slack DM is from your workspace bot. The Teams Adaptive Card is from your Entra-registered bot in your tenant. The email is from your SMTP submission endpoint with your From address.

The practical consequence: alert content stays inside the same trust boundary as the data the agent is touching. Whatever your data-residency posture is for the connected services, Notifications inherits it. There is no separate "mcpgate sent your operator a message about Drive document X" telemetry leaving your perimeter.

Where each surface lives

WhatWhere in the admin
Channel configuration (Slack / Teams / Email)General → Notifications
Per-channel test sendGeneral → Notifications → Test button on each card
Teams app package downloadGeneral → Notifications → Teams card
Alert recipient (operator email)General → ALERT_RECIPIENT_EMAIL env, or first admin
Throughput threshold alerts (separate path)Throughput → Threshold settings

Related