← mundane.codes
Platform

Internal Comms Platform

Self-hosted team chat — rooms, direct messages, search, and bot integrations, running as one deployment your own team controls.

2 engineers 6 months Support August 2026 – Present
Language
Rails
Database
SQLite
Caching
Redis
Hosting
Self-Hosted (Kamal)
3 room types — open, closed, direct — not one generic channel
1 self-contained deployment — web, jobs, cache, files, SSL
0 message history leaving the business's own infrastructure

The Challenge

A growing team's conversations were scattered across group chats never meant for work, email threads nobody could search, and a dozen apps that each held a piece of the picture. Nothing was in one place, search barely worked where it existed at all, and the business had no real control over where its own internal conversations actually lived.

Our Approach

The starting point wasn't "build a chat app" — it was deciding what kind of room actually matches how teams talk. A single generic "channel" concept forces every conversation into the same shape. Three distinct room types do more real work: open rooms anyone can join, closed rooms by invitation, and direct messages for one-to-one or small group conversations — each with its own access rules, not one permission system stretched to cover every case.

Notification control needed to be per room, per person, not a single global on/off switch. Someone can follow every message in a room that matters to them and only mentions in one that doesn't, without missing something important or drowning in noise from everything else.

Search had to actually work, not be a feature that technically exists. A message someone half-remembers from three months ago needs to be findable in seconds, not buried under a search box that only matches exact phrases.

Running it also had to be simple, not an operations project of its own. The whole thing — the chat application, background job processing, caching, file serving, and SSL — runs as one self-contained deployment, not a sprawl of separate services someone has to keep wired together.

Integrations happen through a real API with bot and webhook support, so the platform can be told about things happening elsewhere — a deploy finishing, a support ticket coming in — without turning the product itself into an integration platform.

/ What We Built

Built For The Details That Matter

Rooms, Not One Channel Type

Open rooms anyone can join, closed rooms by invitation, and direct messages — each with access rules that actually fit how the conversation works.

File Attachments With Previews

Share a file in the room and see it inline, not just a filename link someone has to download to understand.

Search That Actually Finds Things

A message from months ago is findable in seconds — search isn't a checkbox feature here.

Notifications, Per Room

Follow everything in a room that matters, just mentions in one that doesn't — notification level is set per room, per person, not globally.

Bot & Webhook API

A real API lets the platform hear about what's happening elsewhere — a deploy, a ticket, an alert — without becoming an integration platform itself.

/ Integrations

What It Connects To

Web Push

Native browser notifications, no separate mobile app required

Bots & Webhooks

External systems post into rooms through a documented API

The Impact

The business owns its own conversation history outright — nothing routes through a third party's infrastructure, and nothing disappears when a free-tier message limit resets.

Because it runs as one self-contained deployment, there's no sprawl of separate services to keep patched and running — the people who run it day to day aren't suddenly operating a distributed system to get team chat.

Search and per-room notification control turned "I know someone said this somewhere" from a recurring frustration into a non-issue.

/ Questions

Worth Asking Before You Call

Does our message history stay on infrastructure we control?

Yes — it's a self-hosted, self-contained deployment. Nothing routes through a third party, and nothing is subject to someone else's retention or pricing changes.

Can this replace Slack or WhatsApp groups entirely, or does it sit alongside them?

It's built to be the primary place work conversations happen — rooms, search, and notification control are built for that, not as a lightweight add-on.

How do external tools (CI, support tickets, alerts) post into it?

Through a documented bot and webhook API — the same way any integration reaches a chat platform, without needing custom work per tool.