OpenSlot MCP
Allows querying Google Calendar ICS feeds to retrieve busy/free availability and find open meeting slots.
Allows querying iCloud calendars through public webcal:// ICS feeds to retrieve busy/free availability and find open meeting slots.
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., "@OpenSlot MCPWhat free slots do I have tomorrow between 9am and 5pm?"
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.
OpenSlot MCP
A read-only Model Context Protocol server that turns one or more Outlook, iCloud, or Google calendars into privacy-safe availability queries. It accepts HTTPS ICS feeds and iCloud-style webcal:// subscription links.
It intentionally never returns event titles, descriptions, locations, attendees, organizers, or raw calendar data — only busy/free time intervals.
Requirements
Node.js 20.6 or newer.
An HTTPS or
webcal://URL to an ICS calendar feed.
No installation is needed: MCP clients can launch the server straight from this repository with npx -y github:YHRen/openslot-mcp. The first launch clones and builds the package (expect several seconds); after that it runs from the npx cache. To get reproducible installs, pin a tag or commit, e.g. github:YHRen/openslot-mcp#v0.1.0.
Related MCP server: ICS Calendar MCP Server
Get a calendar URL
The server uses each provider's read-only calendar feed. It does not ask for account credentials or request write access.
Provider | How to get the ICS feed | Typical allowlist host |
Outlook / Microsoft 365 | In Outlook on the web, open Calendar → View → Calendar settings → Calendar → Shared calendars. Under Publish a calendar, select a calendar and permission level, select Publish, then copy the ICS link. Choose busy-only visibility when available. Microsoft instructions |
|
iCloud Calendar | On a computer or tablet, open Calendar on iCloud.com, select the calendar's information button, turn on Public Calendar, then select Copy. Use the copied | The exact numbered host in the link, such as |
Google Calendar | On a computer, open Settings → Settings for my calendars → calendar name → Integrate calendar, then copy Secret address in iCal format. For an intentionally public calendar, its Public address in iCal format also works. Google instructions |
|
iCloud's public-calendar option makes the calendar readable to anyone who has its link; private iCloud shares are not anonymous ICS feeds and are not supported. Google Workspace administrators may disable secret iCal addresses.
Connect an MCP client
Claude Code:
claude mcp add openslot \
--env CALENDAR_ICS_URL="https://outlook.office365.com/owa/calendar/<token>/calendar.ics" \
--env CALENDAR_ALLOWED_HOSTS="outlook.office365.com" \
-- npx -y github:YHRen/openslot-mcpClaude Desktop (claude_desktop_config.json) and other JSON-configured hosts:
{
"mcpServers": {
"openslot": {
"command": "npx",
"args": ["-y", "github:YHRen/openslot-mcp"],
"env": {
"CALENDAR_ICS_URL": "https://outlook.office365.com/owa/calendar/<token>/calendar.ics",
"CALENDAR_ALLOWED_HOSTS": "outlook.office365.com"
}
}
}
}OpenAI Codex CLI (~/.codex/config.toml):
[mcp_servers.openslot]
command = "npx"
args = ["-y", "github:YHRen/openslot-mcp"]
[mcp_servers.openslot.env]
CALENDAR_ICS_URL = "https://outlook.office365.com/owa/calendar/<token>/calendar.ics"
CALENDAR_ALLOWED_HOSTS = "outlook.office365.com"Google Antigravity (agy CLI and IDE) — add to the shared ~/.gemini/config/mcp_config.json, or .agents/mcp_config.json to scope it to one workspace:
{
"mcpServers": {
"openslot": {
"command": "npx",
"args": ["-y", "github:YHRen/openslot-mcp"],
"env": {
"CALENDAR_ICS_URL": "https://outlook.office365.com/owa/calendar/<token>/calendar.ics",
"CALENDAR_ALLOWED_HOSTS": "outlook.office365.com"
}
}
}
}Other MCP hosts follow the same pattern: launch npx -y github:YHRen/openslot-mcp over stdio with the CALENDAR_* environment variables set.
Replace the sample Outlook URL with the iCloud or Google URL you copied. Set CALENDAR_ALLOWED_HOSTS to the exact hostname in that URL—for example, calendar.google.com for Google or the numbered p…-caldav.icloud.com hostname present in an iCloud link.
To combine providers, configure multiple named feeds:
[
{ "id": "work", "url": "https://outlook.office365.com/owa/calendar/<token>/calendar.ics" },
{ "id": "personal", "url": "webcal://p123-caldav.icloud.com/published/2/<token>" },
{ "id": "family", "url": "https://calendar.google.com/calendar/ical/<calendar-and-token>/basic.ics" }
]Pass the compact JSON as CALENDARS_JSON and set CALENDAR_ALLOWED_HOSTS=outlook.office365.com,p123-caldav.icloud.com,calendar.google.com.
To sanity-check your calendar URL outside a client, run the server directly — it speaks MCP over stdio, so it will sit waiting for a client; starting without an error means the configuration is valid (Ctrl-C to exit):
CALENDAR_ICS_URL="https://…/calendar.ics" npx -y github:YHRen/openslot-mcpTools
get_availability(start, end, timezone?, calendars?, includeTentative?): merged busy intervals only.find_free_slots(start, end, durationMinutes, timezone?, calendars?, includeTentative?, bufferMinutes?, workingHours?): openings matching a required duration, working hours, and optional meeting buffer.get_calendar_status(): cache/source health without event content.
Example — find_free_slots with {"start": "2026-09-01T00:00:00-04:00", "end": "2026-09-03T00:00:00-04:00", "durationMinutes": 30} returns:
{
"timezone": "America/New_York",
"start": "2026-09-01T00:00:00-04:00",
"end": "2026-09-03T00:00:00-04:00",
"durationMinutes": 30,
"slots": [
{ "start": "2026-09-01T10:00:00-04:00", "end": "2026-09-01T11:00:00-04:00", "durationMinutes": 60 }
]
}Queries use offset-bearing ISO-8601 input timestamps, output the caller's requested IANA timezone, and are capped at 90 days. All-day and floating (TZID-less) events are interpreted in the requested timezone. ICS refreshes are cached for five minutes by default and use conditional HTTP requests when the provider supports them. If a refresh fails, cached data is served with a staleCalendars field in the response and retries are backed off for 30 seconds.
Configuration
Set environment variables through your MCP host's env block (or .env for local runs):
CALENDAR_ICS_URL— a single HTTPS orwebcal://calendar feed.CALENDARS_JSON— multiple named calendars, including feeds from different providers. Takes precedence overCALENDAR_ICS_URL.CALENDAR_ALLOWED_HOSTS— optional comma-separated host allowlist; strongly recommended.CALENDAR_CACHE_TTL_SECONDS— feed cache lifetime, default300.CALENDAR_DEFAULT_TIMEZONE— IANA timezone used when a query does not specify one, defaultAmerica/New_York.
Privacy and security
A published ICS URL—including Google's Secret address—acts like a bearer credential: anyone with it may read the calendar view. Store it only in secret or local environment configuration, do not commit it, and rotate/revoke it if exposed. The server converts webcal:// links to HTTPS, rejects embedded URL credentials and non-443 ports, validates every redirect hop against the same rules and the host allowlist, restricts feed size to 5 MiB, and does not log the source URL or calendar contents.
Development
git clone https://github.com/YHRen/openslot-mcp.git
cd openslot-mcp
npm install # also compiles dist/ via the prepare script
cp .env.example .env # put your calendar URL in .env (do not commit it)
npm test # vitest, synthetic fixtures only
npm run check # typecheck
npm run build # compile to dist/
node --env-file=.env dist/index.js # run the built server
node --env-file=.env --import tsx src/index.ts # run from sourceTo point an MCP client at a local checkout instead of the npm package, use node /absolute/path/to/openslot-mcp/dist/index.js as the command.
Available Tools
3 toolsfind_free_slotsC
Find privacy-safe free intervals across configured calendars during stated working hours.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | ||
| start | Yes | ||
| timezone | No | America/New_York | |
| calendars | No | ||
| workingHours | No | ||
| bufferMinutes | No | ||
| durationMinutes | Yes | ||
| includeTentative | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | |
| slots | Yes | |
| start | Yes | |
| timezone | Yes | |
| staleCalendars | No | Calendars served from an expired cache because their last refresh failed. |
| durationMinutes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden, but it only says the operation is 'privacy-safe'. It does not explain what that means behaviorally, how tentative events are treated, whether buffers alter slots, or how conflicts are determined.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler or repetition. It is concise, though arguably too sparse given the tool's complexity, which keeps it from a perfect conciseness score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema and a detailed input schema, the tool has 8 parameters, nested objects, and two sibling tools; the one-sentence description omits usage context, sibling differentiation, and behavioral caveats. Privacy-safe is asserted without elaboration.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needed to clarify parameter semantics, but it only loosely maps to workingHours and the search window. It adds no detail on start/end exclusivity, timezone handling, calendar selection, duration, or buffer behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a concrete verb ('Find') and a specific resource ('free intervals across configured calendars during stated working hours'), giving a clear idea of the operation. It does not explicitly differentiate from similarly named siblings like get_availability, so it loses the fifth point.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to choose find_free_slots over get_availability or get_calendar_status, and no exclusions or prerequisites. Context such as how 'configured calendars' are set or why this is preferable to sibling tools is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_availabilityA
Return privacy-safe busy intervals for the configured calendars. Event names, locations, attendees, and notes are never returned.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | Exclusive ISO-8601 timestamp with an offset. | |
| start | Yes | Inclusive ISO-8601 timestamp with an offset. | |
| timezone | No | IANA timezone used in the response. | America/New_York |
| calendars | No | Optional configured calendar ids. Defaults to all calendars. | |
| includeTentative | No | Whether tentative events block time. |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | |
| busy | Yes | |
| start | Yes | |
| timezone | Yes | |
| staleCalendars | No | Calendars served from an expired cache because their last refresh failed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It reveals a key privacy behavior (never returning event names, locations, attendees, notes), but it does not clarify whether the operation is read-only, requires special permissions, or has any side effects. The privacy guarantee is valuable but incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no waste. The core purpose is front-loaded and the privacy qualifier is stated concisely. Every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema and rich parameter schema cover return values and inputs, but the description omits guidance on when to use this tool versus its siblings. Given the sibling tools exist, the lack of differentiation makes the definition less complete for selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are already documented in the schema. The description adds no parameter-specific meaning beyond the general 'configured calendars' phrase, so it does not elevate above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and resource ('busy intervals') and adds a privacy qualifier, clearly distinguishing it from find_free_slots (free intervals) and get_calendar_status (status). It explicitly states what is not returned, removing ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when busy intervals are needed, but it does not explicitly state when to prefer this tool over find_free_slots or get_calendar_status. No exclusions or alternative routing are provided, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_calendar_statusA
Return source-health and cache metadata only; it does not reveal calendar content.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| calendars | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It clearly scopes the operation to returning metadata only and explicitly excludes content, which is a transparency trait. It also implies a read-only nature (returning rather than modifying), though it doesn't explicitly state safety. For a simple status tool, this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that states the exact scope and exclusion upfront. It is concise with zero waste, front-loading the primary function ('Return source-health and cache metadata') before the caveat. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, an output schema (which presumably details the response structure), and a clear statement of what the tool returns and excludes, the description is complete. An agent can correctly invoke this tool without additional information. The exclusion of calendar content also clarifies how it differs from siblings, making the context complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is an empty object with zero parameters, so there is no parameter semantics to explain. According to the rubric, 0 params warrants a baseline score of 4, which is appropriate here as the description adds no extraneous parameter info and none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear purpose: returning source-health and cache metadata. It explicitly says what it does NOT do ('does not reveal calendar content'), which distinguishes it from sibling tools like get_availability and find_free_slots that would deal with calendar content. The verb 'Return' names a specific resource and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a 'when not to use' clue by stating it does not reveal calendar content, implying it's not for content queries. However, it does not explicitly mention alternatives or provide conditions like 'use this when you need health/cache status vs availability/slots.' An agent could infer but isn't directly guided to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
find_free_slots - First observed
get_availability - First observed
get_calendar_status
TDQS
Scored across 3 tools
Each tool serves a clearly distinct purpose: one returns busy intervals, one returns free slots, and one returns only health/cache metadata. There is no overlap in what an agent would select them for.
All three tool names follow a consistent lowercase snake_case verb_noun pattern: get_availability, find_free_slots, get_calendar_status. The pattern is predictable and readable across the set.
Three tools is a well-scoped size for a focused calendar-availability server. Each tool maps to a distinct operation an agent would need, with no redundancy or bloat.
For the stated purpose of privacy-safe availability, the server covers the essential operations: busy intervals, free slots, and source/cache health. There are no obvious dead ends or missing core capabilities within this narrow domain.
Maintenance
Related MCP Connectors
Merged free/busy, find mutual time, propose bookings with human approval. Never event contents.
GDPR-compliant calendar access for AI assistants: read, create, edit, RSVP. Google, MS 365, Apple.
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Scheduling infrastructure for AI agents across Google and Microsoft calendars.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables natural language queries to Google Calendar API for checking appointments, availability, and events. Supports flexible time ranges, timezone handling, and both service account and OAuth authentication methods.-
- AlicenseNot gradedqualityDmaintenanceEnables reading and interacting with ICS calendar feeds (e.g., Outlook, Google Calendar) with recurring event expansion, caching, and timezone support.MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to search and access public calendar data, supporting iCal, CalDAV, and Google Calendar sources with event search, details, and availability checks.-
- AlicenseAqualityAmaintenanceCalendar API purpose-built for AI agents. Exposes tools to manage agents, calendars, and events, find meeting times, run scheduling proposals, set availability rules, manage webhooks, and subscribe to iCal feeds.5491 npmApache 2.0