M365 Calendar MCP Server

M365 Calendar MCP Server

Enables AI assistants to manage Microsoft 365 and Outlook calendars through the Microsoft Graph API. It supports comprehensive event operations including listing, creating, and updating meetings, as well as finding available slots across multiple attendees.

Category
Visit Server

README

M365 Calendar MCP Server

A Model Context Protocol (MCP) server for Microsoft 365 Calendar integration. Enables AI assistants like Claude to manage your Outlook/Microsoft 365 calendar through the Microsoft Graph API.

Features

  • List Calendars - View all your calendars with permissions and ownership info
  • List Events - Browse events in a date range with full details (supports recurring events)
  • Get Event - Retrieve complete event details including body, recurrence, and attachments info
  • Create Event - Create events with attendees, Teams meetings, recurrence, reminders, and more
  • Update Event - Modify any event property (partial updates supported)
  • Delete Event - Remove events with automatic cancellation notices
  • Respond to Events - Accept, tentatively accept, or decline meeting invitations
  • Find Meeting Times - Find available meeting slots across multiple attendees

Prerequisites

  • Node.js >= 18
  • A Microsoft 365 account (work, school, or personal)
  • An Azure AD app registration

Azure AD App Setup

  1. Go to the Azure Portal > Azure Active Directory > App registrations
  2. Click New registration
    • Name: M365 Calendar MCP
    • Supported account types: Choose based on your needs (single tenant or multi-tenant)
    • Redirect URI: Leave blank (we use device code flow)
  3. After creation, note the Application (client) ID and Directory (tenant) ID
  4. Go to API permissions > Add a permission > Microsoft Graph > Delegated permissions
  5. Add the following permissions:
    • Calendars.ReadWrite
    • Calendars.Read
    • User.Read
  6. Go to Authentication > Enable Allow public client flows (required for device code flow)

Installation

npm install
npm run build

Configuration

Set the following environment variables:

# Required: Your Azure AD app client ID
export M365_CLIENT_ID="your-client-id-here"

# Optional: Your Azure AD tenant ID (defaults to "common" for multi-tenant)
export M365_TENANT_ID="your-tenant-id-here"

# Optional: Custom token cache path
export M365_CALENDAR_TOKEN_CACHE_PATH="/path/to/token-cache.json"

Authentication

Before using the MCP server, authenticate with your Microsoft account:

# Login via device code flow
npm run login
# or
node dist/index.js --login

This will display a URL and code. Open the URL in your browser, enter the code, and sign in with your Microsoft account.

Other auth commands:

# Check authentication status
node dist/index.js --check-auth

# Logout and clear cached tokens
npm run logout

Usage with Claude Desktop

Add to your Claude Desktop configuration (claude_desktop_config.json):

{
  "mcpServers": {
    "m365calendar": {
      "command": "node",
      "args": ["/path/to/m365calender-mcp/dist/index.js"],
      "env": {
        "M365_CLIENT_ID": "your-client-id-here",
        "M365_TENANT_ID": "your-tenant-id-here"
      }
    }
  }
}

Usage with Claude Code

claude mcp add m365calendar -- node /path/to/m365calender-mcp/dist/index.js

Make sure M365_CLIENT_ID is set in your environment.

Available Tools

list-calendars

Lists all calendars accessible to the authenticated user, including shared calendars. Returns each calendar's name, ID, color, default status, edit/share permissions, and owner information.

This is a good starting point to discover calendar IDs. The id returned here can be passed as the calendarId parameter to any other tool. If you omit calendarId in other tools, they default to the user's primary calendar.

Parameters: None

Returns: Array of calendars with id, name, color, isDefault, canEdit, canShare, and owner.


list-events

Lists calendar events within a date/time range. Uses Microsoft's calendarView endpoint, which automatically expands recurring event series into their individual instances within the range. Results are sorted by start time.

Use this tool to answer questions like "What's on my calendar this week?" or "Do I have any meetings tomorrow afternoon?" Follow up with get-event on any event ID to retrieve full details.

Parameters:

Param Required Type Description
startDateTime Yes string Start of the time range in ISO 8601 format (e.g., 2025-03-01T00:00:00Z)
endDateTime Yes string End of the time range in ISO 8601 format (e.g., 2025-03-31T23:59:59Z)
calendarId No string Calendar ID from list-calendars. Defaults to the primary calendar.
top No number Maximum number of events to return (default: 25, max: 100)

Returns: Array of event summaries including subject, start/end times with time zones, location, organizer, attendees with response status, isAllDay, isCancelled, isOnlineMeeting, onlineMeetingUrl, webLink, showAs, importance, isRecurring, and your own myResponse.

Tip: All date/time values should include a timezone offset or use UTC (Z suffix). The response includes time zone information for each event so you can display times correctly.


get-event

Retrieves the full details of a single calendar event by its ID. This returns significantly more data than list-events, including the full HTML body, all locations, online meeting join details, recurrence patterns, categories, attachment indicators, and audit timestamps.

Use this after list-events when you need the complete body content, the Teams join URL, or the recurrence configuration.

Parameters:

Param Required Type Description
eventId Yes string The event ID (obtained from list-events or create-event)
calendarId No string Calendar ID. Defaults to the primary calendar.

Returns: Full event object including body (HTML), locations[], onlineMeeting (join URL, conference ID, toll numbers), recurrence (pattern + range), categories[], hasAttachments, seriesMasterId, type (singleInstance/occurrence/exception/seriesMaster), createdDateTime, and lastModifiedDateTime.


create-event

Creates a new calendar event with full control over all properties. Supports plain events, all-day events, events with attendees (which automatically send invitations), Teams online meetings, recurring events, and custom reminders.

