@mhdd_24/m365-mcp
v1.0.0
Published
MCP server for Microsoft Outlook and Teams via Microsoft Graph API
Maintainers
Readme
@mhdd_24/m365-mcp
Custom MCP server for Microsoft Outlook and Microsoft Teams via the Microsoft Graph API. Built with the same architecture as @mhdd_24/timelog-mcp.
Use it from Cursor, Claude Desktop, or any MCP-compatible client.
Tools (10)
| Tool | Domain | Description |
|------|--------|-------------|
| whoami | Profile | Signed-in user profile |
| list_inbox | Outlook | Recent inbox messages |
| read_email | Outlook | Read a message by ID |
| send_email | Outlook | Send email |
| list_calendar | Outlook | Calendar events for a date range |
| list_teams | Teams | Joined teams |
| list_teams_chats | Teams | Direct/group chats |
| send_teams_chat | Teams | Message a chat |
| list_channels | Teams | Channels in a team |
| send_channel_message | Teams | Post to a channel |
Prerequisites
| Requirement | Notes |
|-------------|--------|
| Node.js 18+ | Native fetch |
| Azure App Registration | Public client (device code flow) |
| Graph API permissions | See below |
| Admin consent | May be required in your org |
Azure App Registration
- Azure Portal → Entra ID → App registrations → New registration
- Name:
Cursor M365 MCP - Supported account types: Single tenant (recommended)
- No redirect URI required for device code flow
- Authentication → Enable Allow public client flows → Yes
- API permissions → Microsoft Graph → Delegated:
| Permission | Purpose |
|--------------|---------|
| User.Read | Profile |
| Mail.Read | Read inbox |
| Mail.Send | Send email |
| Calendars.Read | Calendar |
| Chat.Read, Chat.ReadWrite, ChatMessage.Send | Teams chats |
| Team.ReadBasic.All | List teams |
| Channel.ReadBasic.All, ChannelMessage.Send | Channels |
- Grant admin consent if required
- Copy Application (client) ID and Directory (tenant) ID
Install
git clone https://github.com/Mhdd-24/M365-MCP.git
cd m365-mcp
npm install
npm run buildOr after publish:
npx @mhdd_24/m365-mcpConfigure Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"m365": {
"command": "npx",
"args": ["-y", "@mhdd_24/m365-mcp"],
"env": {
"M365_CLIENT_ID": "<azure-app-client-id>",
"M365_TENANT_ID": "<azure-tenant-id>"
}
}
}
}Local development:
"command": "node",
"args": ["C:/path/to/m365-mcp/dist/index.js"]First-time sign-in
On first tool call, the server prints a device code URL to stderr. Open the link, enter the code, and sign in with your work account.
Or sign in ahead of time:
cp .env.example .env
# fill M365_CLIENT_ID and M365_TENANT_ID
npm run loginToken cache: ~/.m365-mcp/msal-cache.json
Environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| M365_CLIENT_ID | Yes | Azure app client ID |
| M365_TENANT_ID | Yes | Azure tenant ID |
| M365_GRAPH_BASE_URL | No | Default https://graph.microsoft.com/v1.0 |
| M365_TOKEN_CACHE_PATH | No | Custom token cache file path |
Example prompts
Outlook
List my unread emails.
Send an email to [email protected] — subject "Sprint review", body "Meeting at 3pm."
What's on my calendar today?
Teams
List my Teams.
Send a Teams chat message: "PR is ready for review" to chat ID …
Post "Deploy complete" to the General channel in team …
Project structure
m365-mcp/
├── src/
│ ├── index.ts
│ ├── env.ts
│ ├── config/m365.config.ts
│ ├── interfaces/graph.ts
│ ├── services/
│ │ ├── authService.ts ← OAuth device code + MSAL cache
│ │ ├── graphClient.ts ← Graph HTTP wrapper
│ │ └── graphService.ts ← Mail, calendar, Teams APIs
│ ├── tools/ ← MCP tool handlers
│ └── scripts/login.ts
├── package.json
└── README.mdLicense
ISC
