Connect OpenClaw to fmsg, the federated messaging protocol. The plugin receives messages over WebSocket, catches up after reconnects, preserves fmsg message trees as native OpenClaw sessions, and carries attachments in both directions.
Highlights
Native threaded sessions: roots start sessions, linear replies continue them, and sibling branches fork with direct ancestry as context.
The published package contains TypeScript source for linked development and prebuilt JavaScript for managed installs. It has no install-time build hook and is compatible with OpenClaw/npm dependency installation using --ignore-scripts.
Set the API key in the gateway environment, then add channels.fmsg to openclaw.json:
The first discovered child continues its parent's session; later discovered siblings fork. Catch-up is processed oldest-first, making this chronological during normal delivery. Fork context contains only the bounded root-to-parent pid chain—never sibling history—and is explicitly labelled as untrusted content.
Outbound replies:
Reply to the direct parent message.
Reply-all to from, to, every add_to_from, and every add_to.to on that parent, excluding the JWT sender.
If one OpenClaw turn emits several messages, the first replies to the inbound and each subsequent message replies to the preceding outbound message.
A new inbound resets that output chain.
Agent-initiated continuation selects only the latest strict one-to-one thread with the address. It never auto-selects a multi-party thread.
Agent tool
The plugin registers fmsg_send:
{"to":"@alice@example.net","text":"Status update","fmsg_new_thread":false,"topic":"Optional topic for a new root"}
By default it continues the latest strict one-to-one thread. Set fmsg_new_thread to force a new root.
Safety behavior
no_reply inbound messages are recorded and marked read without starting an automatic agent turn.
important is exposed as FmsgImportant in OpenClaw's inbound context. no_reply is retained in the fmsg routing record and audit log, then hard-suppressed before model dispatch.
The loop circuit breaker counts one successful automatic OpenClaw turn, not individual chunks. Inbound messages do not reset it. On the final allowed turn, outbound messages carry no_reply; further turns are suppressed until timestamps leave the sliding window.
Operators can tune both circuit-breaker values or set maxAgentTurnsPerThread: 0 to rely entirely on agent discretion.
Inbound bodies, ancestry, topics, addresses, and filenames are untrusted.
fmsgk_... and compact JWT-shaped strings are redacted immediately before any outbound text is drafted and from plugin error logs.
Runtime routing state is stored under OpenClaw's state directory in fmsg/<account>.json, with bounded message and deduplication history.
Development
npm install --ignore-scripts
npm run typecheck
npm test
npm run build
npm pack --dry-run
Releasing
Stable releases are published to npm by .github/workflows/publish.yml when a GitHub Release is published. The release tag must exactly match the version in package.json, prefixed with v (for example, package version 0.1.0 uses tag v0.1.0). Build and commit dist/ with every version change before creating the release.
The npm package must configure a trusted GitHub Actions publisher for repository markmnl/openclaw-fmsg, workflow publish.yml, with npm publish allowed. The workflow uses short-lived OIDC credentials and does not require an npm token secret.
The unit suite runs an in-memory HTTP and WebSocket implementation of the fmsg Web API. It covers JWT exchange/refresh, drafts and attachments, WebSocket plus inbox catch-up, access control, branch mapping, native session routing, reply-all, output chaining, proactive one-to-one continuation, flags, secret redaction, persistence, and the circuit breaker.
Live OpenClaw gateway acceptance
The opt-in gateway test launches the installed OpenClaw executable with a deterministic local model and the in-memory fmsg Web API. It verifies the ready connection, root and branch session rows in OpenClaw's SQLite session store, first-child continuation, and reply-all:
npm run test:gateway
Set OPENCLAW_E2E_ROOT to an OpenClaw package directory when it is not available at node_modules/openclaw. Set OPENCLAW_E2E_PLUGIN_ROOT to exercise a particular installed copy of this package instead of the working tree.
fmsg-docker e2e
The opt-in e2e test expects two provisioned identities in an already-running fmsg-docker environment:
The addresses are derived from the JWTs. The test sends a root with an attachment, observes WebSocket delivery, downloads the attachment, replies through the second deployment, and verifies the reply's pid.
OpenClaw channel plugin for the federated messaging protocol fmsg
The npm package @markmnl/openclaw-fmsg receives a total of 18 weekly downloads. As such, @markmnl/openclaw-fmsg popularity was classified as not popular.
We found that @markmnl/openclaw-fmsg demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.It has 1 open source maintainer collaborating on the project.
GPT-6 Astra tried to plant malicious code in simulated open source projects using fake GitHub accounts and deceptive PRs during an assigned CTF challenge.