Skip to main content

ChannelProvider

ChannelProvider is the interface that platform integrations implement to connect agents to a messaging platform. A provider owns the full integration lifecycle. This includes app provisioning with OAuth, webhook routing with event handling, adapter creation and agent wiring, and credential management.

Register providers on the Mastra constructor under channels, keyed by an id you choose. Each provider's routes are merged into the server's API routes automatically, and initialize() runs during Mastra startup.

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'
import { SlackProvider } from '@mastra/slack'

export const mastra = new Mastra({
channels: {
slack: new SlackProvider({
refreshToken: process.env.SLACK_REFRESH_TOKEN!,
baseUrl: process.env.MASTRA_BASE_URL,
}),
},
})

The provider's baseUrl is the public URL the platform sends webhooks and events to. In production this is your deployed Mastra server URL. For local development, the platform can't reach http://localhost:4111, so run a tunnel (such as cloudflared or ngrok) and point baseUrl at the tunnel URL (for example https://abc123.trycloudflare.com) so events reach your local dev process.

Mastra includes SlackProvider and TelegramProvider implementations. Build a custom provider by implementing this interface.

Dynamic resolution
Direct link to Dynamic resolution

Instead of a static record, channels also accepts a resolver: an async function returning the current provider map, with a synchronous getRoutes() method. Mastra mounts the resolver's routes at construction and resolves providers at runtime, so connections added after boot become usable without a redeploy. The channels() helper from @mastra/connect returns a resolver backed by the Mastra platform.

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'
import { channels } from '@mastra/connect'

export const mastra = new Mastra({
channels: await channels({ projectId: process.env.MASTRA_PROJECT_ID! }),
})

With a resolver configured, call resolveChannels() to get the current provider map. It also works with a static record, where it returns the record directly.

const providers = await mastra.resolveChannels()

Properties
Direct link to Properties

id:

string
Unique identifier for this channel type, for example 'slack' or 'discord'. Used as the key when routing events and looking the provider up from Mastra.

Methods
Direct link to Methods

getRoutes:

() => ApiRoute[]
Returns the API routes for this channel (OAuth, webhooks, events). These are merged into the server's apiRoutes automatically.

initialize?:

() => Promise<void>
Called during Mastra initialization after all agents are registered. Use it for async setup such as restoring active installations. Does not provision new apps.

configure?:

(credentials: Record<string, unknown> | null) => void | Promise<void>
Provides or clears platform credentials at runtime. Pass null to clear credentials and delete stored tokens.

getInfo?:

() => ChannelPlatformInfo
Returns discovery metadata for the editor UI: platform name, configuration status, and the connect options schema.

connect?:

(agentId: string, options?: Record<string, unknown>) => Promise<ChannelConnectResult>
Connects an agent to the platform. Returns a discriminated result describing the authorization flow required to finish the connection.

disconnect?:

(agentId: string) => Promise<void>
Disconnects an agent from the platform. Deletes the platform app and cleans up stored state.

listInstallations?:

() => Promise<ChannelInstallationInfo[]>
Lists active installations for this platform. Returns public info only, never secrets.

Accessing a provider
Direct link to Accessing a provider

Access a registered provider through the channels getter, keyed by the id you registered it under. The getter is typed from the constructor config, so mastra.channels.slack is the concrete provider with its full method surface.

await mastra.channels.slack.configure({ refreshToken })

When the key is only known at runtime, look the provider up by string id instead. getChannelProvider takes the concrete type as a generic, and getChannelProviders returns every registered provider keyed by id. With a resolver, both return the latest resolved snapshot. Use resolveChannels() when you need providers that reflect the current platform state.

import type { SlackProvider } from '@mastra/slack'

const slack = mastra.getChannelProvider<SlackProvider>('slack')
const all = mastra.getChannelProviders()