SWIRLS_
Agents

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

FieldTypeRequiredDescription
platformenumYesWhere messages are delivered. One of slack, linear, discord, web, mcp.
agentidentifierYesName of a top-level agent block that handles inbound messages. A bare identifier, not a quoted string.
connectionidentifierNoName of a top-level connection block supplying the OAuth credential. Its provider must match platform. Forbidden on platform: mcp channels.
connectoridentifierYes, on platform: mcpName of a top-level connector block naming the inbound OAuth application. Valid only on platform: mcp channels.
modeenumNoHow inbound events are routed. One of mention, dm, all. Defaults to mention. Forbidden on platform: mcp channels.
enabledbooleanNoWhen false, the binding is inactive. Defaults to enabled.
labelstringNoDisplay name shown in the Portal.
descriptionstringNoDescription shown in the Portal.

Platforms

platformWhere the agent runs
slackResponds in Slack channels and DMs.
linearResponds on Linear issues and comments. Requires connection: to post replies.
discordResponds in Discord servers and DMs.
webStandalone authenticated chatbox at /chat/web/:projectId/:channelName, plus SDK embeds keyed by channel name.
mcpExposes 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.

modeThe agent responds to
mention (default)Only messages that @-mention the agent.
dmOnly direct messages.
allBoth 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

On this page