cd /news/ai-agents/calnode-vs-calrs-vs-tymeslot-three-s… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-141380] src=github.com β†— pub= topic=ai-agents verified=true sentiment=↑ positive

Calnode vs. calrs vs. Tymeslot: three self-hosted answers to Calendly

Calnode launched as an Apache-2.0 self-hosted Calendly alternative distributed as a single Go 1.26 static binary with an embedded SQLite database, requiring no Redis, Postgres, or separate API server. Calnode ships a REST API with 88 endpoints, HMAC-signed webhooks configurable via API, a native MCP server built on the official Go SDK with stdio and Streamable HTTP transports, and optional first-party LiveKit video rooms with recording and an AI notetaker exposed as MCP tools and webhooks. The project positions itself against cal.com, which it says spans 500k+ lines of TypeScript across roughly 100 packages and needs a 4 GB+ image with Redis, Postgres, and an API server, while Calnode runs from a single docker run command on a $5 VPS.

read11 min views1 publishedSep 29, 2026
Calnode vs. calrs vs. Tymeslot: three self-hosted answers to Calendly
Image: Michielbdejong (auto-discovered)

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

Kick the tires β€” one command, no config:

docker run -p 3000:3000 -v ./data:/data ghcr.io/calnode/calnode:latest

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.

  • One binary, one file. Pure-Go SQLite (no CGO) compiles to a fully static binary.docker run it, or drop it on a VPS. No external services to orchestrate (built-in video, if you turn it on, is the one add-on β€” it needs a LiveKit server).
  • Meetings built in. Optional first-party video rooms (LiveKit) as a booking location β€” guests join in-browser, no app or account. Recording lands in your own Litestream backup bucket (no extra storage to provision); an AI notetaker turns each call into a transcript + notes, exposed as MCP tools and webhooks. The one add-on: video needs a LiveKit endpoint (Cloud or self-hosted).
  • API-first, agent-ready. A full REST API (88 endpoints) with API keys andHMAC-signed webhooks configured via API β€” script every booking action from Claude, ChatGPT, n8n, or curl. Plus a nativeMCP server built into the binary (official Go SDK; stdio + Streamable HTTP) so agents get first-class booking tools.
  • Modern, no bloat. Go backend + a SvelteKit 5 admin app; public booking pages are server-rendered Go templates for instant first paint and a tiny payload.
  • Correct by construction. DST-safe time handling (UTC instant + IANA name), a transactional double-booking guard, and native-API calendar free/busy (never stale.ics feeds).
  • Yours. Instance-per-tenant by design β€” one deployment is one isolated workspace, your data, your calendar credentials. No shared multi-tenant database.
  • Easy to extend. A clean Go codebase withsqlc -generated queries β€” not a 100-package monorepo. Add an endpoint without spelunking.

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.

Everything a human can do, an agent can do β€” over the API today:

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":"alex@example.com","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:

  • stdio for local agents β€” runcalnode mcp (logs to stderr, JSON-RPC on stdout).
  • Streamable HTTP atPOST /mcp for remote agents. Calnode is its ownOAuth 2.1 authorization server (dynamic client registration + PKCE), so an agent adds the server by URL and clicksConnect β†’ signs in with the workspace's Google/Microsoft login β†’ approves a consent screen β€” no pre-shared key. Acno_ API key also works (Authorization: Bearer <key> ) for scripts.(The Connect UX needs HTTPS β€” it shines on a deployed instance.)
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.

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).

