m365-mcp


Namem365-mcp JSON
Version 0.1.2 PyPI version JSON
download
home_pageNone
SummaryMicrosoft 365 MCP server for Outlook, Calendar, and OneDrive with multi-account support
upload_time2025-10-13 13:30:21
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseMIT
keywords ai calendar mcp microsoft-365 microsoft-graph onedrive outlook
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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

## Quick Start

**📚 See [QUICKSTART.md](QUICKSTART.md) for complete installation and setup guide.**

### TL;DR

```bash
# 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

```bash
# 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

```bash
# 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 content
- **`get_email`** - Get specific email with attachments
- **`create_email_draft`** - Create email draft with attachments support
- **`send_email`** - Send email immediately with CC/BCC and attachments
- **`reply_to_email`** - Reply maintaining thread context
- **`reply_all_email`** - Reply to all recipients in thread
- **`update_email`** - Mark emails as read/unread
- **`move_email`** - Move emails between folders
- **`delete_email`** - Delete emails
- **`get_attachment`** - Get email attachment content
- **`search_emails`** - Search emails by query

### Calendar Tools
- **`list_events`** - List calendar events with details
- **`get_event`** - Get specific event details
- **`create_event`** - Create events with location and attendees
- **`update_event`** - Reschedule or modify events
- **`delete_event`** - Cancel events
- **`respond_event`** - Accept/decline/tentative response to invitations
- **`check_availability`** - Check free/busy times for scheduling
- **`search_events`** - Search calendar events

### Contact Tools
- **`list_contacts`** - List all contacts
- **`get_contact`** - Get specific contact details
- **`create_contact`** - Create new contact
- **`update_contact`** - Update contact information
- **`delete_contact`** - Delete contact
- **`search_contacts`** - Search contacts by query

### File Tools
- **`list_files`** - Browse OneDrive files and folders
- **`get_file`** - Download file content
- **`create_file`** - Upload files to OneDrive
- **`update_file`** - Update existing file content
- **`delete_file`** - Delete files or folders
- **`search_files`** - Search files in OneDrive

### Utility Tools
- **`unified_search`** - Search across emails, events, and files
- **`list_accounts`** - Show authenticated Microsoft accounts
- **`authenticate_account`** - Start authentication for a new Microsoft account
- **`complete_authentication`** - Complete the authentication process after entering device code

## Manual Setup

### 1. Azure App Registration

1. Go to [Azure Portal](https://portal.azure.com) → Microsoft Entra ID → App registrations
2. New registration → Name: `m365-mcp`
3. Supported account types: Personal + Work/School
4. Authentication → Allow public client flows: Yes
5. API permissions → Add these delegated permissions:
   - Mail.ReadWrite
   - Calendars.ReadWrite
   - Files.ReadWrite
   - Contacts.Read
   - People.Read
   - User.Read
6. Copy Application ID

### 2. Installation

```bash
git clone https://github.com/robin-collins/m365-mcp.git
cd m365-mcp
uv sync
```

### 3. Authentication

```bash
# 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`

