ISS
← Field Notes
Distributed Systems screenshot
June 8, 2026 · Distributed Systems · 2 min read

Bridging Discord and Stoat When the Permission Models Do Not Match

Stoatcord is a self-hosted bot that keeps Discord and Stoat communities in sync, compiling 24 Discord permissions into 30 Revolt bits and gating migration on live consent.

Stoatcord is a self-hosted bridge that keeps Discord and Stoat, the platform formerly known as Revolt, in sync. It relays messages in both directions, migrates entire servers, and delivers push notifications to any device. It is aimed at community operators who live on Discord but want a foothold on Stoat without abandoning either side.

The messy part is the mapping

The features that sound simple are the ones that hide the real work. Bidirectional relay pairs Discord webhooks with Stoat masquerade so avatars and usernames stay intact on both sides, and built-in echo prevention keeps a bridged message from bouncing back and duplicating itself. Edits, reactions, and replies survive the crossing. Reaction forwarding and typing indicators sync both ways with debounce, and channel name and topic changes propagate automatically.

Server migration is where the two platforms genuinely disagree. Discord and Stoat do not share a permission model, so the migration wizard compiles 24 Discord permissions into 30 Revolt bits, cloning channels, roles, emoji, and permissions in a single pass. It supports a dry-run mode so you can preview every change before committing anything, which is exactly the safety valve you want when you are about to rewrite a community's structure.

The design decision I appreciate most is how migration handles consent. Cloning a server into someone else's space should not be something one side can do unilaterally, so the bot posts the migration request into the target server and then blocks on a live admin reply before proceeding. Consent is a real gate in the control flow, not a checkbox, and the whole thing waits for a human on the other end to say yes.

Everything is drivable two ways. There is a RESTful HTTP API that acts as a control plane for bridge management, diagnostics, health checks, and push-device registration, so you can wire it into your own monitoring stack. Push notifications go out over FCM, WebPush, and UnifiedPush. Archive migration exports full message history from Discord and imports it into Stoat with timestamps, attachments, reply chains, and embeds preserved, and you can pause, resume, and monitor the job via slash commands or the API.

If you run a community straddling both platforms, the code and setup live at the live site.

Have something that needs building, or stabilizing?

These notes are the work log. The paid work runs through Moonshine Labs, my product and engineering studio. Tell us what you're building, or grab a call.

Work with us →
the studio: moonshinelabs.io