Shipped

  • Event types with per-type duration, location, custom questions, custom email copy
  • DST-correct availability (working hours, day-of-week rules, date overrides)
  • Team routing: fixed Β· round-robin Β· collective Β· priority
  • Google Calendar & Microsoft 365 / Outlook β€” native free/busy conflict checks behind one provider abstraction; autoGoogle Meet / Teams links, minted only when the host's connected calendar matches the platform (else a manual link is used)
  • Sign in with Google or Microsoft (OAuth), email + password, orpasswordless magic-link
  • CalDAV calendars β€” iCloud / Fastmail / Nextcloud via app-password (free/busy + event write-back)
  • Public booking + self-serve reschedule/cancel via signed manage links
  • HTML branded email (logo, banner, business name, size/opacity) with add-to-calendar links
  • REST API (88 endpoints) + API keys; HMAC webhooks with per-webhook payloads + delivery log
  • Native MCP server (10 tools incl. meeting notes + transcript; stdio viacalnode mcp + Streamable HTTP at/mcp )
  • Conversational booking ("Book by chat" on the booking page + embed widget; BYO-LLM, off by default)
  • Paid bookings β€” Stripe Checkout (pay-then-book: the slot is held, confirmed on the payment webhook, auto-refunded on cancel)
  • Zoom β€” per-host OAuth; a Zoom-located booking mints a meeting under the assigned host's account
  • Built-in video meetings (LiveKit) β€” in-browser rooms as a booking location (no app or account for guests); host controls (end-for-all, hand-offand reclaim host, attendee screen-share toggle),meeting recording straight to your ownLitestream backup bucket (the same one you already use for DB backup β€” no extra storage to provision) with in-app downloads,recording consent (notice + consent-or-leave), and anAI notetaker (Deepgram transcript β†’ LLM notes). Headless-consumable: MCPget_meeting_notes /get_transcript +recording.completed /transcript.ready /notes.ready webhooks. BYO LiveKit endpoint (Cloud or self-hosted); configured in Settings β†’ Video β€” seedocs/VIDEO.md
  • 9 languages on every booker-facing surface - booking page, manage/reschedule page, embed widget, all four emails, and the calendar invite:English Β· Spanish Β· French Β· Canadian French Β· German Β· Italian Β· Portuguese Β· Dutch Β· Swedish . Picked fromAccept-Language with a footer switcher and an operator-set fallback language; the booker's choice is stored on the booking, so reminders arrive in the language they booked in. Adding a language is adding one JSON file - no code change.(The admin UI and the built-in video room are English-only. Non-English translations are machine drafts without native review - corrections by PR are very welcome.)
  • Embeddable booking widget (Shadow-DOM web component; inline + popup)
  • Members, roles (owner/admin/member), email-token invitations
  • Idempotency-Key on booking creation; transactional double-booking guard
  • Envelope encryption at rest (secrets sealed with a KEK; recovery escrow)
  • Optional analytics: <head> code injection +window.dataLayer events (GTM/GA4)

On the roadmap

  • OpenAPI spec Β· /metrics Β· multi-domain (one instance, many hostnames)

  • Backend: Go 1.26 Β· pure-Go SQLite (modernc.org/sqlite , CGO-free β†’ static binary) Β·goose migrations

  • Admin UI: SvelteKit 2 / Svelte 5 Β· Vite 8 Β· Tailwind 4 Β· shadcn-svelte (embedded at compile time viago:embed )

  • Public pages: server-rendered Gohtml/template + vanilla JS (no framework runtime)

  • Durability: SQLite WAL + optional Litestream replication (S3/R2) for backup & point-in-time restore

  • Background work: in-process job queue on the same DB β€” reminders, webhook delivery, calendar reconciliation. No broker.

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

  • The DB is the source of truth; external calendars are a projection. A booking exists once it's committed locally; syncing to Google is a retryable side effect.
  • Time = UTC instant + IANA timezone name , never a fixed offset β€” availability resolves to UTC per-date so DST shifts never corrupt a slot.
  • Single process, no external services. Durability comes from Litestream, not a second datastore. (The one exception is optional built-in video: it talks to a LiveKit server β€” Cloud or self-hosted β€” only when you enable video.)
  • Instance-per-tenant. Each install is one workspace; isolation is a feature, and the self-host and cloud codepaths are identical.

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.

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:

  • Production deployment on your infrastructure β€” VPC, private cloud, or bare metal
  • SSO (SAML / OIDC) integrated with Okta, Entra ID, or Google Workspace
  • Calendar, Zoom & CRM integration wired into your existing stack
  • Migration off Calendly / cal.com, plus bulk user & team provisioning
  • Training & ongoing support for your ops and IT teams

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

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.

── more in #ai-agents 4 stories Β· sorted by recency
── more on @calnode 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/calnode-vs-calrs-vs-…] indexed:0 read:11min 2026-09-29 Β· β€”