msgraph-mcp
MCP server providing AI assistants with full access to Microsoft Outlook email and calendar via the Microsoft Graph API, featuring 26 tools for mail, calendar, contacts, and scheduling with delegated authentication.
README
msgraph-mcp
A Model Context Protocol (MCP) server that gives AI assistants full access to Microsoft Outlook email and calendar through the Microsoft Graph API. Built on FastMCP, it supports delegated authentication via device-code flow and can run locally or in a framework-managed cloud environment.
Features
26 tools across mail, calendar, contacts, and scheduling:
- Read — list folders, messages, search (OData
$search), attachments (inline base64 for files under 1.5 MB) - Compose — send, reply, reply-all, forward with dry-run preview by default
- Drafts — create, update, attach files, then send when ready
- Organize — mark read/unread, flag, categorize, move to folder, soft- or hard-delete
- Bulk — multi-pass filtered operations (delete, mark read/unread, move) with dry-run preview, up to 1 000 messages per call
- Folders & aliases — create mail folders, list send-from addresses
Calendar
- Read — list calendars, events (default window: yesterday through 14 days out), full event details
- Write — create, update, delete/cancel events with attendees, body, location, all-day support
- Shared calendars — full read/write access to other users' calendars via
user_idparameter - Scheduling — check free/busy status for multiple users, or let Graph suggest optimal meeting times
- Responses — accept, decline, or tentatively accept meeting invitations
Contacts
- People search — resolve display names to email addresses using the People API
Authentication
- Device-code flow — interactive three-step auth (
start_auth→ user approves →finish_auth) - Multi-account — cache and switch between multiple Microsoft accounts
- Framework mode — accept pre-authenticated tokens via environment variables for serverless deployments
Tool reference
| Area | Tool | Description |
|---|---|---|
| Auth | auth_status |
Show configuration and cached accounts |
| Auth | start_auth |
Begin device-code flow (returns URL + code) |
| Auth | finish_auth |
Complete device-code flow after user approval |
list_folders |
List mail folders with item/unread counts | |
list_messages |
List messages in a folder (limit 50) | |
get_message |
Full message details including body | |
search_messages |
Search via OData $search (limit 50) |
|
list_attachments |
List attachment metadata for a message | |
get_attachments |
Download a single attachment | |
send_message |
Send a new email (dry-run by default) | |
reply_to_message |
Reply or reply-all (dry-run by default) | |
forward_message |
Forward a message (dry-run by default) | |
create_draft |
Create a draft without sending | |
manage_draft |
Update or send an existing draft | |
add_attachment_to_draft |
Attach a file to a draft | |
update_message |
Mark read/unread, flag, or categorize | |
move_message |
Move to a folder (supports well-known names) | |
delete_message |
Soft-delete or permanently delete | |
bulk_manage_messages |
Bulk filtered actions with dry-run (limit 1 000) | |
create_folder |
Create a new mail folder | |
list_aliases |
List email aliases / send-from addresses | |
| Calendar | list_calendars |
List calendars (own or shared via user_id) |
| Calendar | list_events |
List events in a time range (limit 100) |
| Calendar | get_event |
Full event details with attendees |
| Calendar | create_event |
Create a calendar event |
| Calendar | update_event |
Update an existing event |
| Calendar | delete_event |
Delete or cancel an event |
| Calendar | respond_to_event |
Accept, decline, or tentatively accept |
| Calendar | check_availability |
Free/busy lookup or meeting time suggestions |
| Contacts | search_people |
Search contacts by name (limit 50) |
Prerequisites
- Python 3.11+
- An Azure app registration with delegated Microsoft Graph permissions (see below)
- uv (recommended) or pip
Azure app registration
Create an app registration in Microsoft Entra admin center (Azure AD).
1. Supported account types
Choose one:
- Accounts in this organizational directory only — single tenant
- Accounts in any organizational directory — multi-tenant work/school accounts
2. Authentication
- Enable Allow public client flows (required for device-code flow)
3. API permissions
Add delegated Microsoft Graph permissions:
| Permission | Purpose |
|---|---|
User.Read |
Read signed-in user profile |
Mail.ReadWrite |
Read, move, flag, categorize, delete mail |
Mail.Send |
Send mail, reply, forward |
Calendars.ReadWrite |
Read and write calendar events |
Calendars.ReadWrite.Shared |
Access shared / delegated calendars |
People.Read |
Search contacts by name |
For read-only use, replace Mail.ReadWrite and Mail.Send with Mail.Read, and Calendars.ReadWrite / Calendars.ReadWrite.Shared with Calendars.Read. Write tools will return permission errors but everything else works.
4. Admin consent
Grant admin consent for the tenant if required by your organization's policies.
Configuration
Copy .env.example to .env and fill in your values:
cp .env.example .env
| Variable | Default | Description |
|---|---|---|
MICROSOFT_CLIENT_ID |
(required) | Azure app registration client ID |
MICROSOFT_TENANT_ID |
common |
organizations (work/school only), common (any), or a specific tenant GUID |
MICROSOFT_SCOPES |
User.Read Mail.ReadWrite Mail.Send Calendars.ReadWrite Calendars.ReadWrite.Shared People.Read |
Space-separated delegated permissions |
MICROSOFT_TOKEN_CACHE_PATH |
.data/msal_token_cache.json |
Path to the local MSAL token cache |
MAX_ATTACHMENT_INLINE_SIZE |
1572864 |
Max attachment size (bytes) for inline base64 (default 1.5 MB) |
Recommended tenant values:
organizations— work/school accounts only (most common for enterprise)- A specific tenant GUID — locks authentication to a single organization
common— any Microsoft account (work, school, or personal)
Deployment
Local (stdio)
The default transport is stdio, suitable for desktop MCP clients like Claude Code, Claude Desktop, Cursor, and VS Code.
# Install dependencies
uv sync
# Run the server
uv run msgraph-mcp
Or with pip:
pip install -e .
msgraph-mcp
MCP client configuration
Add to your MCP client's configuration (e.g. Claude Desktop claude_desktop_config.json, .mcp.json for Claude Code, etc.):
{
"mcpServers": {
"msgraph-mcp": {
"type": "stdio",
"command": "uv",
"args": ["run", "msgraph-mcp"],
"env": {
"MICROSOFT_CLIENT_ID": "your-client-id",
"MICROSOFT_TENANT_ID": "your-tenant-id"
}
}
}
}
If you use a .env file in the project directory, the env block can be omitted.
Cloud — AWS Lambda with mcp-lambda-wrappers (ChatGPT, Claude.ai)
For use with remote MCP clients like ChatGPT and Claude.ai, this server can be deployed as a serverless AWS Lambda function using mcp-cloud-wrappers. That framework wraps any stdio-based MCP server behind Amazon Bedrock AgentCore Gateway with full OAuth 2.0 and Dynamic Client Registration (RFC 7591) support — no code changes required in this project.
What the framework provides:
- Serverless deployment — runs this MCP server as a Lambda subprocess behind AgentCore Gateway
- Per-user OAuth — each user authenticates with their own Microsoft account; tokens are stored in AWS Secrets Manager with automatic refresh
- Caller authentication — Cognito JWT validation for all inbound requests
- Dynamic Client Registration — MCP clients (ChatGPT, Claude.ai) self-register via a standard
/registerendpoint - Zero idle cost — Lambda functions spin up on demand
How it works:
- An MCP client sends a tool call to the AgentCore Gateway endpoint
- The framework validates the caller's JWT, extracts their identity, and loads their Microsoft Graph OAuth token from Secrets Manager
- The token is injected as
GRAPH_ACCESS_TOKENinto this server's environment - This server runs as a subprocess, reads the token, and executes the tool against Microsoft Graph
- If the user hasn't authenticated yet,
start_authreturns the framework's OAuth URL instead of a device code
This project is used as the reference example service in mcp-lambda-wrappers — see infra/lambda/services/msgraph/ in that repo for the full configuration.
Quick deploy (from the mcp-lambda-wrappers repo):
# One-time: deploy shared infrastructure (Cognito, DCR, OAuth callback)
make deploy-shared
# Create the Azure app secret
aws secretsmanager create-secret \
--name mcp-wrappers-msgraph-service-secrets \
--secret-string '{"MICROSOFT_CLIENT_ID": "your-client-id"}'
# Generate tool definitions and deploy
make gen-tools SERVICE=msgraph
make deploy-service SERVICE=msgraph
Framework environment variables
When running inside the framework, this server auto-detects Lambda mode via these injected environment variables:
| Variable | Description |
|---|---|
GRAPH_ACCESS_TOKEN |
Pre-authenticated Microsoft Graph access token (per-user) |
OAUTH_AUTHENTICATED |
Set to true when auth is complete |
OAUTH_USER_ID |
Authenticated user identifier |
OAUTH_AUTH_URL |
OAuth authorization URL (shown when user needs to authenticate) |
SERVICE_NAME |
Service identifier for the framework |
In this mode:
- The MSAL device-code flow is bypassed — tokens are injected by the framework
- No local token cache is used (compatible with read-only filesystems like Lambda's
/var/task) auth_statusreports the framework-managed token statestart_auth/finish_authreturn guidance to authenticate through the framework's OAuth flow instead
Docker
While no Dockerfile is included, the server can be containerized:
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir .
ENV MICROSOFT_CLIENT_ID=""
ENV MICROSOFT_TENANT_ID="organizations"
EXPOSE 8000
CMD ["msgraph-mcp"]
For persistent authentication, mount a volume for the token cache:
docker run -v msgraph-data:/app/.data \
-e MICROSOFT_CLIENT_ID=your-id \
-e MICROSOFT_TENANT_ID=your-tenant \
msgraph-mcp
Safety defaults
Write operations default to safe behavior:
| Feature | Default | Notes |
|---|---|---|
send_message |
dry_run=True |
Creates a temporary draft for preview, then deletes it |
reply_to_message |
dry_run=True |
Preview before sending |
forward_message |
dry_run=True |
Preview before sending |
bulk_manage_messages |
dry_run=True |
Shows matches without executing |
delete_message |
permanent=False |
Moves to Deleted Items (recoverable) |
Security
- Path segment validation — all user-supplied IDs are validated against a safe-character pattern before URL interpolation, blocking path traversal
- Next-link hardening — pagination only follows HTTPS URLs on the configured Graph host
- Search sanitization — double-quotes stripped from OData
$searchqueries - Retry with backoff — automatic retry for HTTP 429 and transient 5xx errors (3 attempts, respects
Retry-After) - Error translation — raw Graph API payloads are never exposed to callers
- Token cache permissions — cache file
0600, parent directory0700, symlinks rejected
See SECURITY_REVIEW.md for the full threat model and remaining risks.
Development
# Install with dev dependencies
uv sync --dev
# Run tests
uv run pytest
# Or with pip
pip install -e '.[dev]'
pytest
Smoke test harness
A CLI harness for manual testing without a full MCP client:
# Auth
python3 scripts/smoke_test.py status
python3 scripts/smoke_test.py start-auth
python3 scripts/smoke_test.py finish-auth
python3 scripts/smoke_test.py list-accounts
# Mail
python3 scripts/smoke_test.py list-folders
python3 scripts/smoke_test.py list-messages --folder inbox --limit 5
python3 scripts/smoke_test.py get-message MESSAGE_ID
python3 scripts/smoke_test.py search-messages "search term"
python3 scripts/smoke_test.py mark-message-read MESSAGE_ID
python3 scripts/smoke_test.py move-message MESSAGE_ID archive
python3 scripts/smoke_test.py delete-message MESSAGE_ID
python3 scripts/smoke_test.py bulk-manage-messages --sender-contains "newsletters" --limit 50
# Calendar
python3 scripts/smoke_test.py list-calendars
python3 scripts/smoke_test.py list-events --limit 10
python3 scripts/smoke_test.py get-event EVENT_ID
License
See LICENSE for details.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。