Skip to main content

Unified command-line interface for managing Office365 email, calendar, and contacts

Project description

Office365 CLI (o365)

A unified command-line interface for managing Office365 email, calendar, and contacts.

✨ NEW: MCP Server Support! Use Office 365 with Claude Desktop through natural language. Learn more

Features

Core Features

  • Email Management: Read, archive, mark read, and send emails via Graph API
  • Calendar: View and create calendar events, manage invites
  • Teams Chats: List, read, send, and search Microsoft Teams chats
  • OneDrive & SharePoint: List, search, download, and upload files across personal and shared drives
  • Meeting Recordings: List, search, download, and view transcripts of Teams meeting recordings
  • Contacts: Search and manage contacts
  • OAuth2 Authentication: Secure device code flow authentication
  • Streaming Results: Efficient pagination with immediate display for large result sets
  • External Sender Detection: Automatic tagging of emails from outside your organization
  • Attachment Support: Download email attachments with inline image detection
  • Timezone Support: Automatic timezone handling for calendar queries
  • Git-style Time Parsing: Natural time expressions like "2 days ago" and "yesterday"

🚀 MCP Server (NEW!)

  • Model Context Protocol Server: Integrate Office 365 with Claude Desktop and other MCP clients
  • 20 Tools: Access email, calendar, files, chats, contacts, and recordings via natural language
  • 3 Prompt Templates: Pre-built workflows for common tasks
  • Natural Language Queries: Just ask Claude what you need!

Example MCP queries:

  • "Check my unread emails from the last 2 days"
  • "What meetings do I have tomorrow?"
  • "Search my OneDrive for budget spreadsheets"
  • "Show me my recent Teams chats"

See MCP Server section below for setup instructions.

Installation

From PyPI (when published)

pip install o365-cli

From Source

git clone https://github.com/yourusername/o365-cli.git
cd o365-cli
pip install -e .

Development Installation

# Clone the repo
git clone https://github.com/yourusername/o365-cli.git
cd o365-cli

# Install in development mode with dev dependencies
pip install -e ".[dev]"

Quick Start

1. Authentication

First, authenticate with Office365:

o365 auth login

This will prompt you to visit a URL and enter a device code. Follow the instructions to complete authentication.

2. Read Emails

List unread emails:

o365 mail read --unread

3. View Calendar

See today's events:

o365 calendar list --today

Usage

Mail Commands

# List emails (streams all results by default)
o365 mail read
o365 mail read --unread                      # Only unread emails
o365 mail read --since "2 days ago"          # Emails from last 2 days
o365 mail read -n 20                         # Limit to 20 most recent
o365 mail read -s "payment"                  # Search for "payment"

# Read specific email by ID (full Graph API message ID)
o365 mail read AAMkADFhY2VlZWU4LWMxMTItNGRiYy04ZjlkLTc3...

# Archive emails (use full message IDs from mail read output)
o365 mail archive AAMkADFhY2VlZWU4LWMxMTItNGRiYy04ZjlkLTc3...
o365 mail archive --dry-run AAMkADFhY2VlZWU4...  # Preview first

# Mark emails as read
o365 mail mark-read AAMkADFhY2VlZWU4LWMxMTItNGRiYy04ZjlkLTc3...
o365 mail mark-read --dry-run AAMkADFhY2VlZWU4...  # Preview first

# Download email attachment
o365 mail download-attachment <MESSAGE_ID> <ATTACHMENT_ID>
o365 mail download-attachment <MESSAGE_ID> <ATTACHMENT_ID> -o ~/Downloads/

# Send email
echo "<p>Hello!</p>" | o365 mail send -r recipient@example.com -S "Subject" -H -

Note: Message IDs are displayed in full when listing emails. Copy the full ID from the ID: line to use with read, archive, or mark-read commands. The [external] prefix indicates emails from senders outside your organization.

Calendar Commands

# View your calendar
o365 calendar list --today
o365 calendar list --week
o365 calendar list --after "3 days ago"

# View someone else's calendar
o365 calendar list --user john --today
o365 calendar list --user john --week

Chat Commands

# List chats
o365 chat list
o365 chat list --with john            # Filter to chats with john
o365 chat list --since "2 days ago"    # Recent chats

# Read messages
o365 chat read <chat-id>
o365 chat read --with john            # Read chat with john
o365 chat read --with "Project Team"   # Read group chat

# Send messages
o365 chat send --to john -m "Quick question"
o365 chat send --chat <chat-id> -m "Message here"

# Search messages
o365 chat search "deployment"
o365 chat search "bug fix" --with john   # Search in john's chats
o365 chat search "meeting" --since "1 week ago"

Files Commands

# List available drives
o365 files drives
o365 files drives -v                   # Show drive IDs and details

# List files
o365 files list                        # List root of personal OneDrive
o365 files list /Documents             # List Documents folder
o365 files list -l --since "1 week ago"     # Recent files with details

# Search files
o365 files search "quarterly report"
o365 files search "budget" --type xlsx              # Excel files only

# Download files
o365 files download /Reports/Q4.xlsx
o365 files download /Reports/Q4.xlsx ~/Desktop/     # To specific location

