Skip to main content
Glama

useful-outlook-mcp

A remote MCP server for Microsoft Outlook with proper OAuth2 and agent-optimized tools.

Features

  • Spec Compliant: RFC 9728/8414 OAuth metadata, RFC 7591 dynamic client registration

  • Stateless OAuth: Tokens managed by client, not server—as OAuth intended

  • Agent-Optimized Tools: Extensive prompt engineering in tool descriptions

  • Dynamic Scopes: OAuth scopes auto-adjust to enabled tools

  • Production Ready: Docker, rate limiting, read-only mode, tool filtering

Quick Start

npm install
npm run build
npm start  # Server at http://localhost:3000

Required environment:

MS365_MCP_CLIENT_ID=your-azure-ad-client-id
MS365_MCP_CLIENT_SECRET=your-azure-ad-client-secret
MS365_MCP_TENANT_ID=your-tenant-id  # or 'common'

Azure AD Setup

  1. Azure Portal → Microsoft Entra ID → App registrations → New

  2. Add delegated permissions: User.Read, Mail.Read, Mail.ReadWrite, Mail.Send, Calendars.Read, Calendars.ReadWrite, Calendars.Read.Shared, Place.Read.All, People.Read, offline_access

  3. Add redirect URI: http://localhost:6274/oauth/callback (for MCP Inspector)

  4. Certificates & secrets → New client secret → Copy the value

  5. Copy Client ID, Client Secret, and Tenant ID to your .env

Tools

Mail

list-mail-folders · list-mail-messages · search-mail · get-mail-message · send-mail · create-draft-mail · reply-mail · reply-all-mail · create-reply-draft · create-reply-all-draft · delete-mail-message · move-mail-message

Calendar

list-calendars · list-calendar-events · search-calendar-events · find-meeting-times · get-calendar-event · get-calendar-view · create-calendar-event · update-calendar-event · delete-calendar-event

People

lookup-contact-email

For in-person meetings, find-meeting-times automatically:

  • Fetches all available meeting rooms across your organization

  • Includes them in availability checks alongside attendees

  • Groups free rooms by location (city/building)

  • Returns only available rooms with email addresses for booking

Set isOnlineMeeting: false to enable room search. For online meetings (default: true), Teams meeting links are automatically generated.

Required scope: Place.Read.All (add to Azure AD app permissions)

Configuration

Variable

Default

Description

MS365_MCP_CLIENT_ID

required

Azure AD client ID

MS365_MCP_CLIENT_SECRET

-

Client secret (optional)

MS365_MCP_TENANT_ID

common

Tenant ID

MS365_MCP_PORT

3000

Server port

MS365_MCP_READ_ONLY_MODE

false

Disable write operations

MS365_MCP_ENABLED_TOOLS

all

Comma-separated tool allowlist

MS365_MCP_CORS_ORIGIN

*

CORS origins

MS365_MCP_RATE_LIMIT_REQUESTS

30

Requests per window

MS365_MCP_RATE_LIMIT_WINDOW_MS

60000

Window size (ms)

MS365_MCP_ALLOWED_TENANTS

-

Restrict to specific tenants

Docker

From GitHub Container Registry:

docker run -p 3000:3000 \
  -e MS365_MCP_CLIENT_ID=xxx \
  -e MS365_MCP_CLIENT_SECRET=xxx \
  -e MS365_MCP_TENANT_ID=xxx \
  ghcr.io/Leonine-Studios/useful-outlook-mcp:latest

Or build locally:

docker build -t useful-outlook-mcp .
docker run -p 3000:3000 \
  -e MS365_MCP_CLIENT_ID=xxx \
  -e MS365_MCP_CLIENT_SECRET=xxx \
  -e MS365_MCP_TENANT_ID=xxx \
  useful-outlook-mcp

Endpoints

Endpoint

Description

POST /mcp

MCP protocol

GET /health

Health check

GET /.well-known/oauth-protected-resource

RFC 9728

GET /.well-known/oauth-authorization-server

RFC 8414

GET /authorize

OAuth (proxies to Microsoft)

POST /token

Token exchange (proxies to Microsoft)

POST /register

Dynamic client registration

Testing

npm run dev
npx @modelcontextprotocol/inspector  # Connect to http://localhost:3000/mcp

Design Notes

Problems with existing servers

  1. Legacy architecture: Built as stdio with HTTP bolted on. This is HTTP-native.

  2. OAuth done wrong: Most servers store tokens server-side. This server is stateless—tokens passed per-request via Authorization header, never stored.

  3. Tools without thought: Typical servers map API endpoints 1:1 without guidance. Agents fail in practical use because they don't know API quirks or multi-step workflows.

What's different

Every tool includes:

  • When to use it vs alternatives

  • Known Graph API quirks (there are many)

  • Workflow guidance for multi-step tasks

  • Parameter combinations that fail

Example: find-meeting-times explains that email addresses are required (names don't work), how to find emails from names using search-mail, what OrganizerUnavailable means, and that isOrganizerOptional=true needs user confirmation.

Known Graph API quirks

  • Mail sender filtering: eq on from/emailAddress/address is unreliable—uses startswith()

  • Mail recipient filtering: Can't filter to/cc/bcc with $filter—must use $search

  • Calendar organizer filtering: $filter on organizer email returns 500—filtered client-side

  • Concurrency: Parallel calls can return MailboxConcurrency errors

  • Search + sort: $search can't combine with $orderby

License

MIT

-
security - not tested
F
license - not found
-
quality - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Leonine-Studios/outlook-oauth-remote-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server