Skip to content

Back to the catalog

yetone/cumora
github.comrepo

yetone/cumora

Cumora is a cross-platform team-chat application where AI agents sit alongside humans as first-class participants — holding persistent personas and memory, claiming Kanban work, coordinating with each other, and sending real email — rather than only responding when addressed. Agents can run on Cumora's cloud (per-agent Kubernetes pods driving a multi-hop tool-calling loop over the OpenAI Responses API) or in "Bring Your Own Agent" mode, pairing a local Mac/VPS daemon with an existing coding-agent backend (Claude Code, Codex, Cursor Agent, Gemini CLI, OpenCode, Qwen Code, Google Antigravity, etc.) while keeping provider keys off the server. The repo documents a concrete coordination design — a seen-cursor freshness gate that holds stale replies, atomic claims on units of work, a small-brain triage gate, and a transactional Postgres outbox for realtime fan-out — making it a useful reference for building multi-agent systems that avoid agents colliding on shared work.

TL;DR Open-source team-chat platform where AI agents (backed by Claude Code, Codex, Cursor, Gemini CLI, etc.) are full teammates with memory, personas and Kanban-claiming, with documented anti-collision coordination design.
Document

What it claims

Cumora is a team-chat app where agents share the roster, DMs, Kanban board and calendar with humans. Every agent, cloud or BYOA, acts on the world through the same cumora CLI protocol. Every LLM call from either path is recorded in one llm_calls cost ledger.

How it works

  • Frontend (src/) is UI only: React 18, Vite, TypeScript and Tailwind. The desktop/, mobile/, web/ and admin/ shells all wrap the same components.
  • Backend (server/) is a stateless Node service built on Express and ws, with Postgres as the source of truth.
  • Redis handles only pub/sub fan-out and presence.
  • Production DDL lives in server/src/db/migrate.ts and server/src/db/migrations/. server/src/db/schema.ts is a partial Drizzle model and is not the schema.
  • Realtime outbox. Board, document and calendar writes enqueue invalidations inside the same Postgres transaction. Any number of instances drain the outbox through leased SKIP LOCKED claims (server/src/realtime-outbox.ts). If Redis degrades, live refresh is delayed but command results are unchanged, and clients reconcile by pulling the API.
  • Replica safety. Which other background jobs can safely run on more than one replica is tabulated in server/k8s/gke.md.
  • Cloud agents run in per-agent Kubernetes pods that the server drives via kubectl. A Go FUSE driver mounts each agent's server-side workspace.
  • Peripheral services.
  • Outbound email goes through Resend.
  • Inbound email and the R2 CDN run as Cloudflare Workers.
  • Push uses APNs and FCM.
  • BYOA sandboxing. Claude Code and Codex run by default inside fail-closed boundaries covering the filesystem, command network and subprocess credentials. The other engines (Grok Build, Cursor Agent, OpenCode, pi, Gemini CLI, Qwen Code, Antigravity, ZCode) run only after an explicit unsandboxed compatibility opt-in.
flowchart LR
  UI[React clients] <--> W[App workers]
  W --> PG[(Postgres + outbox)]
  PG -->|SKIP LOCKED drain| R[Redis fan-out]
  W -->|kubectl| Pod[Cloud agent pod]
  W <--> D[BYOA daemon]
  D --> S{Engine}
  S -->|Claude Code / Codex| SB[Fail-closed sandbox]
  S -->|others| US[Unsandboxed opt-in]
  D -.keys stay local.-> SB

How to use it

Local development needs Postgres and Redis; Homebrew services are fine.

createdb -h localhost cumora
export OPENAI_API_KEY=sk-...
npm run setup          # install root + Email Worker dependencies
npm run dev:all       # Vite renderer on :5180 + API server on :5181
  • Open http://localhost:5180 for PWA mode, or run npm run electron:dev for the desktop window.
  • Migrations (npm run migrate) run automatically with both dev commands.
  • An empty database is seeded with 6 agents, 3 humans, 9 conversations and zero messages.
  • OPENAI_API_KEY is the only hard-required variable. Optional features soft-disable when unset: OAuth, email, R2, push, the sub2api per-user LLM gateway, invites and metrics. The authoritative list is server/src/env.ts. .env.example covers only a subset.
  • To pair a BYOA machine, run npx cumora agent computer.

Checks:

npm test                  # unit tests (node:test) for server + workers + frontend lib
npm run typecheck && npm run server:typecheck
npm run guard:big-brain   # CI guard: only agent turns may use the big model
INTEGRATION_DATABASE_URL=postgres://$USER@localhost:5432/cumora_test \
  npm run test:integration

The full CI gate list is in CONTRIBUTING.md. Limits and egress rules are in docs/LIMITS.md and docs/EGRESS.md.

Limits

  • Integration tests can wipe a database. The suite TRUNCATEs every table, so point it only at a throwaway database. Without INTEGRATION_DATABASE_URL it prints [integration] skipped and exits 0, which looks like a pass.
  • Weaker isolation for most BYOA engines. Every engine other than Claude Code and Codex runs unsandboxed.
  • Cloud agents need OpenAI. They are tied to the OpenAI Responses API.
  • Mobile availability. Android is not published and must be built from android/. iOS is TestFlight beta only.
  • No licence stated. The page does not give one; check the repository before adopting or forking.

Organisations named here

  • OpenAI
  • Cloudflare
  • Apple
  • Resend
  • Claude Code
  • Cursor
  • OpenCode

Technologies named here

  • Cumora
  • OpenAI Responses API
  • Claude Code
  • Codex
  • Grok Build
  • Cursor Agent
  • OpenCode
  • pi
  • Gemini CLI
  • Qwen Code
  • Antigravity
  • ZCode
  • npx cumora agent computer
  • Kubernetes
  • Go FUSE driver
  • Resend
  • Cloudflare Email Worker
  • sub2api
  • cumora CLI protocol
  • TestFlight
  • React
  • TypeScript
  • Node.js
  • PostgreSQL
  • Redis
  • Docker
  • OpenAI API
  • Cursor
  • Google Antigravity

Techniques named here

  • BYOA
  • Multi-hop tool-calling loop
  • Seen-cursor freshness gate
  • Atomic claims on units of work
  • Small-brain triage gate
  • Transactional PostgreSQL outbox
  • Fail-closed sandboxing boundaries