```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:

```json
{
  "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)

```bash
# 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+)

```bash
# 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:**
```python
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](SECURITY.md) for complete security guide and authentication options**

## Multi-Account Support

All tools require an `account_id` parameter as the first argument:

```python
# 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

```bash
# 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
```python
# 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
```python
# 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`
- 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=consumers` for personal accounts
- **Missing permissions**: Ensure all required API permissions are granted in Azure
- **Token errors**: Delete `~/.m365_mcp_token_cache.json` and re-authenticate

## License

MIT
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "m365-mcp",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "ai, calendar, mcp, microsoft-365, microsoft-graph, onedrive, outlook",
    "author": null,
    "author_email": "robin-collins <robin.f.collins@outlook.com>, elyx <elio@pascarelli.com>",
    "download_url": "https://files.pythonhosted.org/packages/5e/c9/ea042f9c2c763957b23644e9106766e95fb6bc54157578875097149fc6f8/m365_mcp-0.1.2.tar.gz",
    "platform": null,
    "description": "# M365 MCP\n\nPowerful MCP server for Microsoft Graph API - a complete AI assistant toolkit for Outlook, Calendar, OneDrive, and Contacts.\n\n## Features\n\n- **Email Management**: Read, send, reply, manage attachments, organize folders\n- **Calendar Intelligence**: Create, update, check availability, respond to invitations\n- **OneDrive Files**: Upload, download, browse with pagination\n- **Contacts**: Search and list contacts from your address book\n- **Multi-Account**: Support for multiple Microsoft accounts (personal, work, school)\n- **Unified Search**: Search across emails, files, events, and people\n\n## Quick Start\n\n**\ud83d\udcda See [QUICKSTART.md](QUICKSTART.md) for complete installation and setup guide.**\n\n### TL;DR\n\n```bash\n# 1. Install\ngit clone https://github.com/robin-collins/m365-mcp.git\ncd m365-mcp && uv sync\n\n# 2. Configure (use .env.example template)\ncp .env.example .env\n# Edit .env with your M365_MCP_CLIENT_ID\n\n# 3. Authenticate\nuv run authenticate.py\n\n# 4. Run\nuv run m365-mcp\n```\n\n### Claude Desktop\n\n```bash\n# Add M365 MCP server (replace with your Azure app ID)\nclaude 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\n\n# Start Claude Desktop\nclaude\n```\n\n### Usage Examples\n\n```bash\n# Email examples\n> read my latest emails with full content\n> reply to the email from John saying \"I'll review this today\"\n> send an email with attachment to alice@example.com\n\n# Calendar examples  \n> show my calendar for next week\n> check if I'm free tomorrow at 2pm\n> create a meeting with Bob next Monday at 10am\n\n# File examples\n> list files in my OneDrive\n> upload this report to OneDrive\n> search for \"project proposal\" across all my files\n\n# Multi-account\n> list all my Microsoft accounts\n> send email from my work account\n```\n\n## Available Tools\n\n### Email Tools\n- **`list_emails`** - List emails with optional body content\n- **`get_email`** - Get specific email with attachments\n- **`create_email_draft`** - Create email draft with attachments support\n- **`send_email`** - Send email immediately with CC/BCC and attachments\n- **`reply_to_email`** - Reply maintaining thread context\n- **`reply_all_email`** - Reply to all recipients in thread\n- **`update_email`** - Mark emails as read/unread\n- **`move_email`** - Move emails between folders\n- **`delete_email`** - Delete emails\n- **`get_attachment`** - Get email attachment content\n- **`search_emails`** - Search emails by query\n\n### Calendar Tools\n- **`list_events`** - List calendar events with details\n- **`get_event`** - Get specific event details\n- **`create_event`** - Create events with location and attendees\n- **`update_event`** - Reschedule or modify events\n- **`delete_event`** - Cancel events\n- **`respond_event`** - Accept/decline/tentative response to invitations\n- **`check_availability`** - Check free/busy times for scheduling\n- **`search_events`** - Search calendar events\n\n### Contact Tools\n- **`list_contacts`** - List all contacts\n- **`get_contact`** - Get specific contact details\n- **`create_contact`** - Create new contact\n- **`update_contact`** - Update contact information\n- **`delete_contact`** - Delete contact\n- **`search_contacts`** - Search contacts by query\n\n### File Tools\n- **`list_files`** - Browse OneDrive files and folders\n- **`get_file`** - Download file content\n- **`create_file`** - Upload files to OneDrive\n- **`update_file`** - Update existing file content\n- **`delete_file`** - Delete files or folders\n- **`search_files`** - Search files in OneDrive\n\n### Utility Tools\n- **`unified_search`** - Search across emails, events, and files\n- **`list_accounts`** - Show authenticated Microsoft accounts\n- **`authenticate_account`** - Start authentication for a new Microsoft account\n- **`complete_authentication`** - Complete the authentication process after entering device code\n\n## Manual Setup\n\n### 1. Azure App Registration\n\n1. Go to [Azure Portal](https://portal.azure.com) \u2192 Microsoft Entra ID \u2192 App registrations\n2. New registration \u2192 Name: `m365-mcp`\n3. Supported account types: Personal + Work/School\n4. Authentication \u2192 Allow public client flows: Yes\n5. API permissions \u2192 Add these delegated permissions:\n   - Mail.ReadWrite\n   - Calendars.ReadWrite\n   - Files.ReadWrite\n   - Contacts.Read\n   - People.Read\n   - User.Read\n6. Copy Application ID\n\n### 2. Installation\n\n```bash\ngit clone https://github.com/robin-collins/m365-mcp.git\ncd m365-mcp\nuv sync\n```\n\n### 3. Authentication\n\n```bash\n# Set your Azure app ID\nexport M365_MCP_CLIENT_ID=\"your-app-id-here\"\n\n# Run authentication script\nuv run authenticate.py\n\n# Follow the prompts to authenticate your Microsoft accounts\n```\n\n### 4. Claude Desktop Configuration\n\nAdd to your Claude Desktop configuration:\n\n**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`  \n**Windows**: `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"microsoft\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"git+https://github.com/robin-collins/m365-mcp.git\", \"m365-mcp\"],\n      \"env\": {\n        \"M365_MCP_CLIENT_ID\": \"your-app-id-here\"\n      }\n    }\n  }\n}\n```\n\nOr for local development:\n\n```json\n{\n  \"mcpServers\": {\n    \"microsoft\": {\n      \"command\": \"uv\",\n      \"args\": [\"--directory\", \"/path/to/m365-mcp\", \"run\", \"m365-mcp\"],\n      \"env\": {\n        \"M365_MCP_CLIENT_ID\": \"your-app-id-here\"\n      }\n    }\n  }\n}\n```\n\n## Transport Modes\n\nM365 MCP supports two transport modes for different use cases:\n\n### stdio (Default) - For Desktop Apps\n\n**Use for:** Claude Desktop, local MCP clients\n\n**Security:** Inherently secure through process isolation (no authentication required)\n\n```bash\n# Default mode - no configuration needed\nexport M365_MCP_CLIENT_ID=\"your-app-id\"\nuv run m365-mcp\n```\n\n### Streamable HTTP - For Web/API Access\n\n**Use for:** Web applications, remote access, multi-client scenarios\n\n**Security:** \u26a0\ufe0f **Requires authentication** (bearer token or OAuth)\n\n**Protocol:** Uses MCP Streamable HTTP (spec 2025-03-26+)\n\n```bash\n# Generate secure token\nexport MCP_AUTH_TOKEN=$(openssl rand -hex 32)\n\n# Configure Streamable HTTP with bearer authentication\nexport M365_MCP_CLIENT_ID=\"your-app-id\"\nexport MCP_TRANSPORT=\"http\"\nexport MCP_AUTH_METHOD=\"bearer\"\nexport MCP_HOST=\"127.0.0.1\"\nexport MCP_PORT=\"8000\"\n\n# Start server\nuv run m365-mcp\n```\n\n**Client connection:**\n```python\nfrom mcp.client.http import http_client\n\nasync with http_client(\n    \"http://localhost:8000/mcp\",\n    headers={\"Authorization\": f\"Bearer {your_token}\"}\n) as (read, write):\n    # Use the session...\n```\n\n**\ud83d\udcda See [SECURITY.md](SECURITY.md) for complete security guide and authentication options**\n\n## Multi-Account Support\n\nAll tools require an `account_id` parameter as the first argument:\n\n```python\n# List accounts to get IDs\naccounts = list_accounts()\naccount_id = accounts[0][\"account_id\"]\n\n# Use account for operations\nsend_email(account_id, \"user@example.com\", \"Subject\", \"Body\")\nlist_emails(account_id, limit=10, include_body=True)\ncreate_event(account_id, \"Meeting\", \"2024-01-15T10:00:00Z\", \"2024-01-15T11:00:00Z\")\n```\n\n## Development\n\n```bash\n# Run tests\nuv run pytest tests/ -v\n\n# Type checking\nuv run pyright\n\n# Format code\nuvx ruff format .\n\n# Lint\nuvx ruff check --fix --unsafe-fixes .\n```\n\n## Example: AI Assistant Scenarios\n\n### Smart Email Management\n```python\n# Get account ID first\naccounts = list_accounts()\naccount_id = accounts[0][\"account_id\"]\n\n# List latest emails with full content\nemails = list_emails(account_id, limit=10, include_body=True)\n\n# Reply maintaining thread\nreply_to_email(account_id, email_id, \"Thanks for your message. I'll review and get back to you.\")\n\n# Forward with attachments\nemail = get_email(email_id, account_id)\nattachments = [get_attachment(email_id, att[\"id\"], account_id) for att in email[\"attachments\"]]\nsend_email(account_id, \"boss@company.com\", f\"FW: {email['subject']}\", email[\"body\"][\"content\"], attachments=attachments)\n```\n\n### Intelligent Scheduling\n```python\n# Get account ID first\naccounts = list_accounts()\naccount_id = accounts[0][\"account_id\"]\n\n# Check availability before scheduling\navailability = check_availability(account_id, \"2024-01-15T10:00:00Z\", \"2024-01-15T18:00:00Z\", [\"colleague@company.com\"])\n\n# Create meeting with details\ncreate_event(\n    account_id,\n    \"Project Review\",\n    \"2024-01-15T14:00:00Z\", \n    \"2024-01-15T15:00:00Z\",\n    location=\"Conference Room A\",\n    body=\"Quarterly review of project progress\",\n    attendees=[\"colleague@company.com\", \"manager@company.com\"]\n)\n```\n\n## Security Notes\n\n- Tokens are cached locally in `~/.m365_mcp_token_cache.json`\n- Use app-specific passwords if you have 2FA enabled\n- Only request permissions your app actually needs\n- Consider using a dedicated app registration for production\n\n## Troubleshooting\n\n- **Authentication fails**: Check your CLIENT_ID is correct\n- **\"Need admin approval\"**: Use `M365_MCP_TENANT_ID=consumers` for personal accounts\n- **Missing permissions**: Ensure all required API permissions are granted in Azure\n- **Token errors**: Delete `~/.m365_mcp_token_cache.json` and re-authenticate\n\n## License\n\nMIT",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Microsoft 365 MCP server for Outlook, Calendar, and OneDrive with multi-account support",
    "version": "0.1.2",
    "project_urls": {
        "Documentation": "https://github.com/robin-collins/m365-mcp#readme",
        "Homepage": "https://github.com/robin-collins/m365-mcp",
        "Issues": "https://github.com/robin-collins/m365-mcp/issues",
        "Repository": "https://github.com/robin-collins/m365-mcp"
    },
    "split_keywords": [
        "ai",
        " calendar",
        " mcp",
        " microsoft-365",
        " microsoft-graph",
        " onedrive",
        " outlook"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "71009329c1a5a31414fe760e485ee4077b131120221d9a26a2948ddd3415635f",
                "md5": "95cbb88a18cd9ad0c1f9ca4fb78050f0",
                "sha256": "5e90514b73e37c24b3bdc0218e447fc7ca9fc7564ee9dd9bf52d283525564180"
            },
            "downloads": -1,
            "filename": "m365_mcp-0.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "95cbb88a18cd9ad0c1f9ca4fb78050f0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 56861,
            "upload_time": "2025-10-13T13:30:19",
            "upload_time_iso_8601": "2025-10-13T13:30:19.105740Z",
            "url": "https://files.pythonhosted.org/packages/71/00/9329c1a5a31414fe760e485ee4077b131120221d9a26a2948ddd3415635f/m365_mcp-0.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5ec9ea042f9c2c763957b23644e9106766e95fb6bc54157578875097149fc6f8",
                "md5": "e1b973ec324cfda1b9090ec287895384",
                "sha256": "17d4545f678190a2c2c2826fa435dad4db009ad8510d60e51e6f8bbce4d8d6aa"
            },
            "downloads": -1,
            "filename": "m365_mcp-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "e1b973ec324cfda1b9090ec287895384",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 248541,
            "upload_time": "2025-10-13T13:30:21",
            "upload_time_iso_8601": "2025-10-13T13:30:21.891116Z",
            "url": "https://files.pythonhosted.org/packages/5e/c9/ea042f9c2c763957b23644e9106766e95fb6bc54157578875097149fc6f8/m365_mcp-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-13 13:30:21",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "robin-collins",
    "github_project": "m365-mcp#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "m365-mcp"
}
        
Elapsed time: 1.00841s