calendula
calendula is an MCP server for read-only access to a classic Outlook calendar from WSL, with limited Outlook lifecycle controls.
List calendar events for a day or up to 31 days (
list_events), including time, subject, and location; optional date and refresh.Get details for the event at a given time (
get_event), including location, organizer, attendees, status, and body; if none is running, returns the nearest timed event with a note.Refresh Outlook data on demand, while fetched days are cached in memory only: today/future for up to 1 hour by default, past days for the session.
Restart Outlook (classic) to recover a broken COM connection, only after user agreement because unsaved drafts may be lost.
Start Outlook (classic) if it is closed, only after user agreement; it never closes Outlook.
Run as a stdio MCP server or via CLI commands, using PowerShell/COM rather than Microsoft Graph, and never writing calendar data to disk.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@calendula What's on my calendar tomorrow afternoon?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
calendula
An MCP server that lets Claude Code (or any MCP client) read your Outlook (classic) calendar from WSL.
Read-only: list the events of a day (or several), or look up the event at a given time with its attendees and body
Talks to Outlook on Windows through PowerShell and COM: no Microsoft Graph, no admin consent, no tokens
Keeps what it fetched in memory only; nothing is written to disk (see Caching)
Requirements
Windows with Outlook (classic) running. The new Outlook has no COM interface and does not work
WSL: calendula runs in the Linux distribution and calls
wscript.exe,powershell.exeandtasklist.exethrough WSL interopPython 3.11 or later
Related MCP server: Microsoft Calendar MCP Server
Install
uv tool install calendula # or: pipx install calendula
calendula list # prints today's events (checks that Outlook answers)Register it with Claude Code for all your projects:
claude mcp add --scope user calendula -- calendulaOther MCP clients: run calendula as a stdio server.
Then ask things like "What's on my calendar tomorrow afternoon?" or "Who is in the 14:00 meeting?".
To let Claude read the calendar without asking each time, allow the two read-only tools in ~/.claude/settings.json:
{
"permissions": {
"allow": ["mcp__calendula__list_events", "mcp__calendula__get_event"]
}
}Tools
Tool | Arguments | Returns |
|
| Each day's events: time, subject, location |
|
| The event running at that time (or the one starting nearest to it, with a note): location, organizer, attendees, status, body |
| none | Force-quits Outlook and starts it again, to recover a broken COM connection. Unsaved drafts are lost, so the model is told to ask you first |
| none | Starts Outlook when it is closed, and never closes it. It opens a window on your desktop, so the model is told to ask you first |
Every answer starts with the day and the time it was fetched:
2026-11-05 (Thu) fetched 2026-11-05 10:32
09:00-10:00 Weekly sync [Room A]
13:30-14:30 Customer interviewAn event that spans several days (a conference, a meeting past midnight) appears on each day it covers. Bodies are kept whole except for blank lines and the Teams join block.
Caching
Fetching takes a few seconds (PowerShell starts, then Outlook answers over COM), so fetched days are kept in the server's memory:
Today and later are reused for up to 1 hour, then fetched again
Past days fetched after they ended are kept for the life of the server (one Claude Code session)
refresh: truealways fetches; ask for it when the calendar has just changedA request fetches only the days that are missing or stale, in one call
When fetching fails, the error is returned as is; older copies are never shown instead
Nothing is written to disk. Set CALENDULA_TTL_MINUTES to change the 1 hour.
Command line
calendula run the MCP server on stdio (same as `calendula serve`)
calendula list [DATE] [DAYS] print events, fetched from Outlook now
calendula show TIME [--date DATE] print the event at a time
calendula --versionTroubleshooting
CO_E_SERVER_EXEC_FAILURE(0x80080005) and similar COM errors: Outlook's COM connection often breaks after sleep or a network change. Restart Outlook (Claude will ask before callingrestart_outlook)Outlook (classic) is not running: start Outlook and try again, or let Claude do it (it will ask before callingstart_outlook). Reading the calendar never starts Outlook by itself: a closed Outlook can stop at its setup screen, and the read would hangOutlook (classic) has no mail profile:start_outlookdoes not open Outlook on a PC where it has not been set up. If you do want to use it there, set it up in Outlook by hand. Only Office 2016 and later are recognizedOutlook gave no answer: check that Outlook (classic) is runningcalendula needs WSL ...: calendula only works inside WSL on a Windows PC with Outlook
How it works
For each fetch, calendula checks with tasklist.exe that Outlook is running, then writes get_calendar.ps1 (as UTF-16 with a BOM, which Windows PowerShell 5.1 reads correctly) into a temporary directory under /tmp, and runs it hidden through wscript.exe and run_hidden.vbs, using the \\wsl.localhost\... path. The script reads the default calendar folder through Outlook.Application, including recurring events, and writes events.json, which calendula parses.
Development
uv sync
uv run pytest # needs neither Windows nor Outlook
CALENDULA_WINDOWS_TESTS=1 uv run pytest # on WSL: also the PowerShell side, still without Outlook
uv run ruff check && uv run ruff format --checkWhat is tested where, and why, is in docs/test-design.md; the behavior it checks is specified in docs/spec.md.
Releases: bump version in pyproject.toml, then push a tag vX.Y.Z. GitHub Actions tests, builds, publishes to TestPyPI, installs from there, publishes to PyPI (Trusted Publishing), and creates a GitHub release.
License
Available Tools
4 toolsget_eventARead-onlyIdempotent
Details of the event at a time: location, organizer, attendees, status, and the body.
If no event is running at that time, returns the timed event that starts nearest to it (and says so).
Inputs: time (required), date, refresh. Returns: result
list_eventsARead-onlyIdempotent
List events (time, subject, location) day by day. Use get_event for attendees and the body.
Inputs: date, days, refresh. Returns: result
restart_outlookADestructive
Force-quit Outlook (classic) and start it again, to recover a broken COM connection.
Unsaved drafts are lost. Call it only after the user has agreed, and only after a fetch failed with a COM error.
Inputs: no named parameters. Returns: result
start_outlookAIdempotent
Start Outlook (classic) if it is not running. It never closes Outlook.
It opens a window on the user's desktop. Call it only after the user has agreed, and only after a fetch failed because Outlook is not running.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool has a clearly distinct role: start_outlook and restart_outlook differ by their recovery scenario, while list_events and get_event separate summary listing from detailed event retrieval. Descriptions explicitly clarify when to use each, preventing misselection.
All tools follow a consistent snake_case verb_noun pattern: start_outlook, restart_outlook, get_event, list_events. The convention is predictable and readable throughout.
Four tools is a reasonable, well-scoped set for a narrow Outlook calendar helper with process recovery. It is slightly thin, but each tool earns its place rather than being redundant.
The surface only supports reading events and managing Outlook process state; there is no way to create, update, delete, or search events. For a calendar domain, this leaves significant lifecycle gaps that would cause agent failures on common tasks.
Maintenance
Related MCP Connectors
A MCP server that works with Outlook Calendar to manage event listing, reading, and updates.
EU-hosted calendar MCP: Google, Outlook, iCloud, GMX, WEB.DE, CalDAV. Read, book, RSVP, sync.
MCP server for Cronofy — read calendars, events and free/busy, and create, update or delete events.
Read Schedule it events, resources, groups and labels; create and update events and resources.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables interaction with Outlook / Microsoft 365 calendar, allowing users to list events, get event details, find meeting times, and access calendar and profile information.308 npm1MIT
- AlicenseAqualityDmaintenanceEnables fetching and managing Microsoft Outlook calendar events within date ranges through natural language, using Azure AD authentication and dual transport support for compatibility with Claude Desktop and other MCP clients.1MIT
- FlicenseNot gradedqualityDmaintenanceEnables interaction with Google Calendar via MCP, allowing users to list, get, search, and create events as well as list accessible calendars.-
- AlicenseAqualityDmaintenanceEnables reading your Microsoft 365 calendar to get today's meetings and availability.220 npmMIT