Skip to main content
Glama
jbeker

calendar-mcp

by jbeker

calendar-mcp

An MCP server that exposes read-only calendar data from iCal (.ics) feed URLs to an MCP-compatible agent.

You point it at one or more iCal URLs. It fetches them on a regular interval, expands recurring events, caches everything in memory, and offers tools an agent can call to answer questions like "what's on my calendar this week?", "am I free Thursday afternoon?", or "find events mentioning 'dentist'".

It never writes to any calendar — iCal feeds are pull-only sources.

Install

Requires Python ≥ 3.11 and uv.

uv sync

Related MCP server: Google Calendar MCP Server

Configure

Copy the example config and edit it:

cp calendars.example.toml calendars.toml
refresh_interval_minutes = 15          # how often to re-fetch (min 5)
default_timezone = "America/New_York"  # applied to floating times & agenda math
max_results = 200                      # cap on events returned per tool call

[[calendars]]
name = "Work"
url  = "https://example.com/work.ics"

[[calendars]]
name = "Family"
url  = "https://calendar.google.com/.../basic.ics"

Feed URLs are secrets. Google/Apple/Outlook "private address" URLs embed an access token. The server never logs or exposes the URL — only the friendly name appears in output. calendars.toml is git-ignored; keep it private.

Run

uv run calendar-mcp calendars.toml

The server speaks the MCP stdio protocol, so it's normally launched by your MCP client rather than by hand. Register it like this:

{
  "mcpServers": {
    "calendar": {
      "command": "uv",
      "args": ["run", "calendar-mcp", "/absolute/path/to/calendars.toml"]
    }
  }
}

Tools

Tool

What it does

list_calendars

Each feed's refresh state, event count, last success (no URLs).

list_events

Events in a window (recurrences expanded), sorted by start.

get_event

Full detail (description, attendees) for one event UID.

search_events

Case-insensitive match on summary/description/location.

free_busy

Merged busy intervals and the free gaps between them.

agenda

Convenience: today | tomorrow | week | next.

refresh

Force an immediate re-fetch of all feeds.

Times are ISO-8601. If you omit a window, a sensible default is used. Results are capped at max_results and flagged truncated when trimmed, so large calendars don't overrun the agent's context.

Design notes

  • Recurrence (RRULE/EXDATE/RECURRENCE-ID overrides) is expanded by recurring-ical-events.

  • Timezones: UTC, TZID, and floating times are all normalized to timezone-aware ISO-8601; floating times get default_timezone.

  • Resilience: a feed that fails to fetch or parse keeps its last-known-good data and records the error in its status — it never wipes the cache or crashes the refresh loop.

  • HTTP efficiency: ETag/Last-Modified are stored and sent as conditional requests, so an unchanged feed returns 304 and skips re-parsing.

Develop

uv run pytest        # unit tests + fixtures

Not in scope (v1)

Writing/creating events, tasks (VTODO) and reminders (VALARM), an HTTP/daemon transport, and on-disk cache persistence across restarts.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jbeker/calendar_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server