Skip to content

Channels

A channel tentacle holds one platform connection open, translates its events into messages, and draws a run back onto the platform in whatever that platform can show. Keyed by instance, so two Lark apps are two keys, two separate sets of threads, and two bots.

Enable a channel

Follow the app setup for Slack, Lark / Feishu or Discord, connect the NapCat bridge, or build Trunkline for browser access. Add its block to tentacles.yaml, supply the required credentials, and name at least one enabled agent in agents. Set enabled: true if the generator left it disabled. Check the configuration, restart Octomate and send a message to verify the connection. See the shared enablement steps.

tentacles:
  slack:
    type: slack
    app_id: A0123456789
    agents: [inkling, claude]
    mention_only: true
    stream:
      flush_interval: 0.2
    recap:
      messages: 16
      characters: 1000

Supply secrets in YAML or environment variables named OCTOMATE__TENTACLES__<KEY>__<FIELD>. A .env file is optional; remove matching YAML placeholders if using it, because YAML takes precedence.

Shared settings

Key Default Meaning
agents required Agent ids, entry order. The first answers new conversations; every one is a route.
enabled true A disabled channel keeps its block and its routes are still validated.
mention_only true On a surface others can read, the bot answers only when addressed.
stream per platform Live rendering: enabled, flush_interval, min_chars, max_chars, fold_threshold.
recap 16 messages, 1000 chars each How much of a chat room a kick is shown, since a kick there starts with an empty context.
mcp false Whether this channel serves its own MCP tools to the agents on it. Slack only.

Streaming defaults differ: Slack, Lark and Trunkline stream by default; Discord coalesces edits and is off until you set stream.enabled: true. NapCat sends completed messages and has no streaming transport. Within a stream: block you set only what you change and keep the platform's other defaults.

Being addressed

The mention gate looks at whether the surface is shared, not at its type. A direct message, a thread in a Slack DM, or a Lark one-to-one chat is never gated. On a shared surface the bot answers when:

  • the message @-mentions it,
  • the message replies to one of its messages, which Discord reports; Slack, Lark and NapCat do not supply the reply-author information used by this gate, or
  • the message lands in a thread an agent already owns, because a handoff pinned it.

A group's main channel is never pinned to an owner, so there a mention stays the rule even after a long exchange. Set mention_only: false to answer everything on that channel.

A message sent to a thread or chat room while a turn is running there waits: it is in the history, and the turn the next message starts answers it too.

Identity

The first time someone speaks, the channel records a visitor profile: a platform identity owned by nobody. The agent still answers. What a visitor lacks is everything that follows the person across channels: history search, moves into their direct messages elsewhere, their MCP connectors. Linking the profile to an account fixes that; see Accounts and tokens.

What each channel renders

Slack Lark Discord NapCat Trunkline
Streaming text Native stream Streaming card Message edits No; completed messages Every event, live
Thinking and tool cards Folding plan Cards that fold No No Yes
MCP app artifacts Card with viewer button Card with viewer button Card with viewer button Text overview and link Inline cards and standalone pages
Todo checklist Plan tasks Card No Text with the final reply Yes
Approval cards Buttons, paged One card each Buttons, one each Text only Yes
Question cards One message One card Buttons and a modal Text only Yes
Sub-threads Yes Yes Public threads from a text channel No No; top-level threads only
Direct messages Yes Yes Yes Yes No
Profile linking From chat, or Slack OAuth From chat, or Lark OAuth From chat, or Discord OAuth From chat Not needed

Subagents get a timeline of their own on Slack, Lark and Discord. Every channel posts a one-line error with a trace id when a turn fails, and ignores a message the platform delivers twice.

A channel draws each thread's runs in order, apart from the run itself. A slow platform call holds up only its own thread, and a message the platform refuses costs that message, not the turn: the reply is in the ledger regardless. Cards answered on another surface stay as they are on IM channels for now; Trunkline marks them answered.

The threads page explains what each platform's chats and threads become inside Octomate, and where a reply lands.

Artifact overviews

Slack, Lark, Discord and NapCat can post a saved artifact's title, provider and viewer link in the conversation where it was created. Separate invocations get separate messages, including during a run. The overview contains no app HTML or tool arguments and does not rerun the tool.

Set the existing Trunkline host in octomate.yaml to enable these overviews:

artifacts:
  viewer_origin: https://octomate-app.example.com

This uses your existing viewer deployment. The artifact settings also let you choose its path. Without a viewer origin, IM channels keep their normal replies and do not post artifact overviews. Trunkline's inline cards still work independently of this setting.

Opening a link requires access to that host and signing in as the artifact's owner. Posting a link in a group does not grant its members access. The interactive app still needs the separate sandbox setup; the overview itself needs no connection to the app provider.