Channel adapters
A channel adapter connects WednesdayAI to a messaging platform. A channel is a plugin that exposes aChannelPlugin object — a composition of small adapter interfaces, each owning one concern (auth, messaging, outbound delivery, status, setup, onboarding, and more). You implement only the adapters your platform needs; the rest are optional.
ChannelPlugin is not a flat object with login / logout / send / handleEvent
methods. Those names are not part of the contract. The real model is a set of named
adapter slots, each typed by its own interface and re-exported from openclaw/plugin-sdk.The ChannelPlugin shape
ChannelPlugin<ResolvedAccount, Probe, Audit> is generic. ResolvedAccount is the per-account type your config adapter resolves; Probe and Audit are channel-specific status types.
Adapter slots
| Slot | Adapter type | Owns |
|---|---|---|
config (required) | ChannelConfigAdapter | Resolving accounts from config |
meta (required) | ChannelMeta | Display name and channel metadata |
capabilities (required) | ChannelCapabilities | Declared feature support |
auth | ChannelAuthAdapter | Login/logout, credential handling |
setup | ChannelSetupAdapter | First-run setup |
onboarding | ChannelOnboardingAdapter | CLI onboarding wizard steps |
messaging | ChannelMessagingAdapter | Inbound message handling |
outbound | ChannelOutboundAdapter | Delivering outbound replies |
status | ChannelStatusAdapter | Connectivity/health status |
security | ChannelSecurityAdapter | DM policy, allowlist enforcement |
pairing | ChannelPairingAdapter | Pairing flow |
groups | ChannelGroupAdapter | Group/channel handling |
mentions | ChannelMentionAdapter | Mention gating |
threading | ChannelThreadingAdapter | Threads/topics |
streaming | ChannelStreamingAdapter | Streaming/partial replies |
commands | ChannelCommandAdapter | Channel-specific commands |
directory | ChannelDirectoryAdapter | Peer/group directory listing |
resolver | ChannelResolverAdapter | Target resolution |
actions | ChannelMessageActionAdapter | Message actions |
heartbeat | ChannelHeartbeatAdapter | Heartbeat delivery |
gateway | ChannelGatewayAdapter | Gateway-side methods |
agentTools | ChannelAgentToolFactory or ChannelAgentTool[] | Channel-owned agent tools |
openclaw/plugin-sdk. Implement an adapter in its own file (src/auth.ts, src/messaging.ts, etc.) and compose them in the plugin object.
Registering the channel
A channel plugin is registered from the plugin’sregister function via api.registerChannel(...):
Repo layout
Channel plugins live underextensions/ as pnpm workspace packages:
package.json requirements
- Plugin id, directory name, and npm package name must match exactly.
- Pin
openclawto exactly2026.3.2(the fork base) in bothpeerDependenciesanddevDependencies. Do not use a range like>=2026.3.2— plugins built against a newer openclaw may import APIs that do not exist in this fork. openclawgoes indevDependencies/peerDependencies, neverdependencies.- No
workspace:*independencies.
The
package.json "openclaw" key carries the id used for workspace discovery. A separate
openclaw.plugin.json manifest (with id and configSchema) is still required at the
plugin root for config validation. See the manifest reference.Account model
TheResolvedAccount type parameter is the per-account record your config adapter resolves from configuration. For channels that store credentials, keep them under ~/.openclaw/credentials/<channel>/ and use the SDK credential and config helpers rather than writing files directly.
Testing a channel adapter
Test each adapter in isolation. Mock the platform client; do not make live API calls in unit tests.Docs and PR checklist for a new channel
When adding a channel, update every surface that lists channels (onboarding/overview docs, control UI, mobile/macOS app where applicable) and add matching status and configuration forms.-
ChannelPlugincomposes the adapters the platform needs (config,meta,capabilitiesat minimum) - Registered via
api.registerChannel(...) - Package name
@wednesdayai/<channel>; id matches directory name -
openclawpinned to exactly2026.3.2; noworkspace:*independencies -
openclaw.plugin.jsonpresent withid+configSchema - Unit tests pass:
pnpm test:fast - Channel doc added under
docs/channels/and indexed -
CHANGELOG.mdupdated; dev log atdocs/logs/YYYY-MM-DD-<name>-channel.md
What’s next
- Plugin SDK reference — full exported adapter types
- Plugin manifest reference
- Write your first plugin