Skip to content

Repository files navigation

o365-mcp: Outlook + Teams MCP Server

An MCP server providing access to Microsoft Outlook email, calendar, and Teams messages via Microsoft Graph API.

Setup

1. Azure AD App Registration

First, create an app registration in your Azure AD tenant:

  1. Go to portal.azure.com
  2. Navigate to Azure Active Directory > App registrations > New registration
  3. Configure:
    • Name: o365-mcp
    • Supported account types: "Accounts in this organizational directory only"
  4. Under "Authentication":
    • Redirect URI: Public client/native, value: https://login.microsoftonline.com/{tenant}/oauth2/nativeclient (replace {tenant} with your Directory ID)
    • Enable "Allow public client flows"
  5. Under "API permissions", add delegated permissions:
    • Mail.Read
    • Mail.ReadWrite
    • Calendars.Read
    • Calendars.ReadWrite
    • Chat.Read
    • Chat.ReadWrite
    • ChannelMessage.Read.All (requires admin consent)
    • Contacts.Read
    • User.Read
  6. Request admin consent for ChannelMessage.Read.All from your IT team
  7. Note your Application (client) ID and Directory (tenant) ID

2. Build and Install

npm install
npm run build

3. First Authentication

Before using with Claude Code, authenticate once to store your token in Keychain:

AZURE_TENANT_ID=<your-tenant-id> \
AZURE_CLIENT_ID=<your-client-id> \
npm run auth

Follow the device code flow in your terminal.

4. Register with Claude Code

Add this to ~/.claude.json:

{
  "mcpServers": {
    "o365": {
      "command": "node",
      "args": ["/Users/nickda/Code/nick-dev/o365-mcp/dist/index.js"],
      "env": {
        "AZURE_TENANT_ID": "<your-tenant-id>",
        "AZURE_CLIENT_ID": "<your-client-id>"
      }
    }
  }
}

Restart Claude Code.

Testing

Integration Tests

AZURE_TENANT_ID=<your-tenant-id> \
AZURE_CLIENT_ID=<your-client-id> \
npm run test

MCP Inspector

Interactively test tools before using in Claude Code:

AZURE_TENANT_ID=<your-tenant-id> \
AZURE_CLIENT_ID=<your-client-id> \
npx @modelcontextprotocol/inspector node dist/index.js

Then visit the Inspector URL in your browser to invoke tools manually.

Tools

Phase 1: Read Tools

  • get_emails - List emails from inbox with filtering
  • get_email - Get full content of a single email
  • search_emails - Full-text search across emails
  • get_calendar_events - List calendar events for a date range
  • get_event - Get full details of a calendar event
  • get_teams_messages - Get messages from Teams chats or channels
  • search_teams_messages - Search across Teams messages
  • get_contacts - Look up a contact by name or email

Phase 2: Write Tools (coming soon)

  • draft_email - Create an email draft
  • send_teams_message - Send a Teams message
  • create_calendar_event - Create a calendar event
  • accept_decline_event - RSVP to a calendar invite

Troubleshooting

"No authenticated account found"

Run: npm run auth

"Insufficient privileges" on Teams channels

Admin consent is required for ChannelMessage.Read.All. Contact your IT team, or use 1:1 chats instead.

Token not found in Keychain

The Keychain implementation uses the keytar npm package. On macOS, this uses the native Keychain. Verify keytar is installed: npm ls keytar

Development

  • npm run build - Compile TypeScript
  • npm run dev - Run with tsx (for development)
  • npm run start - Run compiled server
  • npm run auth - Run authentication flow
  • npm run test - Run integration tests

About

No description, website, or topics provided.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages