← Lee Ying-Chieh / Luke Case Study
Personal project · end-to-end solo delivery · AI-assisted

MsgMesh — a multi-tenant event bus

Keep Kafka behind a gateway and expose only HTTP / SSE / WebSocket / MCP, so apps and AI agents can subscribe to an event stream "in one line" — auth, rate-limiting and multi-tenant isolation all handled by the platform, and clients never touch the broker directly.

● Live · public beta Solo build~5 weeksGo monorepok8s-readyMCP-native
29
MCP tools · AI-native
424
commits · solo
86
test files
contract
docs-as-tests · no drift

01 The problem

Kafka is powerful, but handing it directly to every app or tenant is a burden: each client has to handle auth, metering, tenant isolation, rate-limiting and schema compatibility — and reach the broker. Heavy, risky, hard to maintain. At the same time, a new generation of AI agents needs a way to "subscribe to an event stream in one line," not to wire up their own Kafka consumer.

MsgMesh's bet: put a gateway in front of Kafka and expose only HTTP / SSE / WebSocket / MCP; every cross-cutting concern (auth, multi-tenancy, rate-limiting, reliable delivery, schema contracts) is handled by the platform, and clients only "publish / consume."

02 Key decisions & trade-offs

This is the part I think best represents engineering judgment — not just "what I built," but "why I chose it and what I gave up."

Clients never connect to Kafka — everything goes through the gateway
WhyExposing Kafka means doing auth/metering/isolation/rate-limiting yourself — heavy and dangerous. With a gateway, the outside world only sees HTTP/SSE/WS/MCP and the platform handles cross-cutting concerns once. Trade-off: one extra hop of latency and a gateway that must stay highly available, in exchange for a minimal, secure public surface. Cheaper to run than a per-tenant cluster.
at-least-once + idempotency, not exactly-once
WhyWebhook retries inevitably resend, and exactly-once in a distributed system is very costly. I chose at-least-once and made consumers idempotent: webhooks carry an HMAC signature, failures land in a DLQ and can replay; metering dedups by offset high-watermark. Approximate exactly-once via idempotency keys — without paying its price.
Cross-replica presence: fail-open, availability over global consistency
WhyMultiple realtime pods must share "who's online." Presence lives in a Redis ZSET (member = connection, score = heartbeat time), expired by scanning. If Redis is down, fail open to local state — I'd rather presence be briefly imprecise than let real-time connections drop entirely. A deliberate CAP trade-off.
Contract-drift testing: "docs as tests"
WhyAPI docs drift from implementation faster than anything. I use chi.Walk to read the actually-registered routes and compare them both ways against the OpenAPI spec — a route missing from the spec, or a spec entry with no route, turns the test red. Docs stop being a well-meant lie and become a CI-enforced truth.
Modular monolith: one binary, but real service boundaries
WhyFor a solo project, splitting into microservices up front is premature optimization. I chose a Go monorepo modular monolith: an allinone single binary to cut ops cost, with strict internal service boundaries (control-plane / gateway / realtime / worker / webhook-worker …) plus strict layering and DIP. A Compose/Helm split path is ready — no rewrite needed when it's time to split.

03 Engineering highlights

Reliable delivery

webhook HMAC signatures + retry + dead-letter queue (DLQ) + replay for at-least-once; offset high-watermark dedup for idempotency. Kafka · franz-go

Real-time + distributed state

SSE and WebSocket share one live-tail hub; cross-replica presence via Redis ZSET heartbeats, fail-open fallback to local. SSE / WebSocket · Redis

Multi-tenant control plane

Tenant / topic namespaces, schema registry + versioning + BACKWARD compat checks, API keys (producer/consumer/admin scope) with quotas and plans. PostgreSQL · etcd

Built for k8s scale-out

Stateless services + external state, etcd config, advisory-lock idempotent migrations (safe on concurrent pod start); Helm chart + HPA ready. Helm/K8s · etcd

Integration DX / differentiator

A native MCP server lets AI agents watch_topic to subscribe directly; the TS SDK is the single source of truth for the HTTP contract, with auto OpenAPI + Swagger UI and a CLI. MCP · TypeScript SDK

Defense in depth

SSRF protection (urlguard blocks private networks on the webhook side), human/machine credential separation (httpOnly session vs API key), capability keys + short-lived data-plane tokens, argon2id. chi · JWT · argon2id

04 How I keep quality

This is exactly where AI-assisted development gets questioned, so I built the guardrails into the process — and those guardrails are themselves the proof that this isn't "AI slop":

05 Stack

Go 1.25 · Kafka (franz-go) · PostgreSQL (pgx) · Redis · etcd
SSE / WebSocket · MCP · chi · JWT · argon2id · layered architecture + DIP
Helm / Kubernetes · Docker Compose · Prometheus · Sentry
Honest framing

This is a project I built and now run solo, AI-assisted, in about 5 weeks from zero (public beta — not a production-scale commercial service). My role: architecture decisions, setting the conventions, code review — and full-lifecycle ownership; much of the implementation code was produced by AI (Claude Code) under my direction and review. The guardrails above — contract tests, review gate, TDD, DLQ, idempotency — are how I make sure it isn't vibe-coded slop. For the deeper implementation I reviewed the approach; the details are open to inspection on request.

What this project is meant to prove: I can take a multi-tenant backend end to end on my own — architecture, implementation, launch and production ops — and hold the quality bar through engineering discipline, not luck. Exactly what a remote, high-autonomy team needs.