calnode README

The project's README from github.com/Calnode/calnode. As one markdown file: README.md.

Calnode

A lean, self-hostable scheduling engine that lives in your AI stack.

Calnode is a Calendly-style booking app — with first-party video meetings, recording, and AI notetaking built in — shipped as a single Go binary with an embedded SQLite database: no Redis, no Postgres, no separate API server, no multi-gigabyte image. It's API-first, webhook-native, and built for a world where agents do the booking. Self-host the whole thing on a $5 box; nothing is paywalled.

Calnode runs for pennies on a small VPS — it's a single static binary serving a SQLite file, so there's almost nothing to pay for.

Apache-2.0 · Go 1.26 · single static binary · SQLite + Litestream

OpenSSF Scorecard · Audit it yourself


Quick start

Kick the tires — one command, no config:

docker run -p 3000:3000 -v ./data:/data ghcr.io/calnode/calnode:latest
# → open http://localhost:3000

The whole app — booking pages, admin UI, SQLite — in one container, with data in ./data. With no encryption key set it runs on an ephemeral one (fine for a look; stored credentials won't survive a restart). Deploying for real — HTTPS, a persistent encryption key, backups — see Deploy for real below, or the full DEPLOY.md.


Why Calnode


Calnode vs cal.com

The default open-source scheduler is a SaaS monolith. Calnode is the opposite.

cal.com Calnode
Codebase 500k+ LOC TS across ~100 packages Lean Go + one SvelteKit app
Runtime deps 4 GB+ image; needs Redis + Postgres + API server One static binary + a SQLite file
Database Postgres (+ Redis) SQLite (WAL) + Litestream point-in-time backup
Webhooks UI-only API-first, HMAC-signed, per-webhook payloads
AI / agents None REST API + webhooks + a native MCP server (stdio + HTTP)
Video & recording Third-party links (Zoom / Meet) Built-in in-browser rooms + recording + AI notes (self-hosted LiveKit)
Deploy Orchestrate several services docker run one container
Isolation Shared multi-tenant DB (org_id everywhere) Instance-per-tenant — isolation is the default
Licence AGPL-3.0 Apache-2.0, nothing paywalled for self-host

(cal.com figures reflect its public footprint; see the the design docs for the full rationale.)

If you're weighing self-hosted schedulers and you want small, fast, scriptable, and AI-ready over feature-maximal, Calnode is built for you.


AI-native

Everything a human can do, an agent can do — over the API today:

# Find slots and book, with an API key
curl -s "$BASE/v1/event-types/intro-call/slots?from=2026-06-16&to=2026-06-20&tz=Pacific/Auckland" \
  -H "Authorization: Bearer $API_KEY"

curl -s -X POST "$BASE/v1/bookings" -H "Authorization: Bearer $API_KEY" \
  -H 'Idempotency-Key: 9f3c…' -H 'Content-Type: application/json' \
  -d '{"event_type_slug":"intro-call","start_at":"2026-06-17T21:00:00Z","name":"Alex","email":"[email protected]","timezone":"Pacific/Auckland"}'

Wire booking lifecycle events (booking.created / .rescheduled / .cancelled) to n8n / Make / your own service with HMAC-signed webhooks — all configured through the API, not buried in a UI.

Native MCP server. A Model Context Protocol server is compiled into the binary (official Go SDK), exposing eight first-class tools — list_event_types, get_event_type, get_available_slots, create_booking, get_booking, reschedule_booking, cancel_booking, list_bookings. The MCP tools call the same internal services as the REST API (no parallel code path), so booking side effects — calendar events, confirmation emails, webhooks, reminders — fire identically.

Two transports:

User:  "Book a 30-min call with Wynne next week — I'm in Auckland."
Agent: get_available_slots("intro-call", "2026-06-16", "2026-06-20", "Pacific/Auckland")
       → presents options → create_booking(…) → returns confirmation + meeting link

Conversational booking — in the booking page itself. Beyond agents, the booking page (and the embed widget) ships an optional "Book by chat" assistant: a visitor types "free Tuesday afternoon or next week" and it resolves real availability and books — the deterministic engine still computes the slots (the model never invents times), and the assistant only ever sees free/busy windows, never your calendar contents. Bring your own model — any OpenAI-compatible endpoint (a hosted model or one you run yourself); off by default, with the standard calendar always there as the fallback.

Connecting Claude (remote / HTTP). In Claude (claude.ai or Desktop) → Settings → Connectors → Add custom connector → enter https://<your-instance>/mcp → Connect → sign in → Allow. Custom connectors need a paid Claude plan; the server must be on HTTPS. Local stdio alternative (any plan): point an MCP client at the calnode mcp subcommand via its config file — no OAuth, runs against the local DB.

Permissions. MCP tools are role-scoped, mirroring the rest of the app: an owner/admin acts across the whole workspace, a member sees and manages only bookings they host. (The stdio subcommand is the local operator → full access.) Booking creation and availability are the public booking surface, open to all. Roles are fixed (owner / admin / member); configurable RBAC is intentionally out of the lean core.


Deploy for real

docker run -d -p 3000:3000 \
  -e BASE_URL=https://booking.example.com \
  -e CALNODE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
  -e CALNODE_RECOVERY_SECRET="$(openssl rand -hex 32)" \
  -e DATABASE_URL=sqlite:///data/calnode.db \
  -v calnode-data:/data \
  ghcr.io/calnode/calnode:latest

Pinning a version. :latest follows the newest tagged release; :edge tracks main. For reproducible deploys, pin a release — :0.1 (tracks patches within the minor) or an exact :0.1.0. See releases.

Open / → it redirects to /admin/ and walks you through first-run setup (create the owner account, connect a calendar, add an event type). Put a TLS-terminating proxy in front that forwards the original Host header.

Full guide → DEPLOY.md (env vars, Railway step-by-step, custom domains, Resend email, Google & Microsoft OAuth, Litestream backups, troubleshooting).


Features

Shipped

On the roadmap


Stack


Design principles

A few load-bearing decisions (full detail in the the design docs):


Audit it yourself in 10 minutes

Calnode's backend is small enough to fit entirely in one LLM's context window — most scheduling software (cal.com included) can't say that. AUDIT.md turns that into a self-serve check: a copy-paste scanner block (govulncheck, gosec, gitleaks across full history, SBOM, semgrep — all neutral, standard tooling you run yourself), an adversarial LLM prompt-pack for your own coding agent, and a claims → verification manifest mapping every security claim we make to exactly how to check it in the source. Not a certification — a due-diligence accelerator.


Commercial support

Self-hosting is free forever — docker run it and you own the whole thing. If you'd rather not run it yourself, Orchestratr — the team behind Calnode — will deploy and operate it for you:

Built for regulated and mid-to-large orgs that need Calnode on their own infrastructure, fully integrated. → calnode.com/services


License

Apache-2.0. The full scheduler is self-hostable, and nothing previously free is ever paywalled.

The code is Apache-2.0; the "Calnode" name and logo are not — see TRADEMARK.md (use the code freely; name your fork something else). Contributions are accepted under a CLA so the project can stand behind every line and keep its future licensing options open — see CONTRIBUTING.md.

calnode (Calnode/calnode)

Searching Database…

Что это?Calnode — самохостинговое приложение для планирования встреч в духе Calendly или Cal.com, поставляемое как один Go-бинарник со встроенной базой SQLite. Включает собственные видеовстречи, запись, AI-конспектирование и построено по принципу API-first с нативным MCP-сервером для AI-агентов.
Это полноценное приложение или просто библиотека для встраивания?Это законченное самодостаточное приложение: один статический Go-бинарник, который раздаёт админ-UI, публичные страницы бронирования и REST/MCP API, без внешних баз или сервисов.
Как его запустить?Для быстрого взгляда запустите одной docker-командой (данные хранятся в ./data) или следуйте DEPLOY.md для продакшн-настройки с HTTPS, постоянным ключом шифрования и бэкапами.
Нужны ли Postgres или Redis для запуска?Нет — Calnode сознательно их избегает. Единственная опциональная внешняя зависимость — сервер LiveKit, если вы включите встроенные видеовстречи.
Есть ли подводные камни в настройке по умолчанию или недостающие функции?Без заданного ключа шифрования он работает на эфемерном, поэтому сохранённые учётные данные не переживут перезапуск. Кроме того, RBAC жёстко ограничен ролями owner/admin/member (без кастомных прав), а переводы не на английский сделаны машинно без вычитки носителями.
Для кого это вместо cal.com?Для тех, кто хочет маленький, быстрый, скриптуемый, готовый к AI самохостинговый планировщик, а не максимально нафаршированный SaaS-монолит вроде cal.com.
Можно ли дёшево запустить это на крошечном VPS?Да — он рассчитан на VPS за $5, поскольку это просто статический бинарник, обслуживающий файл SQLite.
Видит ли AI-ассистент мои настоящие данные календаря?Нет — разговорный ассистент «Book by chat» видит только окна занятости/свободы, но никогда не содержимое календаря, а фактические свободные слоты считает детерминированный движок, а не модель.
Не указано в READMECalnode лицензирован под Apache-2.0, и для самохостинга ничего не закрыто платным доступом, в отличие от AGPL-3.0 у cal.com.
Что MCP-сервер реально позволяет делать агенту?Встроенный MCP-сервер открывает инструменты вроде listeventtypes, getavailableslots, createbooking, getbooking, reschedulebooking, cancelbooking и listbookings, плюс инструменты заметок/транскриптов встреч, через stdio или Streamable HTTP, используя те же внутренние сервисы, что и REST API.
Как Calnode обращается с часовыми поясами и переводом часов?Время хранится как момент UTC плюс имя часового пояса IANA, а не фиксированное смещение, поэтому доступность всегда корректно вычисляется при переводах часов, а не искажает слот.
Поддерживается ли приём оплаты за бронирования?Да — через Stripe Checkout по схеме «сначала оплата, потом бронь»: слот удерживается, подтверждается по платёжному вебхуку и автоматически возвращается при отмене брони.
Как подключить Claude или ChatGPT к моему экземпляру Calnode?Для Claude добавьте его как custom connector через Settings → Connectors, используя ваш HTTPS-адрес и вход через OAuth (нужен платный план Claude); для локальных агентов без OAuth запустите субкоманду calnode mcp через stdio на локальной базе.
Creator
Calnode
Size
2.8 MB
Stars
118
Age
3mo
Commits · 90 Days