calendar-mcp
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 syncConfigure
Copy the example config and edit it:
cp calendars.example.toml calendars.tomlrefresh_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
nameappears in output.calendars.tomlis git-ignored; keep it private.
Run
uv run calendar-mcp calendars.tomlThe 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 |
| Each feed's refresh state, event count, last success (no URLs). |
| Events in a window (recurrences expanded), sorted by start. |
| Full detail (description, attendees) for one event UID. |
| Case-insensitive match on summary/description/location. |
| Merged busy intervals and the free gaps between them. |
| Convenience: |
| 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-IDoverrides) is expanded byrecurring-ical-events.Timezones: UTC,
TZID, and floating times are all normalized to timezone-aware ISO-8601; floating times getdefault_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-Modifiedare stored and sent as conditional requests, so an unchanged feed returns304and skips re-parsing.
Develop
uv run pytest # unit tests + fixturesNot in scope (v1)
Writing/creating events, tasks (VTODO) and reminders (VALARM), an HTTP/daemon
transport, and on-disk cache persistence across restarts.
License
Copyright (C) 2026 Jeremy Beker.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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