# Upload files
o365 files upload ~/analysis.pdf /Reports/

Note: By default, only personal OneDrive access is enabled. To access shared drives and SharePoint sites, enable the additional scopes in your config:

[scopes]
files.all = true   # Enable access to shared drives
sites.all = true   # Enable access to SharePoint sites

These permissions (Files.Read.All, Files.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All) may require admin consent in some organizations. See Azure App Registration for details.

Recordings Commands

# List recordings
o365 recordings list
o365 recordings list --since "1 week ago"     # Recent recordings
o365 recordings list -n 100                   # Last 100 recordings

# Search recordings
o365 recordings search "sprint planning"
o365 recordings search "review" --since "1 month ago"

# Download recording
o365 recordings download <recording-id>
o365 recordings download <recording-id> ~/Videos/

# View transcript
o365 recordings transcript <recording-id>
o365 recordings transcript <recording-id> --output notes.txt
o365 recordings transcript <recording-id> --format vtt
o365 recordings transcript <recording-id> --timestamps --speakers

# Get recording info
o365 recordings info <recording-id>

Note: Recordings commands require Files permissions to be enabled (recordings are stored in OneDrive). Use o365 recordings list or o365 recordings search to get recording IDs.

Contacts Commands

# List all contacts
o365 contacts list

# Search for contacts
o365 contacts search john
o365 contacts search john@example.com

# Resolve contact (for scripting)
o365 contacts search john --resolve

Authentication Commands

# Initial login
o365 auth login

# Refresh token
o365 auth refresh

# Check status
o365 auth status

Config Commands

# List all configuration values
o365 config list

# Get a specific value
o365 config get auth.client_id
o365 config get scopes.mail

# Set a value
o365 config set auth.client_id "your-client-id"
o365 config set auth.tenant "common"
o365 config set scopes.files.all "true"

# Remove a value
o365 config unset scopes.custom

# Edit config file in editor
o365 config edit

# Show config file path
o365 config path

Configuration

Required Setup

Before using o365-cli, you must configure your Azure AD application credentials. There are two ways to do this:

Option 1: Config File (Recommended)

Create ~/.config/o365/config:

[auth]
client_id = your-azure-ad-application-id
tenant = your-azure-ad-tenant-id

[scopes]
# Enable/disable command groups (all enabled by default)
mail = true
calendar = true
contacts = true
chat = true
files = true

# Optional: Enable .All scopes for shared drives/sites (may require admin consent)
files.all = false      # Access shared drives (Files.Read.All, Files.ReadWrite.All)
sites.all = false      # Access SharePoint sites (Sites.Read.All, Sites.ReadWrite.All)

[paths]
# Optional: customize storage locations
# token_file = ~/.config/o365/tokens.json
# mail_dir = ~/.mail/office365/

See config.example for a complete configuration template.

Option 2: Environment Variables

export O365_CLIENT_ID=your-azure-ad-application-id
export O365_TENANT=your-azure-ad-tenant-id

# Optional: customize scopes
export O365_SCOPES="https://graph.microsoft.com/Mail.Read,https://graph.microsoft.com/User.Read,offline_access"

# Optional: customize paths
export O365_TOKEN_FILE=~/.config/o365/tokens.json
export O365_MAIL_DIR=~/.mail/office365/

Priority: Environment variables override config file settings.

Azure App Registration

To use this tool, you need to register an application in Azure Active Directory:

  1. Go to Azure PortalApp registrationsNew registration

  2. Set Redirect URI to: Public client/native (mobile & desktop) with value https://login.microsoftonline.com/common/oauth2/nativeclient

  3. Under API permissions, add these Microsoft Graph delegated permissions:

    • Calendars.Read
    • Calendars.ReadWrite
    • Calendars.ReadWrite.Shared
    • Chat.Read
    • Chat.ReadWrite
    • ChatMessage.Send
    • Contacts.Read
    • Contacts.ReadWrite
    • Files.Read
    • Files.ReadWrite
    • Mail.ReadWrite
    • Mail.Send
    • MailboxSettings.Read
    • User.Read
    • offline_access

    Optional (for shared drives/SharePoint, may require admin consent):

    • Files.Read.All
    • Files.ReadWrite.All
    • Sites.Read.All
    • Sites.ReadWrite.All
  4. Copy the Application (client) ID and Directory (tenant) ID to your config file

Important: After adding new permissions to your Azure AD app or changing scopes in your config file, you must re-authenticate:

o365 auth login

Note: You can request fewer permissions if you only need specific features. For example, for mail-only access:

[scopes]
mail = true
calendar = false
contacts = false
chat = false
files = false

Additional Configuration (Mail Sending)

For o365 mail send, you also need SMTP configuration in ~/.env:

export SMTP_EMAIL=your.email@example.com
export SMTP_PASSWORD=your-app-password
export SMTP_SIGNATURE_FILE=~/.signature.html

Storage Locations

  • Configuration: ~/.config/o365/config
  • OAuth Tokens: ~/.config/o365/tokens.json (default)

All paths can be customized via config file or environment variables.

