Documentation

How OpenCalendar works, and how to use it.

Everything here describes the app as it is today. Where something is built but not yet switched on, or still being built, it says so.

Getting started

  1. Open the app. No sign-up is needed. The first time it runs, the app makes a key in your browser; it is how people who book you know a link is yours.
  2. Add a calendar: open a calendar file, follow a calendar address, or press + beside Calendars to start an empty one.
  3. Open Scheduling links, press New link, fill in what guests should see and when you can meet, and press Save and publish.
  4. Press Copy link and send it to someone.

Your calendars, links and key are kept in this browser only. Read Your key and backups before you rely on it.

Connect, use and disconnect a calendar

Every calendar you tick in the sidebar is shown in the grid and counts as busy time for your scheduling links.

Calendar files Available

Followed calendars Available

Google Calendar Built · awaiting Google’s approval

Not available yet. The connection is built and is waiting for Google’s review of the app; until then Settings shows no Connect button for Google. These are the steps once it is switched on.

What is read, where it is kept and who can see it is in the privacy policy, under Google user data.

Microsoft Outlook and Microsoft 365 Built · awaiting registration

Not available yet. The connection is built and is waiting for the app’s registration with Microsoft; until then Settings shows no Connect button for Microsoft. These are the steps once it is switched on.

iCloud and other CalDAV servers Built · not available yet

Built, and not available yet. The connection has been proven against a CalDAV server of another make, not against iCloud or Fastmail themselves; and in a browser it needs the helper, which is not running yet. Until it is available, an iCloud calendar can be followed through its public calendar address, or opened from an exported file.

Make it the default app for calendar files

An installed copy of the web app can open calendar files from your computer. This works in Chrome and Edge on a computer. A desktop app that does this without a browser is being built and is not available yet.

  1. Install it. Open the app and choose Install from the browser’s address bar or menu.
  2. Open a file with it. Right-click an .ics, .vcs or .ifb file, choose Open with, and pick OpenCalendar. The first time, the browser asks whether to allow it.
  3. Make it the default. On a Mac: select the file, choose Get Info, set Open with to OpenCalendar and press Change All. On Windows: right-click the file, choose Open with, Choose another app, pick OpenCalendar and choose Always.
  4. Calendar links. In Settings, under Calendar links, press Open calendar links here so that webcal: links, the kind a “subscribe to calendar” button uses, open in OpenCalendar.

A scheduling link looks like this:

https://opencalendar.me/app/#/b/npub1…/intro?k=…

Everything after the # stays in the browser: your public key, the link’s name and the link’s own key. A web server never receives it.

  1. You publish. Your browser encrypts the page (title, lengths, hours, questions, meeting link) and the times you are busy inside the booking window, using the link’s key, and leaves both on the relay. Busy times are start and end only, rounded to the slot size.
  2. The guest opens the link. Their browser fetches those records, opens them with the key in the link, and works out the free times itself: your hours, minus your busy times, minus slots already claimed. It shows each time in the guest’s zone and yours, and says when your calendar was last read.
  3. The guest books. Their browser leaves two records: a claim on the slot, and a sealed request that only you can open, with their name, email address and answers.
  4. The claim stops double booking. Every guest’s browser reads the claims and treats a claimed slot as taken. The earliest claim on a slot wins. This works while all of your devices are off.
  5. You answer. When your app is next open it checks the slot against your calendars, adds the meeting, and sends a sealed reply: confirmed, declined, or other times. The guest’s private status link shows the answer, and lets them move or cancel.

When a booking counts as confirmed

You choose on each link:

Group links

A group link lists several hosts by public key, and a rule: everyone must be free, or any one host may take the meeting (round-robin). Each host publishes their own busy times, signed with their own key. The guest’s browser combines them. No host sees another’s calendar, and the request goes to each host. To be added to a group, copy your public key from Settings and give it to whoever makes the link.

A host who cannot connect their work calendar can still take part, with busy times from a followed calendar address or a file.

Shared calendars and polls

Sharing a calendar. Open the calendar’s Share dialog, paste a person’s public key, give them a name, and choose what they may do: see only when it is busy, see events, or see and change events. Events are encrypted on your device before they are sent. Removing someone issues new keys, so they cannot read what is written afterwards; what they already have, they keep. Attachments are not shared: other members see a file’s name and size only.

A meeting poll. In Scheduling links, press New poll, propose a few times and send the link. Each person answers yes, maybe or no in their own time zone. A vote is signed by a key the voter’s browser makes, so nobody holding the link can change someone else’s answer. You pick the time and the meeting is added to your calendar.

What the relay can and cannot see

The relay is a server that stores and forwards signed, encrypted records. The app uses wss://relay.opensync.network/ unless you set another in Settings. It is the only server that holds anything of yours, and it holds it sealed.

The relay can seeThe relay cannot see
That encrypted records exist, how large they are, and when they arrivedYour events, their titles, places or attendees
The public key that signed a scheduling page and its busy times — the host’sWhat the page says, or when the host is busy
That a one-day key left a claim, with an opaque tagWhich link or which slot the claim is for
How many sealed messages are addressed to a public keyWho sent them, what time they are about, or what they say
The network address of each connectionThe link’s key: it is never sent to any server

Three things to know, because they are not obvious:

For agents: the CLI and MCP server

opencalendar is the same scheduling core as the web app, built as a local program, so the times it offers are the times the page offers. It runs on your own machine and talks to the relay directly. There is no hosted endpoint.

It builds from the source with Cargo. The public repository is not open yet, so there is nothing to download today; these are the commands once it is.

cargo build --release -p cal-cli

opencalendar mcp                         # an MCP server on stdin and stdout
opencalendar tools                       # list the tools
opencalendar find_times '{"link":"https://opencalendar.me/app/#/b/npub1…/intro?k=…","tz":"Europe/London"}'

To give it to an MCP client, register the command:

{ "mcpServers": { "opencalendar": { "command": "opencalendar", "args": ["mcp"] } } }
ToolWhat it does
link_infoReads a scheduling link: who it is with, how long, where, in which time zone, and whether a booking made now is confirmed at once or is a request
find_timesThe open times on a link. For a group link, the times that work for the group
propose_bookingBooks one open time for a named person. Returns whether it is confirmed or a request, and a private status link
booking_statusWhat became of a booking: waiting, confirmed, declined, cancelled, or a counter-proposal
reschedule_bookingMoves a booking to another open time on the same link
cancel_bookingCancels a booking and tells the host
read_calendar_fileThe events in .ics files on this machine, with repeating events expanded
free_timeWhen the owner of some .ics files is free for a meeting of a given length

The rules it keeps, so that an agent cannot quietly get a time wrong:

What it does not do today: read or change the calendar inside your OpenCalendar app, or act as you on a shared calendar. It books on links, as a guest would, and reads calendar files.

Running your own helper and relay

The helper is a small program that does the two things a web page cannot: fetch a calendar address from a site that does not allow web pages to read it, and add the secret Google requires to complete or renew a sign-in. It has no database, writes no file, and logs no address, token or body. It answers only the one app origin it was started for.

GET  /healthz
GET  /fetch?url=https://…      a calendar file, passed through
POST /google/token             a sign-in code or a refresh token, passed to Google

To run your own beside your own copy of the app:

HELPER_BIND=127.0.0.1:5208 \
HELPER_ALLOW_ORIGIN=https://calendar.your-domain.example \
GOOGLE_CLIENT_ID=… GOOGLE_CLIENT_SECRET=… \
cargo run --release --manifest-path crates/cal-helper/Cargo.toml

Then tell your copy of the app where it is, in the app’s config.json. No rebuild is needed:

{ "googleClientId": "…", "microsoftClientId": "…", "helperUrl": "https://helper.your-domain.example" }

Your own relay. Set its address in Settings, under Relay. The app needs a relay that will store application data (kind 30078) and gift wraps (kind 1059) from keys it has not seen before. The relay the app uses by default is open source, at github.com/open-sync/opensync. A link published to another relay carries that relay’s address, so your guests’ browsers are sent to yours.

Your key and backups

The account, which is optional

The round button at the top right of the app opens the account page. The account is one sign-in shared by our apps, with a balance of credits that the apps with paid features spend. OpenCalendar needs none of it. Nothing in the app is behind the account, nothing in it costs credits, and a booking page, a status page or a poll never shows it.

What the account server holds, and how to remove it, is in the privacy policy.

Known limits

Removing OpenCalendar

  1. Export any calendars you want to keep.
  2. Disconnect connected accounts in Settings, Accounts, and remove the app’s access at Google or Microsoft if you connected one.
  3. If you signed in to the optional account and want it gone too, open the account page and press Delete account…. Signing out alone leaves the account where it is.
  4. In Settings, press Delete everything here. This removes every calendar, link, booking and the key from the browser. It cannot be undone.
  5. If you installed the app, uninstall it from the browser’s app menu.

Once the key is gone, a booking made through a link you gave out reaches nobody, so tell the people who have one. What remains on the relay is sealed and expires as described under the relay; the details are in the privacy policy.