Calendar MCP Server
A unified Model Context Protocol server for managing calendars across Google Calendar, Microsoft 365, and Exchange On-Premises. It provides tools for scheduling, conflict detection, and event management across multiple provider accounts using a consistent data format.
README
Calendar MCP Server
A Model Context Protocol (MCP) server providing unified calendar management across Google Calendar, Microsoft 365, and Exchange On-Premises.
Table of Contents
- Features
- Quick Start
- Installation
- Configuration
- Claude Code Integration
- Tools Reference
- Resources Reference
- Prompts Reference
- Usage Examples
- Troubleshooting
- Architecture
Features
- Multi-Provider Support: Connect to Google Calendar, Microsoft 365 (Graph API), and Exchange On-Premises (EWS)
- Multiple Accounts: Support for multiple accounts per provider (e.g., 2+ Exchange accounts)
- 12 MCP Tools: Comprehensive calendar operations including CRUD, free/busy, conflict detection, and sync helpers
- 4 MCP Resources: Quick access to calendar summaries, today's events, weekly schedule, and upcoming events
- 4 MCP Prompts: Pre-built templates for scheduling meetings and daily briefings
- NTLM Authentication: Full support for Exchange NTLM authentication via
@ewsjs/xhr - Unified Data Model: Consistent event format across all providers
- Timezone Support: Configurable timezone for all operations
Quick Start
# 1. Clone/navigate to the project
cd calendar-mcp
# 2. Install dependencies
npm install
# 3. Build the project
npm run build
# 4. Configure environment variables (see Configuration section)
cp .env.example .env
# Edit .env with your credentials
# 5. Test the server
node dist/index.js
Installation
Prerequisites
- Node.js 18+
- npm or yarn
- Access to at least one calendar provider (Google, Microsoft 365, or Exchange)
Install Dependencies
npm install
Build
npm run build
This compiles TypeScript to JavaScript in the dist/ directory.
Configuration
The server uses environment variables for configuration. Create a .env file in the project root or pass environment variables directly.
Environment Variables
Server Settings
| Variable | Description | Default |
|---|---|---|
MCP_SERVER_NAME |
Server name for identification | calendar-mcp |
MCP_SERVER_VERSION |
Server version | 1.0.0 |
LOG_LEVEL |
Logging level: debug, info, warn, error |
info |
DEFAULT_TIMEZONE |
IANA timezone for all operations | UTC |
DEFAULT_WORKING_HOURS_START |
Working hours start (HH:MM) | 09:00 |
DEFAULT_WORKING_HOURS_END |
Working hours end (HH:MM) | 18:00 |
DEFAULT_WORKING_DAYS |
Working days (comma-separated) | monday,tuesday,wednesday,thursday,friday |
Request Settings
| Variable | Description | Default |
|---|---|---|
REQUEST_TIMEOUT |
Request timeout in milliseconds | 30000 |
MAX_RETRIES |
Maximum retry attempts | 3 |
RETRY_DELAY_MS |
Delay between retries | 1000 |
RATE_LIMIT_REQUESTS_PER_MINUTE |
Rate limiting | 60 |
Google Calendar Setup
| Variable | Description | Required |
|---|---|---|
GOOGLE_ENABLED |
Enable Google Calendar | Yes |
GOOGLE_PROVIDER_ID |
Unique identifier for this account | Yes |
GOOGLE_PROVIDER_NAME |
Display name | Yes |
GOOGLE_EMAIL |
Google account email | Yes |
GOOGLE_CLIENT_ID |
OAuth client ID from Google Cloud Console | Yes |
GOOGLE_CLIENT_SECRET |
OAuth client secret | Yes |
GOOGLE_REDIRECT_URI |
OAuth redirect URI | Yes |
GOOGLE_ACCESS_TOKEN |
Pre-authorized access token | Yes |
GOOGLE_REFRESH_TOKEN |
Refresh token for token renewal | Yes |
GOOGLE_TOKEN_EXPIRY |
Token expiry (ISO 8601) | No |
Getting Google Credentials
- Go to Google Cloud Console
- Create a new project or select existing
- Enable the Google Calendar API
- Go to Credentials → Create Credentials → OAuth client ID
- Configure consent screen if prompted
- Select Desktop app or Web application
- Copy Client ID and Client Secret
- Use OAuth Playground to get tokens:
- Select
https://www.googleapis.com/auth/calendar - Authorize and get access/refresh tokens
- Select
Example Google Configuration
GOOGLE_ENABLED=true
GOOGLE_PROVIDER_ID=google-personal
GOOGLE_PROVIDER_NAME=Personal Google Calendar
GOOGLE_EMAIL=yourname@gmail.com
GOOGLE_CLIENT_ID=123456789.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxx
GOOGLE_REDIRECT_URI=http://localhost:3000/oauth/google/callback
GOOGLE_ACCESS_TOKEN=ya29.xxxxx
GOOGLE_REFRESH_TOKEN=1//xxxxx
Microsoft 365 Setup
| Variable | Description | Required |
|---|---|---|
MICROSOFT_ENABLED |
Enable Microsoft 365 | Yes |
MICROSOFT_PROVIDER_ID |
Unique identifier for this account | Yes |
MICROSOFT_PROVIDER_NAME |
Display name | Yes |
MICROSOFT_EMAIL |
Microsoft account email | Yes |
MICROSOFT_CLIENT_ID |
Azure AD app client ID | Yes |
MICROSOFT_CLIENT_SECRET |
Azure AD app client secret | Yes |
MICROSOFT_TENANT_ID |
Azure tenant ID (common, organizations, or specific) |
Yes |
MICROSOFT_REDIRECT_URI |
OAuth redirect URI | Yes |
MICROSOFT_ACCESS_TOKEN |
Pre-authorized access token | Yes |
MICROSOFT_REFRESH_TOKEN |
Refresh token | Yes |
MICROSOFT_TOKEN_EXPIRY |
Token expiry (ISO 8601) | No |
Getting Microsoft Credentials
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click New registration
- Add redirect URI
- Go to Certificates & secrets → New client secret
- Go to API permissions → Add:
Calendars.ReadWriteUser.Read
- Grant admin consent if required
- Use Graph Explorer to test
Example Microsoft Configuration
MICROSOFT_ENABLED=true
MICROSOFT_PROVIDER_ID=microsoft-work
MICROSOFT_PROVIDER_NAME=Work Microsoft 365
MICROSOFT_EMAIL=yourname@company.com
MICROSOFT_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MICROSOFT_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxx
MICROSOFT_TENANT_ID=common
MICROSOFT_REDIRECT_URI=http://localhost:3000/oauth/microsoft/callback
MICROSOFT_ACCESS_TOKEN=eyJ0eXAiOiJKV1QiLCJ...
MICROSOFT_REFRESH_TOKEN=0.xxxxx
Exchange On-Premises Setup
| Variable | Description | Required |
|---|---|---|
EXCHANGE_ENABLED |
Enable Exchange provider | Yes |
EXCHANGE_PROVIDER_ID |
Unique identifier for this account | Yes |
EXCHANGE_PROVIDER_NAME |
Display name | Yes |
EXCHANGE_EMAIL |
Exchange email address | Yes |
EXCHANGE_EWS_URL |
EWS endpoint URL | Yes |
EXCHANGE_AUTH_METHOD |
Authentication: ntlm, basic, or oauth |
Yes |
For NTLM Authentication (most common for on-premises)
| Variable | Description | Required |
|---|---|---|
EXCHANGE_USERNAME |
Username (without domain) | Yes |
EXCHANGE_PASSWORD |
Password (quote if special chars) | Yes |
EXCHANGE_DOMAIN |
Active Directory domain | Yes |
For Basic Authentication
| Variable | Description | Required |
|---|---|---|
EXCHANGE_USERNAME |
Full username or email | Yes |
EXCHANGE_PASSWORD |
Password | Yes |
For OAuth Authentication (Hybrid Exchange)
| Variable | Description | Required |
|---|---|---|
EXCHANGE_OAUTH_CLIENT_ID |
Azure AD app ID | Yes |
EXCHANGE_OAUTH_CLIENT_SECRET |
Client secret | Yes |
EXCHANGE_OAUTH_TENANT_ID |
Azure tenant ID | Yes |
EXCHANGE_OAUTH_ACCESS_TOKEN |
Access token | Yes |
EXCHANGE_OAUTH_REFRESH_TOKEN |
Refresh token | No |
Finding Your EWS URL
- Open Outlook on desktop
- Hold Ctrl and right-click the Outlook icon in system tray
- Select "Test E-mail AutoConfiguration"
- Look for the EWS URL (typically
https://mail.company.com/EWS/Exchange.asmx)
Or ask your Exchange administrator.
Example Exchange Configuration (NTLM)
EXCHANGE_ENABLED=true
EXCHANGE_PROVIDER_ID=exchange-work
EXCHANGE_PROVIDER_NAME=Work Exchange
EXCHANGE_EMAIL=yourname@company.com
EXCHANGE_EWS_URL=https://mail.company.com/EWS/Exchange.asmx
EXCHANGE_AUTH_METHOD=ntlm
EXCHANGE_USERNAME="yourname"
EXCHANGE_PASSWORD="YourP@ssword!"
EXCHANGE_DOMAIN="COMPANYDOMAIN"
Note: If your password contains special characters like
!,@,$, wrap it in quotes.
Multiple Exchange Accounts
To configure additional Exchange accounts, use the EXCHANGE_2_, EXCHANGE_3_, etc. prefixes:
# First Exchange Account
EXCHANGE_ENABLED=true
EXCHANGE_PROVIDER_ID=exchange-account1
EXCHANGE_PROVIDER_NAME=Account 1
EXCHANGE_EMAIL=user1@company.com
EXCHANGE_EWS_URL=https://mail.company.com/EWS/Exchange.asmx
EXCHANGE_AUTH_METHOD=ntlm
EXCHANGE_USERNAME="user1"
EXCHANGE_PASSWORD="password1"
EXCHANGE_DOMAIN="DOMAIN"
# Second Exchange Account
EXCHANGE_2_ENABLED=true
EXCHANGE_2_PROVIDER_ID=exchange-account2
EXCHANGE_2_PROVIDER_NAME=Account 2
EXCHANGE_2_EMAIL=user2@company.com
EXCHANGE_2_EWS_URL=https://mail.company.com/EWS/Exchange.asmx
EXCHANGE_2_AUTH_METHOD=ntlm
EXCHANGE_2_USERNAME="user2"
EXCHANGE_2_PASSWORD="password2"
EXCHANGE_2_DOMAIN="DOMAIN"
# Third Exchange Account (if needed)
EXCHANGE_3_ENABLED=true
# ... and so on
Claude Code Integration
Method 1: Using /mcp Command (Recommended)
- Open Claude Code in your project directory
- Run
/mcp - Select "Add Server"
- Configure with:
{
"type": "stdio",
"command": "node",
"args": ["/full/path/to/calendar-mcp/dist/index.js"],
"env": {
"DEFAULT_TIMEZONE": "Your/Timezone",
"EXCHANGE_ENABLED": "true",
"EXCHANGE_PROVIDER_ID": "your-exchange",
"EXCHANGE_PROVIDER_NAME": "Your Exchange",
"EXCHANGE_EMAIL": "your@email.com",
"EXCHANGE_EWS_URL": "https://mail.company.com/EWS/Exchange.asmx",
"EXCHANGE_AUTH_METHOD": "ntlm",
"EXCHANGE_USERNAME": "username",
"EXCHANGE_PASSWORD": "password",
"EXCHANGE_DOMAIN": "DOMAIN"
}
}
- Restart Claude Code or run
/mcpand reconnect
Method 2: Edit ~/.claude.json Directly
Add to the mcpServers object in your project's configuration:
{
"projects": {
"/path/to/your/project": {
"mcpServers": {
"calendar": {
"type": "stdio",
"command": "node",
"args": ["/full/path/to/calendar-mcp/dist/index.js"],
"env": {
"DEFAULT_TIMEZONE": "Asia/Baku",
"EXCHANGE_ENABLED": "true",
"EXCHANGE_PROVIDER_ID": "exchange-work",
"EXCHANGE_PROVIDER_NAME": "Work Calendar",
"EXCHANGE_EMAIL": "you@company.com",
"EXCHANGE_EWS_URL": "https://mail.company.com/EWS/Exchange.asmx",
"EXCHANGE_AUTH_METHOD": "ntlm",
"EXCHANGE_USERNAME": "username",
"EXCHANGE_PASSWORD": "password",
"EXCHANGE_DOMAIN": "DOMAIN"
}
}
}
}
}
}
Verify Connection
After configuring, test with:
- Ask Claude: "List my calendars"
- Or: "What meetings do I have today?"
Tools Reference
Core Calendar Operations
list_calendars
List all available calendars across connected providers.
| Parameter | Type | Description |
|---|---|---|
provider |
string | Filter by provider: google, microsoft, exchange, or all (default: all) |
Example:
List all my calendars
list_events
List events within a time range with optional filters.
| Parameter | Type | Required | Description |
|---|---|---|---|
startTime |
string | Yes | Start of time range (ISO 8601) |
endTime |
string | Yes | End of time range (ISO 8601) |
providers |
string[] | No | Filter to specific providers |
calendarIds |
string[] | No | Filter to specific calendar IDs |
searchQuery |
string | No | Text search in subject/body |
maxResults |
number | No | Maximum results (default: 100, max: 500) |
orderBy |
string | No | Sort order: start or updated |
expandRecurring |
boolean | No | Expand recurring events (default: true) |
Example:
Show me all my meetings for tomorrow
What events do I have this week?
Search my calendar for "standup" meetings
get_event
Get detailed information about a specific event.
| Parameter | Type | Required | Description |
|---|---|---|---|
eventId |
string | Yes | The event ID |
provider |
string | Yes | Provider: google, microsoft, or exchange |
calendarId |
string | No | Calendar ID (required for some providers) |
Example:
Get details for event ID AAMkADA3OWE...
create_event
Create a new calendar event.
| Parameter | Type | Required | Description |
|---|---|---|---|
provider |
string | Yes | Provider to create event on |
subject |
string | Yes | Event title |
startTime |
string | Yes | Start time (ISO 8601) |
endTime |
string | Yes | End time (ISO 8601) |
calendarId |
string | No | Target calendar ID |
body |
string | No | Event description |
bodyType |
string | No | Body type: text or html |
location |
string | No | Physical location |
attendees |
array | No | List of attendees with email and type |
isAllDay |
boolean | No | All-day event |
recurrence |
object | No | Recurrence settings |
reminderMinutes |
number | No | Reminder before event |
createOnlineMeeting |
boolean | No | Create Teams/Meet link |
onlineMeetingProvider |
string | No | teams or meet |
sensitivity |
string | No | normal, personal, private, confidential |
showAs |
string | No | free, busy, tentative, oof, workingElsewhere |
Example:
Create a meeting called "Project Review" tomorrow at 2pm for 1 hour
Schedule a lunch event next Monday from 12-1pm at "Cafe Downtown"
Create a weekly team standup every Monday at 9am
update_event
Update an existing event.
| Parameter | Type | Required | Description |
|---|---|---|---|
eventId |
string | Yes | Event ID to update |
provider |
string | Yes | Provider the event belongs to |
subject |
string | No | New title |
startTime |
string | No | New start time |
endTime |
string | No | New end time |
body |
string | No | New description |
location |
string | No | New location |
attendees |
array | No | Updated attendee list |
updateScope |
string | No | For recurring: single, thisAndFuture, all |
sendUpdates |
boolean | No | Notify attendees (default: true) |
Example:
Move my 2pm meeting to 3pm
Change the location of event AAMk... to "Room 201"
delete_event
Delete a calendar event.
| Parameter | Type | Required | Description |
|---|---|---|---|
eventId |
string | Yes | Event ID to delete |
provider |
string | Yes | Provider the event belongs to |
calendarId |
string | No | Calendar ID |
deleteScope |
string | No | For recurring: single, thisAndFuture, all |
sendCancellation |
boolean | No | Send cancellation notices |
Example:
Delete my 3pm meeting
Cancel all instances of my recurring standup
Availability & Scheduling
get_free_busy
Get aggregated availability across all calendars.
| Parameter | Type | Required | Description |
|---|---|---|---|
startTime |
string | Yes | Start of time range (ISO 8601) |
endTime |
string | Yes | End of time range (ISO 8601) |
providers |
string[] | No | Filter to specific providers |
calendarIds |
string[] | No | Filter to specific calendars |
slotDuration |
number | No | Minimum free slot duration in minutes |
workingHoursOnly |
boolean | No | Only consider working hours |
workingHours |
object | No | Custom working hours config |
Example:
When am I free tomorrow?
Find me a 1-hour free slot this week
Show my availability for the next 3 days during working hours
check_conflicts
Check if a proposed time slot conflicts with existing events.
| Parameter | Type | Required | Description |
|---|---|---|---|
startTime |
string | Yes | Proposed start time (ISO 8601) |
endTime |
string | Yes | Proposed end time (ISO 8601) |
excludeEventId |
string | No | Event ID to exclude (for rescheduling) |
excludeProvider |
string | No | Provider of excluded event |
Example:
Do I have any conflicts tomorrow at 2pm?
Check if I can schedule a meeting on Friday from 10-11am
respond_to_invite
Respond to a meeting invitation.
| Parameter | Type | Required | Description |
|---|---|---|---|
eventId |
string | Yes | Event ID |
provider |
string | Yes | Provider the event belongs to |
response |
string | Yes | Response: accepted, declined, tentative |
calendarId |
string | No | Calendar ID |
message |
string | No | Optional response message |
Example:
Accept the meeting invite for AAMk...
Decline the team lunch with message "I have a conflict"
Tentatively accept the project review
Sync Helpers
find_matching_events
Find matching events between two calendars.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_provider |
string | Yes | Source calendar provider |
target_provider |
string | Yes | Target calendar provider |
start_time |
string | Yes | Start of time range |
end_time |
string | Yes | End of time range |
source_calendar_id |
string | No | Source calendar ID |
target_calendar_id |
string | No | Target calendar ID |
min_confidence |
string | No | Match confidence: high, medium, low |
Example:
Find events that exist in both my Exchange calendars
Check for duplicates between Google and Microsoft
copy_event
Copy an event from one calendar to another.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_event_id |
string | Yes | Event ID to copy |
source_provider |
string | Yes | Source provider |
target_provider |
string | Yes | Target provider |
source_calendar_id |
string | No | Source calendar ID |
target_calendar_id |
string | No | Target calendar ID |
include_attendees |
boolean | No | Include attendees (default: false) |
include_body |
boolean | No | Include description (default: true) |
Example:
Copy event AAMk... from Exchange to Google Calendar
compare_calendars
Compare two calendars to find matching events, differences, and missing events.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_provider |
string | Yes | Source calendar provider |
target_provider |
string | Yes | Target calendar provider |
start_time |
string | Yes | Start of time range |
end_time |
string | Yes | End of time range |
source_calendar_id |
string | No | Source calendar ID |
target_calendar_id |
string | No | Target calendar ID |
Example:
Compare my two Exchange calendars for this week
What events are only in my first calendar but not the second?
Resources Reference
MCP Resources provide quick access to calendar data.
| URI | Description |
|---|---|
calendar://summary |
Overview of all calendars with event counts |
calendar://today |
Today's events across all calendars |
calendar://week |
This week's events grouped by day |
calendar://next/{count} |
Next N upcoming events (e.g., calendar://next/5) |
Usage in Claude Code:
@calendar://today
Show me @calendar://summary
What's in @calendar://week
Prompts Reference
MCP Prompts are pre-built conversation templates.
schedule-meeting
Interactive prompt to schedule a new meeting.
Arguments:
title: Meeting titleduration: Duration (e.g., "30 minutes", "1 hour")attendees: Comma-separated email addressesnotes: Additional notes
daily-briefing
Generate a briefing of today's schedule.
Arguments:
timezone: Override default timezoneinclude_details: Include full event details (true/false)
find-meeting-time
Find available time slots for a meeting.
Arguments:
duration: Required meeting durationwithin_days: Number of days to searchattendees: Participants to check availability for
sync-calendars
Compare and sync events between calendars.
Arguments:
source_provider: Source calendar providertarget_provider: Target calendar provideraction:compare,copy_missing, orfull_sync
Usage Examples
Daily Workflow
# Morning check
"What's on my calendar today?"
# Quick view
"Show me my next 5 meetings"
# Check availability
"Am I free at 3pm today?"
# Schedule meeting
"Schedule a 30-minute call with john@company.com tomorrow at 2pm"
Finding Time
"When am I free this week for a 1-hour meeting?"
"Find me an open slot tomorrow afternoon"
"Do I have any conflicts if I book 10-11am on Friday?"
Managing Events
"Move my 2pm meeting to 3pm"
"Cancel tomorrow's standup"
"Add 'Conference Room A' as the location for my next meeting"
Multi-Calendar
"Compare my two Exchange calendars for this week"
"List all calendars I have access to"
"Copy the project review from my work calendar to personal"
Troubleshooting
Common Issues
"No calendars found"
Cause: Environment variables not loaded properly.
Solutions:
- Verify
EXCHANGE_ENABLED=trueis set - Check that all required variables are present
- For Claude Code: ensure
envobject in MCP config has all variables - Restart Claude Code after config changes
"401 Unauthorized" (Exchange NTLM)
Cause: Invalid credentials or wrong username format.
Solutions:
- Use just the username, not
domain\userformat - Put the domain in
EXCHANGE_DOMAINseparately - Quote passwords with special characters:
EXCHANGE_PASSWORD="P@ss!word" - Verify credentials work by visiting EWS URL in browser
"Failed to connect to Exchange"
Cause: Network or certificate issues.
Solutions:
- Verify EWS URL is accessible from your network
- Check if VPN is required
- For self-signed certs, you may need to set
NODE_TLS_REJECT_UNAUTHORIZED=0
"Property not loaded" errors
Cause: EWS doesn't load all properties by default.
Solution: This is handled internally with safe property access. If you see this, update to latest version.
Google/Microsoft token expired
Cause: Access tokens have limited lifetime.
Solution:
- Get new tokens using OAuth flow
- Update
ACCESS_TOKENandTOKEN_EXPIRYin config - Implement token refresh in your setup
Debug Mode
Run with debug logging:
LOG_LEVEL=debug node dist/index.js
Testing Connection
Test Exchange connection directly:
# Set environment variables
export EXCHANGE_ENABLED=true
export EXCHANGE_EWS_URL=https://mail.company.com/EWS/Exchange.asmx
export EXCHANGE_AUTH_METHOD=ntlm
export EXCHANGE_USERNAME=youruser
export EXCHANGE_PASSWORD='yourpassword'
export EXCHANGE_DOMAIN=YOURDOMAIN
# Run test
node -e "
const { loadConfig, hasConfiguredProviders } = require('./dist/utils/config.js');
console.log('Has providers:', hasConfiguredProviders());
console.log('Config:', JSON.stringify(loadConfig(), null, 2));
"
Architecture
calendar-mcp/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── types/
│ │ └── index.ts # TypeScript interfaces
│ ├── providers/
│ │ ├── base.ts # Base provider interface
│ │ ├── google/
│ │ │ ├── index.ts # Google Calendar provider
│ │ │ └── client.ts # Google API client
│ │ ├── microsoft/
│ │ │ ├── index.ts # Microsoft 365 provider
│ │ │ └── client.ts # Graph API client
│ │ └── exchange/
│ │ ├── index.ts # Exchange EWS provider
│ │ ├── client.ts # EWS client with NTLM support
│ │ └── auth.ts # Authentication manager
│ ├── services/
│ │ ├── calendar-service.ts # Multi-provider orchestration
│ │ └── sync-service.ts # Calendar sync logic
│ ├── tools/
│ │ ├── index.ts # Tool registration
│ │ ├── list-calendars.ts
│ │ ├── list-events.ts
│ │ ├── get-event.ts
│ │ ├── create-event.ts
│ │ ├── update-event.ts
│ │ ├── delete-event.ts
│ │ ├── get-free-busy.ts
│ │ ├── check-conflicts.ts
│ │ ├── respond-to-invite.ts
│ │ ├── find-matching-events.ts
│ │ ├── copy-event.ts
│ │ └── compare-calendars.ts
│ ├── resources/
│ │ └── index.ts # MCP resources
│ ├── prompts/
│ │ └── index.ts # MCP prompts
│ └── utils/
│ ├── config.ts # Configuration loader
│ ├── date.ts # Date utilities
│ └── formatting.ts # Output formatting
├── dist/ # Compiled JavaScript
├── .env # Environment configuration
├── .env.example # Example configuration
├── package.json
├── tsconfig.json
└── README.md
Key Dependencies
| Package | Purpose |
|---|---|
@modelcontextprotocol/sdk |
MCP server implementation |
ews-javascript-api |
Exchange Web Services client |
@ewsjs/xhr |
NTLM authentication for EWS |
@microsoft/microsoft-graph-client |
Microsoft Graph API |
googleapis |
Google Calendar API |
dotenv |
Environment variable loading |
date-fns |
Date manipulation |
date-fns-tz |
Timezone handling |
License
MIT
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm test - Submit a pull request
Support
For issues and feature requests, please open a GitHub issue.
Recommended Servers
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.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
E2B
Using MCP to run code via e2b.