Channels - Connect Agents to Messaging Platforms

Trust: ★★★☆☆ (0.90) · 0 validations · developer_reference

Published: 2026-05-10 · Source: crawler_authoritative

Tình huống

Mastra documentation for connecting agents to external messaging platforms (Slack, Discord, Telegram). Developers building agents that respond to messages across multiple chat platforms.

Insight

Channels connect Mastra agents to messaging platforms by receiving platform events, processing them through the agent pipeline, and streaming responses back to conversations. The system uses adapters from the Chat SDK (e.g., @chat-adapter/slack, @chat-adapter/discord) to handle platform-specific protocols. Each platform generates a webhook route at /api/agents/{agentId}/channels/{platform}/webhook. Channel state persists across restarts when configured with storage (e.g., LibSQLStore). Credentials are read from environment variables by default.

Thread context behavior: By default, on first mention in a non-DM thread, Mastra fetches the last 10 messages from the platform and prepends them to the user’s message for context. After responding, the agent subscribes to the thread and maintains full history via Mastra’s memory. Subsequent messages do not re-fetch from the platform. Set threadContext: { maxMessages: 0 } to disable.

Multi-user awareness automatically prefixes messages with sender name and platform ID (e.g., [Alice (@U123ABC)]: message) so agents can distinguish speakers in group conversations.

Tool approval renders tools with requireApproval: true as interactive cards with Approve/Deny buttons. Set cards: false on adapters to render as plain text; when cards are disabled and a tool requires approval, the agent uses autoResumeSuspendedTools to let the LLM decide based on context.

Multimodal content configuration uses inlineMedia (accepts MIME type patterns like ‘image/’, ‘video/’, ‘audio/*’) and inlineLinks (domain matching for URLs like youtube.com, imgur.com). Gemini models can natively process images, video, and audio. YouTube URLs are treated as native video file parts; imgur links are HEAD-checked and inlined as file parts if mimeType matches inlineMedia. Default only sends images inline; unsupported types are described as text summaries to prevent model crashes.

Hành động

  1. Install required packages: @mastra/core and the appropriate chat adapter (e.g., @chat-adapter/slack).

  2. Create an agent with channel adapters:

import { Agent } from '@mastra/core/agent'
import { createSlackAdapter } from '@chat-adapter/slack'
 
export const supportAgent = new Agent({
  id: 'support-agent',
  name: 'Support Agent',
  instructions: 'You are a helpful support assistant.',
  model: 'openai/gpt-5.4',
  channels: {
    adapters: {
      slack: createSlackAdapter(),
    },
  },
})
  1. Register in Mastra instance with storage:
import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'
 
export const mastra = new Mastra({
  agents: { supportAgent },
  storage: new LibSQLStore({
    url: process.env.DATABASE_URL,
  }),
})
  1. Configure platform credentials via environment variables (adapter-specific).

  2. Point platform webhook to /api/agents/{agentId}/channels/{platform}/webhook.

  3. For local development, use a tunnel (ngrok or cloudflared) to expose localhost:

ngrok http 4111
# or
npx cloudflared tunnel --url http://localhost:4111
  1. For multimodal support, add inlineMedia and inlineLinks config to channels object:
channels: {
  adapters: { discord: createDiscordAdapter() },
  inlineMedia: ['image/*', 'video/*', 'audio/*'],
  inlineLinks: [
    { match: 'youtube.com', mimeType: 'video/*' },
    'imgur.com',
  ],
}
  1. For tools requiring approval, add requireApproval: true to createTool config. Set cards: false on adapter to disable interactive cards.

Kết quả

When channels are configured, agents respond to messages in Slack workspaces, Discord servers, and Telegram chats. Thread context is fetched on first mention and persisted via Mastra memory. Tool calls render as interactive approval cards (or plain text if cards disabled). Multi-user messages are prefixed with sender identity for context. Multimodal content (images, video, audio, linked media) is processed by compatible models.

Điều kiện áp dụng

Requires @mastra/[email protected] or higher. Chat adapters from @chat-adapter packages required for each platform. Storage (e.g., LibSQLStore) required for channel state persistence. Multimodal content requires models that support image/video/audio processing (e.g., Gemini).


Nội dung gốc (Original)

Channels

Added in: @mastra/[email protected]

Channels connect your agents to messaging platforms like Slack, Discord, and Telegram. When a user sends a message on a platform, the agent receives it, processes it through the normal agent pipeline, and streams the response back to the conversation.

When to use channels

Use channels when you want your agent to:

  • Respond to messages in Slack workspaces, Discord servers, or Telegram chats
  • Handle both direct messages and mentions in group conversations

Quickstart

Configure channels directly on your agent using adapters from the Chat SDK:

import { Agent } from '@mastra/core/agent'
import { createSlackAdapter } from '@chat-adapter/slack'
 
export const supportAgent = new Agent({
  id: 'support-agent',
  name: 'Support Agent',
  instructions: 'You are a helpful support assistant.',
  model: 'openai/gpt-5.4',
  channels: {
    adapters: {
      slack: createSlackAdapter(),
    },
  },
})

Register the agent in your Mastra instance with storage so channel state persists across restarts:

import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'
import { supportAgent } from './agents/support-agent'
 
export const mastra = new Mastra({
  agents: { supportAgent },
  storage: new LibSQLStore({
    url: process.env.DATABASE_URL,
  }),
})

Each adapter reads credentials from environment variables by default.

Platform setup

Each platform requires credentials and event configuration. See the Chat SDK adapter docs for full setup: Slack, Discord, Telegram.

Mastra generates a webhook route for each platform at:

/api/agents/{agentId}/channels/{platform}/webhook

For example: /api/agents/support-agent/channels/slack/webhook

Point your platform’s webhook or interactions URL to this path.

Local development

Platform webhooks need a public URL to reach your local server. Use a tunnel to expose localhost:4111:

# ngrok
ngrok http 4111
 
# cloudflared
npx cloudflared tunnel --url http://localhost:4111

Copy the generated URL and use it as the base for your webhook paths (e.g. https://abc123.ngrok.io/api/agents/support-agent/channels/slack/webhook).

Thread context

When a user mentions the agent mid-conversation in a channel thread, the agent may not have prior context. By default, Mastra fetches the last 10 messages from the platform on the first mention.

  1. On the first mention in a thread, the agent fetches recent messages from the platform.
  2. These messages are prepended to the user’s message as conversation context.
  3. After responding, the agent subscribes to the thread and has full history via Mastra’s memory.
  4. Subsequent messages in that thread do not re-fetch from the platform.

Set threadContext: { maxMessages: 0 } to disable this behavior. This only applies to non-DM threads.

Tool approval

Tools with requireApproval: true render as interactive cards with Approve and Deny buttons:

import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
 
const deleteFile = createTool({
  id: 'delete-file',
  description: 'Delete a file from the system',
  inputSchema: z.object({
    path: z.string().describe('Path to the file to delete'),
  }),
  requireApproval: true,
  execute: async ({ path }) => {
    await fs.unlink(path)
    return { deleted: path }
  },
})

When the agent calls this tool, users see a card with the tool name, arguments, and Approve/Deny buttons. The tool only executes after approval.

Set cards: false on an adapter to render tool calls as plain text instead of interactive cards. When cards are disabled and a tool requires approval, the agent uses autoResumeSuspendedTools to let the LLM decide based on the conversation context.

Multi-user awareness

In group conversations, Mastra automatically prefixes each message with the sender’s name and platform ID so the agent can distinguish between speakers:

[Alice (@U123ABC)]: Can you help me with this?
[Bob (@U456DEF)]: I have a question too.

Multimodal content

Models like Gemini can natively process images, video, and audio. Combine inlineMedia and inlineLinks to let users share rich content with your agent across platforms:

import { Agent } from '@mastra/core/agent'
import { createDiscordAdapter } from '@chat-adapter/discord'
import { google } from '@ai-sdk/google'
 
export const visionAgent = new Agent({
  name: 'Vision Agent',
  instructions: 'You can see images, watch videos, and listen to audio.',
  model: google('gemini-3.1-flash-image-preview'),
  channels: {
    adapters: {
      discord: createDiscordAdapter(),
    },
    inlineMedia: ['image/*', 'video/*', 'audio/*'],
    inlineLinks: [
      // Gemini treats YouTube URLs as native video file parts
      { match: 'youtube.com', mimeType: 'video/*' },
      { match: 'youtu.be', mimeType: 'video/*' },
      'imgur.com', // HEAD-check imgur links; inline as file part if mimeType matches inlineMedia
    ],
  },
})

With this configuration:

  • A user uploads a screenshot and the agent describes what it sees
  • A user uploads an .mp4 clip and the agent summarizes the video
  • A user pastes a YouTube link and the agent watches and discusses the video
  • A user pastes an imgur link and the agent sees the image directly

By default, only images are sent inline (inlineMedia: ['image/*']). Unsupported types are described as text summaries so the agent knows about the file without crashing models that reject them.

Note: See Channels reference for all inlineMedia patterns and inlineLinks reference for domain matching, HEAD detection, and forced mime types.

Liên kết

Xem thêm: