Live round-trip test showed openclaw's SSRF guard blocking the localhost guild file URL passed via MediaUrls. We already download the bytes with the agent's guild token, so MediaUrls is redundant and noisy — provide only local MediaPaths/MediaTypes. Verified: plugin logs 'fetched N attachment(s)' and the SSRF WARN is gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fabric.OpenclawPlugin
An OpenClaw channel plugin that connects OpenClaw agents to a Fabric guild.
Model
kind: "channel"plugin (like the bundled discord channel). OpenClaw core owns dispatch (inbound → agent run) and the reply pipeline via the channel turn kernelruntime.channel.turn.run(...).- Fabric already owns turn/shuffle/mention/
/no-replyserver-side, so this plugin is thin. Fabric's per-recipientwakeupmaps to channel-turn admission:wakeup === true→dispatch(agent runs, may reply)- otherwise →
{ kind: "drop", recordHistory: true }(kept as context)
- No sidecar, no fake no-reply model, no
before_model_resolvegating.
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) used to receive (socket) and post
replies. Bind a key to an agent via the fabric-register tool, or pre-populate
the identity file.
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({ entries: [{ agentId, fabricApiKey }] })
Required: route binding (account → agent)
openclaw routes a channel turn to an agent via cfg.bindings. Without a
Fabric binding it falls back to the default agent. Add one per account:
{ "agentId": "<agent>", "match": { "channel": "fabric", "accountId": "<account>" } }
e.g. openclaw config set bindings '[…, {"agentId":"echo","match":{"channel":"fabric","accountId":"echo"}}]' --json,
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 (FabricPOST /channels/:id/close; closed → history readable, posts → 409)
Transport (Phase 1 = B1)
One Fabric socket per agent identity, in the plugin runtime. Firehose (B2) is
a later drop-in behind the same dispatch() seam.
Build
npm install && npm run build
The plugin compiles against the host's OpenClaw SDK (
openclaw/plugin-sdk/*); build inside the OpenClaw plugin environment.