# Channel docs

Each channel is an entry point bound to a **default agent**. Inbound messages are
normalized and run through the agent (with its MCP tools); the reply goes back out
the same channel. Channels live in a **workspace**, so the same identity can exist
in different workspaces without clashing.

| Channel                   | In                 | Out                   | Auth                        |
| ------------------------- | ------------------ | --------------------- | --------------------------- |
| [HTTP](./http.md)         | synchronous `POST` | reply in the response | API secret (optional)       |
| [Email](./email.md)       | provider webhook   | per-channel SMTP      | inbound secret + SMTP creds |
| [WhatsApp](./whatsapp.md) | Baileys socket     | Baileys socket        | QR / pairing code           |
| [Slack](./slack.md)       | Events API webhook | `chat.postMessage`    | signing secret + bot token  |
| [Telegram](./telegram.md) | Bot API webhook    | `sendMessage`         | secret token + bot token    |

## Things common to every channel

- **Identity** — a human-readable label. HTTP uses it in the webhook URL; email uses the address; WhatsApp/Slack use it as a label. Unique within a workspace + kind.
- **Webhook URL** — for HTTP/Email/Slack the exact URL is shown on the channel page under **Endpoint** (copy button). You never build it by hand.
- **Credentials** — secrets live here and support `{{ variables }}`; store sensitive values as **secure variables** so they're masked.

### Routing — how a message reaches an agent

For each message the agent is resolved in this order:

1. **Command** — a configured command word (e.g. `/mister`) routes to that agent. On WhatsApp the slash is optional (a bare keyword still needs a mention in groups); on email/HTTP/Slack the slash is required, so plain prose doesn't trigger commands.
2. **Per-group agent** (WhatsApp) or **sticky agent** (DMs/email/HTTP/Slack) — after using a command, plain follow-ups keep going to that same agent until the user sends `/exit` or the thread is idle for 30 minutes. Groups/channels never stick, so one member can't hijack the thread.
3. **Default agent** — the channel's **concierge**, used otherwise.

**Concierge** — the default agent. It receives a live menu of the channel's commands, each enriched with the target agent's MCP tool capabilities (discovered once, cached ~10 min), so it can greet users and suggest concrete example messages. It only lists commands actually configured on the channel.

**Built-in commands**

- `/help` — a static list of the channel's commands (mention-gated in groups).
- `/exit` — drop a DM back to the concierge (clears the sticky agent).

### Guards

Checked before the agent runs: **sender allowlist**, **per-sender rate limit**, and a **max message length**.