After creating an event, the full created event object is returned, including the server-assigned id and any auto-generated fields like the Teams meeting URL.

Parameters:

Param Required Type Default Description
subject Yes string - Event title
startDateTime Yes string - Start in ISO 8601 (e.g., 2025-03-15T09:00:00)
endDateTime Yes string - End in ISO 8601 (e.g., 2025-03-15T10:00:00)
body No string - Event description (HTML supported)
startTimeZone No string UTC IANA time zone (e.g., America/New_York, Europe/London)
endTimeZone No string UTC IANA time zone for end
location No string - Location display name (e.g., "Conference Room A")
attendees No array - List of { email, name?, type? } (type: required/optional/resource)
isAllDay No boolean false All-day event (start/end should be date-only, e.g., 2025-03-15T00:00:00)
isOnlineMeeting No boolean false Set true to auto-create a Teams meeting with join link
showAs No enum busy free, tentative, busy, oof, workingElsewhere, unknown
importance No enum normal low, normal, high
sensitivity No enum normal normal, personal, private, confidential
categories No string[] - Color category labels
reminderMinutesBeforeStart No number 15 Reminder timing in minutes
calendarId No string - Target calendar ID. Defaults to the primary calendar.
recurrence No object - Recurrence pattern and range (see below)

Recurrence object structure:

{
  "pattern": {
    "type": "weekly",
    "interval": 1,
    "daysOfWeek": ["monday", "wednesday", "friday"]
  },
  "range": {
    "type": "endDate",
    "startDate": "2025-03-15",
    "endDate": "2025-06-15"
  }
}
  • Pattern types: daily, weekly, absoluteMonthly, relativeMonthly, absoluteYearly, relativeYearly
  • Range types: endDate (with endDate), noEnd (runs forever), numbered (with numberOfOccurrences)
  • For weekly: use daysOfWeek. For absoluteMonthly: use dayOfMonth. For relativeMonthly: use daysOfWeek + index (first, second, third, fourth, last).

Tip: When adding attendees, Microsoft automatically sends invitation emails. Set isOnlineMeeting: true to include a Teams join link in the invitation.


update-event

Updates an existing calendar event using partial update (PATCH) semantics. Only the fields you provide are modified; all other fields remain unchanged. This is safe to use when you only need to change one property (e.g., updating just the subject or moving the time).

If the event has attendees, Microsoft sends update notifications automatically when relevant fields change (time, location, etc.).

Parameters:

Param Required Type Description
eventId Yes string The ID of the event to update
calendarId No string Calendar ID. Defaults to the primary calendar.

All other parameters are the same as create-event (subject, body, startDateTime, endDateTime, location, attendees, etc.) but all are optional. Only include the fields you want to change.

Returns: The full updated event object.

Tip: To reschedule, provide both startDateTime and endDateTime together. To update attendees, provide the complete attendee list (it replaces the existing list, not appends).


delete-event

Permanently deletes a calendar event. If the authenticated user is the organizer and the event has attendees, Microsoft automatically sends cancellation notices to all attendees.

This action cannot be undone. The event is moved to the Deleted Items folder.

Parameters:

Param Required Type Description
eventId Yes string The ID of the event to delete
calendarId No string Calendar ID. Defaults to the primary calendar.

Returns: Confirmation message.


respond-event

Responds to a calendar event invitation that someone else organized. You can accept, tentatively accept, or decline. Optionally include a message visible to the organizer, and control whether a response email is actually sent.

Use this after finding an event via list-events where your myResponse is none or notResponded.

Parameters:

Param Required Type Default Description
eventId Yes string - The ID of the event to respond to
response Yes enum - accept, tentativelyAccept, or decline
comment No string - Message to include with the response (visible to the organizer)
sendResponse No boolean true Set false to update your status silently without notifying the organizer

Returns: Confirmation message.


find-meeting-times

Finds available meeting times for a group of attendees using Microsoft's scheduling intelligence. This queries each attendee's calendar availability and suggests optimal time slots where everyone (or the most people) can meet.

This is particularly useful for scheduling meetings with multiple people without manually checking each person's calendar. Use the suggested time slots with create-event to book the meeting.

Parameters:

Param Required Type Default Description
attendees Yes array - List of { email, name?, type? } to check availability for
startDateTime Yes string - Start of the search window in ISO 8601
endDateTime Yes string - End of the search window in ISO 8601
durationMinutes No number 30 Desired meeting length in minutes
maxCandidates No number 5 Maximum number of time suggestions to return
isOrganizerOptional No boolean false If true, suggestions may include times when the organizer is busy
meetingTimeZone No string UTC Time zone for the suggestions (e.g., America/Chicago)

Returns: Meeting time suggestions from Microsoft's scheduling engine, including the proposed time slots, attendee availability for each slot, and a confidence score.

Tip: The search window should be at least a few days wide to get good results. The attendees must be in the same Microsoft 365 organization (or federated) for availability lookup to work.


Typical Workflow

  1. list-calendars - Discover available calendars and their IDs
  2. list-events - Browse events in a date range on a specific calendar
  3. get-event - Drill into a specific event for full details (body, Teams link, recurrence)
  4. find-meeting-times - Find a slot that works for everyone, then...
  5. create-event - Book the meeting with attendees and a Teams link
  6. update-event - Reschedule or modify the event later
  7. respond-event - Accept or decline meetings others have invited you to
  8. delete-event - Cancel a meeting you organized

Development

# Install dependencies
npm install

# Build
npm run build

# Run in development mode
npm run dev

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured