Channels
Expose an agent as a chat assistant on Slack, Linear, Discord, or the web.
What it is. The glue between an agent and the chat interface you already use.
Use it when your team lives in Slack or Linear, or you want the agent answering on Discord or embedded in your own website.
Works with agents (the actor behind the channel) and connections (the brokered OAuth grant for the platform).
A channel block binds an agent to a chat platform. Once a channel is enabled, the agent answers messages on that platform. Each inbound message starts an agent turn, and the agent's reply is posted back to the conversation.
Channels are how a hosted agent becomes a live assistant rather than only a workflow step. The same agent block can power a workflow node, Cloud in-app chat, and one or more channels at the same time. Channel bindings come from your deployed definition: deploy with git push or swirls deploy and routing updates immediately.
The channel block
The channel block is a top-level declaration. It points at an agent by name and declares which platform delivers messages.
secret vendor_keys {
vars: [OPENROUTER_API_KEY]
}
agent concierge {
label: "Concierge"
secrets: vendor_keys
model: "openai/gpt-4o-mini"
maxSteps: 8
system: @ts {
return "You are a helpful concierge. Prefer tools over guessing."
}
}
channel slack_concierge {
label: "Concierge (Slack)"
platform: slack
agent: concierge
mode: mention
enabled: true
}Field reference
| Field | Type | Required | Description |
|---|---|---|---|
platform | enum | Yes | Where messages are delivered. One of slack, linear, discord, web, mcp. |
agent | identifier | Yes | Name of a top-level agent block that handles inbound messages. A bare identifier, not a quoted string. |
connection | identifier | No | Name of a top-level connection block supplying the OAuth credential. Its provider must match platform. Forbidden on platform: mcp channels. |
connector | identifier | Yes, on platform: mcp | Name of a top-level connector block naming the inbound OAuth application. Valid only on platform: mcp channels. |
mode | enum | No | How inbound events are routed. One of mention, dm, all. Defaults to mention. Forbidden on platform: mcp channels. |
enabled | boolean | No | When false, the binding is inactive. Defaults to enabled. |
label | string | No | Display name shown in the Portal. |
description | string | No | Description shown in the Portal. |
Platforms
platform | Where the agent runs |
|---|---|
slack | Responds in Slack channels and DMs. |
linear | Responds on Linear issues and comments. Requires connection: to post replies. |
discord | Responds in Discord servers and DMs. |
web | Standalone authenticated chatbox at /chat/web/:projectId/:channelName, plus SDK embeds keyed by channel name. |
mcp | Exposes the agent as a remote MCP server that external clients (Claude Desktop, Claude Code, ChatGPT) connect to as a custom connector. See MCP channels. |
For OAuth-backed platforms (slack, linear, discord), set connection: to name a connection block whose provider matches platform, and authorize that connection on the project Connections page in Swirls Cloud. The web surface does not require a connection.
platform: mcp is different from the other four: it requires connector: instead of connection:, forbids mode:, and the agent is reached by an external client's own tool rather than a chat platform Swirls integrates with. See MCP channels for the full DSL, the credential flow, and connecting from Claude Desktop, Claude Code, and ChatGPT.
The web chatbox requires a signed-in Swirls user with an active organization. To put agent chat in front of your own app's users, proxy it through your server: see Embed agent chat.
Modes
mode controls which inbound events reach the agent.
mode | The agent responds to |
|---|---|
mention (default) | Only messages that @-mention the agent. |
dm | Only direct messages. |
all | Both mentions and direct messages. |
For a focused assistant on a busy Slack workspace, mention keeps the agent quiet until called. For a private one-on-one assistant, dm is the common choice.
For platform: web, mode is optional and ignored by the chat service. Web channels are not routed by platform:mode:agent; each web channel gets its own standalone chatbox link keyed by channel name. You can declare multiple web channels for the same agent (for example separate support and sales chatboxes).
Cloud in-app chat lists all deployed agents and does not require a web channel. Use a platform: web channel when you want a dedicated standalone chatbox link or SDK embed.
Routing and uniqueness
Non-web platforms route inbound events by the tuple platform : mode : agent. Two enabled channels cannot share the same tuple, because the runtime would not know which binding wins.
Web channels are different: each enabled web channel must have a unique channel block name. Multiple web channels can point at the same agent.
// Valid: same agent, different platforms.
channel slack_concierge {
platform: slack
agent: concierge
mode: mention
}
channel web_concierge {
label: "Concierge (Web)"
platform: web
agent: concierge
enabled: true
}// Valid: multiple web chatboxes for the same agent (unique channel names).
channel web_support {
platform: web
agent: concierge
}
channel web_sales {
platform: web
agent: concierge
}// Invalid: two enabled web channels with the same block name.
channel web_concierge {
platform: web
agent: concierge
}
channel web_concierge {
platform: web
agent: researcher
}// Valid: same platform and mode, different agents.
channel slack_concierge {
platform: slack
agent: concierge
mode: mention
}
channel slack_researcher {
platform: slack
agent: researcher
mode: mention
}// Invalid: two enabled bindings for slack:mention:concierge.
channel a {
platform: slack
agent: concierge
mode: mention
}
channel b {
platform: slack
agent: concierge
mode: mention
}A disabled channel (enabled: false) does not count toward this check. You can keep an inactive duplicate around without a conflict.
Common mistakes
agent as a quoted string
The agent field takes a bare identifier that names an agent block, not a quoted string.
// Incorrect
channel bad {
platform: web
agent: "concierge"
}// Correct
channel good {
platform: web
agent: concierge
}Binding to an undefined agent
The agent must resolve to an agent block in the workspace, whether in the same file or another file in a multi-file workflow. A name with no matching block is a validation error.
Duplicate enabled routing
For Slack, Linear, and Discord, two enabled channels with the same platform : mode : agent tuple conflict. Change the mode, point one at a different agent, or set enabled: false on one of them.
For web channels, two enabled channels cannot share the same channel block name. Rename one or disable it.
Further reading
- Agents: The
agentblock, roles, tools, sandboxes, and subagent teams. - Embed agent chat: Put a web channel in front of your own app's users.
- Connections: The
connectionblock and OAuth authorization in Swirls Cloud. - Secrets and auth:
secretblocks and provider key setup. - Multi-file workflows: Declaring agents and channels across files.