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
Each adapter type is imported from
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.
- Bundled extensions carry no
openclawpeer or dev dependency (ADR 0005) — fork-base compatibility is expressed by our SemVer version and theforkBasemarker indist/build-info.json, not anopenclawrange. - Third-party installable plugins put
openclawindevDependenciestargeting our published SemVer, with"openclaw": "*"inpeerDependencies— see the Plugin SDK installation pattern. Never putopenclawindependencies; the gateway provides the SDK at runtime. - 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 - No
openclawpeer pin (bundled extensions carry none — ADR 0005); 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