Note: Email commands now interact directly with Office365 via Graph API rather than syncing to local storage.

MCP Server

The Office 365 MCP (Model Context Protocol) Server enables natural language interaction with your Office 365 account through Claude Desktop and other MCP-compatible clients.

What is MCP?

Model Context Protocol (MCP) is an open protocol developed by Anthropic that allows AI assistants like Claude to securely connect to external data sources and tools. With the Office 365 MCP server, you can use natural language to:

  • Check and manage your emails
  • View and create calendar events
  • Search and manage files in OneDrive
  • Read and send Teams messages
  • Search contacts
  • Access meeting recordings and transcripts

Quick Setup

  1. Install with MCP support:
pip install git+https://github.com/shitchell/o365-cli.git
pip install "o365-cli[mcp]"
  1. Authenticate with Office 365:
o365 auth login
  1. Configure Claude Desktop:

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or equivalent:

{
  "mcpServers": {
    "office365": {
      "command": "/path/to/o365-mcp"
    }
  }
}

Find your path with: which o365-mcp

  1. Restart Claude Desktop and look for the 🔨 icon to see 20 available Office 365 tools!

Available Tools

The MCP server provides 20 tools across 6 categories:

Category Tools Examples
📧 Email read_emails, get_email_content, send_email "Check unread emails from last week"
📅 Calendar list_calendar_events, create_calendar_event, delete_calendar_event "What meetings do I have tomorrow?"
📁 Files list_onedrive_files, search_onedrive, download_onedrive_file, upload_onedrive_file "Search OneDrive for budget files"
💬 Teams Chat list_teams_chats, read_chat_messages, send_chat_message, search_teams_messages "Show recent Teams messages"
👥 Contacts search_contacts, list_contacts "Find John Doe's email"
🎥 Recordings list_recordings, search_recordings, download_recording, get_recording_transcript "List last week's meeting recordings"

Example Queries

Once configured, you can ask Claude Desktop questions like:

What unread emails do I have from the last 2 days?

Show me my calendar for next week

Search my OneDrive for files containing "quarterly report"

What are my recent Teams chats?

Create a meeting tomorrow at 2pm titled "Project Sync" with john@example.com

List my Teams meeting recordings from last month

Documentation

Entry Points

The MCP server can be started two ways:

# Dedicated command
o365-mcp

# Subcommand
o365 mcp

Both start the same MCP server. Claude Desktop will use the configured command automatically.

Architecture

The o365 command is implemented as a Python package with the following structure:

o365/
├── __init__.py       # Package initialization
├── __main__.py       # Main entry point and command routing
├── common.py         # Shared utilities (auth, API calls, constants)
├── mail.py           # Mail command implementations
├── calendar.py       # Calendar command implementations
├── contacts.py       # Contacts command implementations
├── chat.py           # Teams chat command implementations
├── files.py          # OneDrive/SharePoint command implementations
├── recordings.py     # Meeting recordings command implementations
├── auth.py           # Authentication command implementations
├── config_cmd.py     # Configuration command implementations
└── mcp_server.py     # MCP server implementation (20 tools, 3 prompts, 1 resource)

Each module provides both CLI commands and structured data functions, enabling both command-line usage and MCP integration.

Requirements

Core Requirements

  • Python 3.10+ (3.10+ required for MCP server)
  • python-dateutil for time parsing
  • html2text for email content conversion

Optional Requirements

  • mcp SDK for MCP server functionality (install with pip install "o365-cli[mcp]")

Development Requirements

  • pytest for testing
  • pytest-mock for test mocking
  • black for code formatting
  • flake8 for linting

Development

Running Tests

pytest

Code Formatting

black o365/

Linting

flake8 o365/

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgments

  • Uses Microsoft Graph API for Office365 integration
  • Device code flow for terminal-friendly OAuth2 authentication
  • HTML to text conversion via html2text library

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

o365_cli-1.0.1.tar.gz (71.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

o365_cli-1.0.1-py3-none-any.whl (61.2 kB view details)

Uploaded Python 3

File details

Details for the file o365_cli-1.0.1.tar.gz.

File metadata

  • Download URL: o365_cli-1.0.1.tar.gz
  • Upload date:
  • Size: 71.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.4

File hashes

Hashes for o365_cli-1.0.1.tar.gz
Algorithm Hash digest
SHA256 1c4813866769886adfecfa5b7cdb8cd54a8031e90724d2ce73a0f7fe9ee00628
MD5 3c47a7dfd83577df3afc74c52164472e
BLAKE2b-256 e8a3e7f31dac00d2ae9320f997e09721704bc8599e7eae9f7c856a942cf9b5bc

See more details on using hashes here.

File details

Details for the file o365_cli-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: o365_cli-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 61.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.4

File hashes

Hashes for o365_cli-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 698d86a96ac6e78a003eb500c64fdd55836d68f89494dac1c47bf0495fc8cc81
MD5 e69de6498e47e47e4f362be2e8bb0e33
BLAKE2b-256 8f62ad7fdb9bca9bab518b323f1a4f5d80b308f0eb8f681519285f93c8d8cc15

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page