Channels
A channel connects a platform to your agent. For conversations, it:
- Converts incoming messages into agent input.
- Maps each platform conversation to an eve session.
- Decides how, where, and whether to deliver replies.
A channel can also receive events and pass them to another channel without starting a conversation of its own.
eve ships a base HTTP channel and first-class platform channels, and you can author your own. Browse them in the Integrations gallery with the Channels filter.
Every channel runs the same agent, so tools and instructions need no channel-specific logic.
Choose where the conversation lives
The agent doesn't have to reply where an event arrived. A webhook, for example, can start a conversation in a team chat without replying to the webhook's source.
Use a cross-channel hand-off when the conversation belongs elsewhere. The destination channel handles the session, replies, and follow-up messages. To post a notification without running the agent, use the platform's API instead.
Audience
When a channel creates a session, it sets the session's audience: public, private, or unknown. The audience controls what traces capture, not who may call the channel. Each channel decides from what it knows about the conversation, and falls back to unknown.
Route auth decides who may call the channel and identifies the caller. See Auth & route protection for caller types and authorization. See the default eve HTTP channel for its mapping, or custom channels to classify your own.
Sign-ins
When a tool needs a connection the person hasn't authorized, the built-in channels show a sign-in. Its link or code is a credential: whoever completes it connects their account. So it appears only where the person signing in reads it alone:
- In a conversation that's theirs (a direct message, a private chat, an SMS thread), eve posts the sign-in there.
- In a group, eve posts a status without the link and sends the sign-in privately where the platform can. Slack and Chat SDK adapters use ephemeral messages; Telegram sends it once the requester presses Authorize.
- Teams channels and Discord servers and group DMs can't send privately. There, the status asks the person to continue in a direct message with the agent.
- On GitHub, where every comment is public, the status says the person who asked must sign in.
- When the sign-in ends, eve edits the status where it can, or posts how it ended. Once the person connects, it shows the turn resuming.
Linear uses its native sign-in prompt. A sign-in that an approval's responder needs appears with that approval's prompt.
Overlapping messages
Channels default to turnPolicy: "steer", which adds a new message to the running turn. The turn ID stays the same.
- Before assistant answer output or local tool execution begins, the message interrupts pending model generation and the turn continues with the correction.
- Executing tools finish and keep their results before steering reaches the next model call.
- After answer output starts, steering waits until the current model step finishes.
Reasoning and search progress don't count as answer output. Interrupted provider-managed search may run again; completed local tools are preserved.
Set turnPolicy: "queue" on any built-in or custom channel when each turn must finish before the next message starts:
Adjacent queued messages combine into one turn only when their full auth contexts match, including identity, issuer, authenticator, and authorization attributes. Their attachments and context stay in payload order. A different auth context ends the batch, and eve doesn't regroup messages across intervening senders. Anonymous messages stay separate. Turns still share the session's conversation history.
from(address).send(...), fixed Session.send(...), cross-channel sends, and Chat SDK bridge sends accept a per-send turnPolicy override. A send with only answers answers its pending request without joining the turn. Use cancel() to stop without a replacement.
Events rejected before send(...), such as invalid signatures or filtered mentions, never reach the active turn. A message already sent to the session can interrupt the model before the channel's deliver hook runs. If that hook ignores the message, eve resumes the original request with its original auth, source, and channel state.
Each channel has its own provider terms, data flow, auth model, and user-consent expectations. Before you send non-public, sensitive, regulated, or production data through a channel, confirm that it fits your use case. Check the provider, your configured scopes, signature checks, route auth, and how replies are posted.
Where channels live
Channel files live under agent/channels/ in the root agent or come from an extension mounted there. The file stem is the channel id: agent/channels/intake.ts is addressed as intake. An extension mount prefixes its channel IDs but not their route paths. Local subagents don't declare channels.
Install a channel from the registry with eve add channel/<name>, such as eve add channel/slack or eve add channel/web, or author the file by hand.
The eve HTTP channel (default)
The eve channel is the default HTTP session API that the terminal UI, useEveAgent, and curl call. It serves the health, agent info, callback, task input, and session routes, which you replace together. eve supplies it when no agent/channels/eve.ts exists. Author that file to replace it, most often to change route auth. See HTTP channel for routes, auth, replacement, and disablement.
Custom channels
Build a channel with defineChannel from eve/channels when you need your own HTTP or WebSocket endpoint. Its routes can start conversations on that channel or hand work to another one. See Custom channels for examples and the authoring API.
Relationship to the Chat SDK
eve uses the Chat SDK's card-builder components (Cards, Buttons, Actions, etc.) to compose rich Slack messages. Cards you build with the Slack channel are converted to Slack Block Kit at post time.
eve's first-class channels handle webhooks, verification, event parsing, and threads themselves. The optional Chat SDK channel instead accepts a Chat SDK adapter and exposes its Chat and Thread primitives. Use slackChannel for eve's Slack integration, defineChannel(...) for an eve-native custom channel, or chatSdkChannel when you want a Chat SDK adapter and runtime.
Which channel?
| You want… | Use |
|---|---|
| A web app / browser chat UI | eve channel + useEveAgent |
Local tooling, SDK clients, curl | eve HTTP channel (default) |
| MCP clients handing off long-running work | MCP |
| Slack mentions, DMs, buttons | Slack |
| iMessage and SMS | Linq |
| iMessage | Photon |
| Discord messages, DMs, slash commands | Discord |
| Microsoft Teams messages + Adaptive Cards | Teams |
| Telegram bot messages | Telegram |
| SMS or speech-transcribed phone calls | Twilio |
| GitHub @mentions, PR review with checkout | GitHub |
| Linear issue delegation and Agent Sessions | Linear |
| Another Chat SDK-supported service | Chat SDK adapters |
| Anything else (internal webhook, WebSocket) | Custom channel (defineChannel, above) |
Disclaimer
As the deployer, you are responsible for ensuring your agent complies with applicable laws.
Where an eve agent communicates with people, the law may require you to disclose that they are interacting with an automated AI system. eve doesn't add this disclosure; configure it in your instructions or channel responses. See Responsible use for the full deployer responsibilities.
What to read next
- eve HTTP channel: the default session API behind the TUI, SDK clients, and browser UIs
- Slack: the most common platform channel, end to end
- MCP: let MCP clients hand long-running work to the agent
- Linq, Photon, Discord, Teams, Telegram, Twilio, GitHub, and Linear: the other first-class platform channels
- Chat SDK adapters: reach services eve has no first-class channel for
- Custom channels: build a channel for any surface with
defineChannel - Durable cross-channel notifications: post to another platform without starting an agent turn
- Frontend: browser chat on the eve channel with
useEveAgent - Integrations: browse every built-in channel in one gallery using the Channels filter