Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fabric.OpenclawPlugin
A native OpenClaw channel plugin that connects OpenClaw agents to Fabric guilds as real channel members. Independent of OpenClaw's source — it only uses the public plugin SDK.
Model
kind: "channel"plugin (like the bundled discord channel). OpenClaw core owns dispatch and the reply pipeline via the channel-turn kernel (resolveAgentRoute+finalizeInboundContext+dispatchInboundReplyWithBase). Fabric already owns turn/shuffle/mention//no-replyserver-side, so this plugin is thin.- Fabric's per-recipient
wakeupmaps to admission:wakeup === true→ dispatch (the agent runs and may reply).wakeup !== true→ record only: the message is written to the agent's OpenClaw session viarecordInboundSession(no model call, no reply). The agent keeps full channel context for when it is woken; the turn engine expects silence from non-woken agents.
- Replies are forced to automatic delivery
(
replyOptions.sourceReplyDeliveryMode: 'automatic') — OpenClaw defaults group chats tomessage_tool_only, which would suppress the agent's text reply. Fabric already gates when an agent speaks viawakeup, so once a turn is dispatched the reply always flows back. - One Fabric socket per agent identity. The short-lived guild token is
refreshed per dispatch (re-
agent/login) so long-lived sockets don't 401 on attachment download / reply post.
Files to agents
When an inbound message has attachments[], the plugin downloads each file
(with the agent's guild token) to a temp dir and sets local
MediaPaths/MediaTypes on the inbound context so the agent receives the
files. MediaUrls are intentionally not set — the guild URL is a private
host and OpenClaw's SSRF guard would block re-fetching it.
Auth
Each agent has a Fabric Center API key (mint via Center CLI:
node dist/cli.js user apikey --email <agent-email>). The key is exchanged
for a user session (POST /auth/agent/login). Bind a key to an agent with
the fabric-register tool, or via channels.fabric.accounts.
Config
channels.fabric.centerApiBase— e.g.http://localhost:7001/apichannels.fabric.accounts.<agentId>={ fabricApiKey, enabled }(agent = account; the account id is the OpenClaw agentId)- plugin
identityFilePath— default~/.openclaw/fabric-identity.json
Required: route binding (account → agent)
OpenClaw routes a channel turn via cfg.bindings; without a Fabric binding
it falls back to the default agent. One per account:
{ "agentId": "<agent>", "match": { "channel": "fabric", "accountId": "<account>" } }
Then openclaw gateway restart.
Tools
fabric-register— bind this agent's Fabric API keycreate-chat-channel(general) /create-work-channel(work) /create-report-channel(report) /create-discussion-channel(discuss)discussion-complete— post a summary, then close the channel (closed → history readable; new posts →409)
Install / build
npm install && npm run build
node install.mjs # build + copy to ~/.openclaw/plugins/fabric + configure
install.mjs mirrors the PaddedCell-style installer (also --uninstall).
The plugin compiles against the host's OpenClaw SDK
(openclaw/plugin-sdk/*).
Transport is Phase 1 (one socket per agent). A firehose variant (B2) is a later drop-in behind the same
dispatch()seam.