M365 MCP
Minimal, powerful MCP server for Microsoft Graph API (Outlook, Calendar, OneDrive)
Installation
npx m365-mcpAsk AI about M365 MCP
Powered by Claude Β· Grounded in docs
I know everything about M365 MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
M365 MCP
Powerful MCP server for Microsoft Graph API - a complete AI assistant toolkit for Outlook, Calendar, OneDrive, and Contacts.
Features
- Email Management: Read, send, reply, manage attachments, organize folders
- Calendar Intelligence: Create, update, check availability, respond to invitations
- OneDrive Files: Upload, download, browse with pagination
- Contacts: Search and list contacts from your address book
- Multi-Account: Support for multiple Microsoft accounts (personal, work, school)
- Unified Search: Search across emails, files, events, and people
- β‘ High-Performance Caching: AES-256 encrypted cache with 300x performance improvement
- π Security & Compliance: GDPR and HIPAA compliant data encryption at rest
Quick Start
π See QUICKSTART.md for complete installation and setup guide.
TL;DR
# 1. Install
git clone https://github.com/robin-collins/m365-mcp.git
cd m365-mcp && uv sync
# 2. Configure (use .env.example template)
cp .env.example .env
# Edit .env with your M365_MCP_CLIENT_ID
# 3. Authenticate
uv run authenticate.py
# 4. Run
uv run m365-mcp
Claude Desktop
# Add M365 MCP server (replace with your Azure app ID)
claude mcp add m365-mcp -e M365_MCP_CLIENT_ID=your-app-id-here -- uvx --from git+https://github.com/robin-collins/m365-mcp.git m365-mcp
# Start Claude Desktop
claude
Usage Examples
# Email examples
> read my latest emails with full content
> reply to the email from John saying "I'll review this today"
> send an email with attachment to alice@example.com
# Calendar examples
> show my calendar for next week
> check if I'm free tomorrow at 2pm
> create a meeting with Bob next Monday at 10am
# File examples
> list files in my OneDrive
> upload this report to OneDrive
> search for "project proposal" across all my files
# Multi-account
> list all my Microsoft accounts
> send email from my work account
Available Tools
Email Tools
list_emails- List emails with optional body contentget_email- Get specific email with attachmentscreate_email_draft- Create email draft with attachments supportsend_email- Send email immediately with CC/BCC and attachmentsreply_to_email- Reply maintaining thread contextreply_all_email- Reply to all recipients in threadupdate_email- Mark emails as read/unreadmove_email- Move emails between foldersdelete_email- Delete emailsget_attachment- Get email attachment contentsearch_emails- Search emails by query
Calendar Tools
list_events- List calendar events with detailsget_event- Get specific event detailscreate_event- Create events with location and attendeesupdate_event- Reschedule or modify eventsdelete_event- Cancel eventsrespond_event- Accept/decline/tentative response to invitationscheck_availability- Check free/busy times for schedulingsearch_events- Search calendar events
Contact Tools
list_contacts- List all contactsget_contact- Get specific contact detailscreate_contact- Create new contactupdate_contact- Update contact informationdelete_contact- Delete contactsearch_contacts- Search contacts by query
File Tools
list_files- Browse OneDrive files and foldersget_file- Download file contentcreate_file- Upload files to OneDriveupdate_file- Update existing file contentdelete_file- Delete files or folderssearch_files- Search files in OneDrive
Utility Tools
unified_search- Search across emails, events, and fileslist_accounts- Show authenticated Microsoft accountsauthenticate_account- Start authentication for a new Microsoft accountcomplete_authentication- Complete the authentication process after entering device code
Cache Management Tools
cache_get_stats- View cache statistics (size, entries, hit rate)cache_invalidate- Manually invalidate cache entries by patterncache_task_enqueue- Queue background cache warming taskscache_task_status- Check status of queued cache taskscache_task_list- List all cache tasks by account or status
β‘ High-Performance Caching
M365 MCP includes an intelligent caching system that dramatically improves performance by reducing redundant API calls to Microsoft Graph.
Key Features
- π AES-256 Encryption: All cached data encrypted at rest using SQLCipher
- β‘ 300x Performance Boost: Common operations like
folder_get_treego from 30s β <100ms - π§ Intelligent TTL: Three-state cache (Fresh/Stale/Expired) with automatic refresh
- π¦ Automatic Compression: Large entries (β₯50KB) automatically compressed (70-80% size reduction)
- π Cache Warming: Background pre-population on startup for instant responses
- π― Smart Invalidation: Write operations automatically invalidate related caches
- π Multi-Account: Complete isolation between different accounts
- β Compliance Ready: GDPR and HIPAA compliant data protection
Performance Benchmarks
| Operation | Without Cache | With Cache | Speedup |
|---|---|---|---|
folder_get_tree | 30s | <100ms | 300x |
email_list | 2-5s | <50ms | 40-100x |
file_list | 1-3s | <30ms | 30-100x |
| Cache Hit Rate | N/A | >80% | 70%+ API call reduction |
Cache Configuration
The cache works automatically, but you can control its behavior:
# Use cache (default - recommended)
folder_get_tree(account_id, path="/Documents")
# Force refresh (bypass cache, update with fresh data)
folder_get_tree(account_id, path="/Documents", force_refresh=True)
# Disable cache for this request only
email_list(account_id, folder="inbox", use_cache=False)
Cache Security
- Encryption: AES-256 encryption via SQLCipher
- Key Storage: System keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- Fallback: Environment variable
M365_MCP_CACHE_KEYfor headless servers - Compliance: GDPR Article 32 and HIPAA Β§164.312 compliant
Cache Management
View cache statistics:
stats = cache_get_stats()
# Returns: total_entries, size_bytes, hit_rate, oldest_entry, etc.
Manually invalidate cache:
# Invalidate all email caches
cache_invalidate("email_*")
# Invalidate specific account's caches
cache_invalidate("email_*", account_id="account-123")
π For complete cache documentation, see CLAUDE.md
Manual Setup
1. Azure App Registration
- Go to Azure Portal β Microsoft Entra ID β App registrations
- New registration β Name:
m365-mcp - Supported account types: Personal + Work/School
- Authentication β Allow public client flows: Yes
- API permissions β Add these delegated permissions:
- offline_access (required for refresh tokens; the CLI retries against the consumers authority if a personal account flags it as reserved)
- Mail.ReadWrite
- Calendars.ReadWrite
- Files.ReadWrite
- Contacts.Read
- People.Read
- User.Read
- Copy Application ID
2. Installation
git clone https://github.com/robin-collins/m365-mcp.git
cd m365-mcp
uv sync
3. Authentication
# Set your Azure app ID
export M365_MCP_CLIENT_ID="your-app-id-here"
# Run authentication script
uv run authenticate.py
# Follow the prompts to authenticate your Microsoft accounts
4. Claude Desktop Configuration
Add to your Claude Desktop configuration:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"microsoft": {
"command": "uvx",
"args": ["--from", "git+https://github.com/robin-collins/m365-mcp.git", "m365-mcp"],
"env": {
"M365_MCP_CLIENT_ID": "your-app-id-here"
}
}
}
}
Or for local development:
{
"mcpServers": {
"microsoft": {
"command": "uv",
"args": ["--directory", "/path/to/m365-mcp", "run", "m365-mcp"],
"env": {
"M365_MCP_CLIENT_ID": "your-app-id-here"
}
}
}
}
Transport Modes
M365 MCP supports two transport modes for different use cases:
stdio (Default) - For Desktop Apps
Use for: Claude Desktop, local MCP clients
Security: Inherently secure through process isolation (no authentication required)
# Default mode - no configuration needed
export M365_MCP_CLIENT_ID="your-app-id"
uv run m365-mcp
Streamable HTTP - For Web/API Access
Use for: Web applications, remote access, multi-client scenarios
Security: β οΈ Requires authentication (bearer token or OAuth)
Protocol: Uses MCP Streamable HTTP (spec 2025-03-26+)
# Generate secure token
export MCP_AUTH_TOKEN=$(openssl rand -hex 32)
# Configure Streamable HTTP with bearer authentication
export M365_MCP_CLIENT_ID="your-app-id"
export MCP_TRANSPORT="http"
export MCP_AUTH_METHOD="bearer"
export MCP_HOST="127.0.0.1"
export MCP_PORT="8000"
# Start server
uv run m365-mcp
Client connection:
from mcp.client.http import http_client
async with http_client(
"http://localhost:8000/mcp",
headers={"Authorization": f"Bearer {your_token}"}
) as (read, write):
# Use the session...
π See SECURITY.md for complete security guide and authentication options
Multi-Account Support
All tools require an account_id parameter as the first argument:
# List accounts to get IDs
accounts = list_accounts()
account_id = accounts[0]["account_id"]
# Use account for operations
send_email(account_id, "user@example.com", "Subject", "Body")
list_emails(account_id, limit=10, include_body=True)
create_event(account_id, "Meeting", "2024-01-15T10:00:00Z", "2024-01-15T11:00:00Z")
Development
# Run tests
uv run pytest tests/ -v
# Type checking
uv run pyright
# Format code
uvx ruff format .
# Lint
uvx ruff check --fix --unsafe-fixes .
Example: AI Assistant Scenarios
Smart Email Management
# Get account ID first
accounts = list_accounts()
account_id = accounts[0]["account_id"]
# List latest emails with full content
emails = list_emails(account_id, limit=10, include_body=True)
# Reply maintaining thread
reply_to_email(account_id, email_id, "Thanks for your message. I'll review and get back to you.")
# Forward with attachments
email = get_email(email_id, account_id)
attachments = [get_attachment(email_id, att["id"], account_id) for att in email["attachments"]]
send_email(account_id, "boss@company.com", f"FW: {email['subject']}", email["body"]["content"], attachments=attachments)
Intelligent Scheduling
# Get account ID first
accounts = list_accounts()
account_id = accounts[0]["account_id"]
# Check availability before scheduling
availability = check_availability(account_id, "2024-01-15T10:00:00Z", "2024-01-15T18:00:00Z", ["colleague@company.com"])
# Create meeting with details
create_event(
account_id,
"Project Review",
"2024-01-15T14:00:00Z",
"2024-01-15T15:00:00Z",
location="Conference Room A",
body="Quarterly review of project progress",
attendees=["colleague@company.com", "manager@company.com"]
)
Security Notes
- Tokens are cached locally in
~/.m365_mcp_token_cache.json - Cache data is encrypted at rest using AES-256 in
~/.m365_mcp_cache.db - Encryption keys stored securely in system keyring (or
M365_MCP_CACHE_KEYenv var) - Use app-specific passwords if you have 2FA enabled
- Only request permissions your app actually needs
- Consider using a dedicated app registration for production
Troubleshooting
- Authentication fails: Check your CLIENT_ID is correct
- "Need admin approval": Use
M365_MCP_TENANT_ID=consumersfor personal accounts - Missing permissions: Ensure all required API permissions are granted in Azure
- Token errors: Delete
~/.m365_mcp_token_cache.jsonand re-authenticate - Cache issues: Delete
~/.m365_mcp_cache.dbto reset cache (encryption key will regenerate) - Slow first requests: Normal - cache warming runs in background, subsequent requests are fast
License
MIT
