mcp server
microsoft-mcp
A Microsoft Graph API integration MCP server that provides AI assistants with comprehensive access to Microsoft 365 services through the Model Context Protocol (MCP). It enables natural language autom
Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
{
"mcpServers": {
"microsoft-mcp": {
"command": "uvx",
"args": [
"microsoft-mcp"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 17, 2026Microsoft 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
- Professional Email Templates: KamDental-branded templates with automatic theme selection
- 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
Quick Start with Claude Desktop
# Add Microsoft MCP server (replace with your Azure app ID)
claude mcp add microsoft-mcp -e MICROSOFT_MCP_CLIENT_ID=your-app-id-here -- uvx --from git+https://github.com/elyxlz/microsoft-mcp.git microsoft-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
# Professional email templates
> send a practice report for Baytown location with this month's financial data
> send an executive summary across all locations
> send a provider performance update for Dr. Johnson
> send an alert notification about system downtime
# 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
Professional Email Templates
send_practice_report- Send branded practice performance reportsend_executive_summary- Send multi-location executive overviewsend_provider_update- Send provider performance updatesend_alert_notification- Send urgent alerts and notifications
Email Template Features
- Automatic Theme Selection: Baytown (blue), Humble (green), or Executive (dark) based on location/recipient
- Mobile Responsive: Optimized for all devices and email clients
- Professional Design: Consistent branding with KamDental visual identity
- Performance Optimized: <2 second rendering, <100KB total size
- Accessibility: WCAG 2.1 AA compliant with screen reader support
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
Manual Setup
1. Azure App Registration
- Go to Azure Portal → Microsoft Entra ID → App registrations
- New registration → Name:
microsoft-mcp - Supported account types: Personal + Work/School
- Authentication → Allow public client flows: Yes
- API permissions → Add these delegated permissions:
- Mail.ReadWrite
- Mail.Send
- Calendars.ReadWrite
- Files.ReadWrite
- Contacts.Read
- People.Read
- User.Read
- Copy Application ID
2. Installation
git clone https://github.com/elyxlz/microsoft-mcp.git
cd microsoft-mcp
uv sync
3. Authentication
# Set your Azure app ID
export MICROSOFT_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/elyxlz/microsoft-mcp.git", "microsoft-mcp"],
"env": {
"MICROSOFT_MCP_CLIENT_ID": "your-app-id-here"
}
}
}
}
Or for local development:
{
"mcpServers": {
"microsoft": {
"command": "uv",
"args": ["--directory", "/path/to/microsoft-mcp", "run", "microsoft-mcp"],
"env": {
"MICROSOFT_MCP_CLIENT_ID": "your-app-id-here"
}
}
}
}
Multi-Account Support
All tools require an account_id parameter as the first argument. You can pass:
- The exact
home_account_id(recommended) - The account
username(email), e.g.admin@contoso.com - The keyword
defaultto use the first authenticated account
# 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")
# Or via username or 'default'
list_emails("admin@contoso.com", limit=10, include_body=True)
list_emails("default", limit=10, include_body=True)
Professional Email Templates
The KamDental Email Framework provides professional, branded email templates:
Practice Report Example
await send_practice_report(
account_id="default",
to="manager@kamdental.com",
subject="Baytown Practice Report - January 2024",
location="Baytown",
financial_data={
"production": {"value": 285000, "goal": 300000},
"collections": {"value": 270000, "ratio": 0.947},
"case_acceptance": {"value": 0.72, "goal": 0.75},
"call_answer_rate": {"value": 0.91, "goal": 0.95}
},
provider_data=[
{
"name": "Dr. Sarah Johnson",
"role": "General Dentist",
"production": 125000,
"goal_percentage": 1.04
}
],
period="January 2024",
alerts=[
{
"type": "warning",
"title": "Production Below Target",
"message": "Current production is 5% below monthly target."
}
]
)
Executive Summary Example
await send_executive_summary(
account_id="default",
to="executive@kamdental.com",
locations_data=[
{
"name": "Baytown",
"production": 285000,
"target": 300000,
"status": "warning"
},
{
"name": "Humble",
"production": 195000,
"target": 180000,
"status": "ahead"
}
],
period="Q1 2024",
key_insights=[
{
"title": "Overall Performance",
"description": "Combined production at 96% of target"
}
]
)
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 .
# Test email framework
uv run python -m microsoft_mcp.email_framework.test_runner
Codex CLI Setup
You can run this MCP server from Codex CLI by adding an MCP server entry that launches the microsoft-mcp binary (or uvx command) with the required environment variable.
- Add to your Codex config file (adjust path to wherever your Codex CLI reads config):
[mcp_servers.microsoft]
command = "uvx"
args = [
"--from",
"git+https://github.com/elyxlz/microsoft-mcp.git",
"microsoft-mcp",
]
env = { "MICROSOFT_MCP_CLIENT_ID" = "your-azure-app-id", "MICROSOFT_MCP_TENANT_ID" = "common" }
Notes:
MICROSOFT_MCP_CLIENT_IDis required (Azure App Registration → Application ID).- Optional
MICROSOFT_MCP_TENANT_IDcan becommon, your tenant GUID, orconsumersfor personal accounts. - The above uses
uvxto fetch/run directly from GitHub. If you’re developing locally, use the local variant below.
- Local development variant (run from your checked-out repo):
[mcp_servers.microsoft]
command = "uv"
args = ["--directory", "/path/to/microsoft-mcp", "run", "microsoft-mcp"]
env = { "MICROSOFT_MCP_CLIENT_ID" = "your-azure-app-id", "MICROSOFT_MCP_TENANT_ID" = "common" }
- Start Codex CLI and ensure the server appears in the tool list. If authentication is needed, use the
auth_operationstool:
auth_operations(action="authenticate")→ visit the URL and enter the codeauth_operations(action="status")→ verify at least one account is authenticated- Use
account_id="default"or your email (e.g.,admin@contoso.com) when calling tools
Troubleshooting:
- If email sending returns 403 on
/me/sendMail, add theMail.Senddelegated permission to your Azure app and grant admin consent. - If passing an
account_idthat doesn’t exist, the server now returns a clear error with the list of available accounts. You can also passdefaultto use the first account.
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
~/.microsoft_mcp_token_cache.json - 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
MICROSOFT_MCP_TENANT_ID=consumersfor personal accounts - Missing permissions: Ensure all required API permissions are granted in Azure
- Sending mail requires the
Mail.Senddelegated permission (in addition toMail.ReadWrite). A missingMail.Sendtypically returns HTTP 403 on/me/sendMail.
- Sending mail requires the
- Token errors: Delete
~/.microsoft_mcp_token_cache.jsonand re-authenticate
Documentation
- Email Framework Guide - Comprehensive guide to professional email templates
- API Documentation - Detailed API reference
- Examples - Code examples and use cases
- Bugfix: Account Resolution Hang - Details of the fix for hanging tool calls when
account_idmismatched
License
MIT