From m365
Manages Microsoft 365 mailboxes via Microsoft Graph API: read/search emails, manage shared mailboxes, set out-of-office replies, check sizes, diagnose mail flow issues for MSPs.
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin m365This skill uses the workspace's default tool permissions.
Microsoft 365 mailboxes are managed through Exchange Online, accessible via Microsoft Graph. For MSPs, mailbox tasks range from diagnosing delivery failures and searching for lost emails to managing shared mailboxes and offboarding users. Graph provides a unified API across all mailbox types.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Designs, implements, and audits WCAG 2.2 AA accessible UIs for Web (ARIA/HTML5), iOS (SwiftUI traits), and Android (Compose semantics). Audits code for compliance gaps.
Microsoft 365 mailboxes are managed through Exchange Online, accessible via Microsoft Graph. For MSPs, mailbox tasks range from diagnosing delivery failures and searching for lost emails to managing shared mailboxes and offboarding users. Graph provides a unified API across all mailbox types.
| Type | Description | Common MSP Tasks |
|---|---|---|
| User Mailbox | Standard licensed user | Search, out-of-office, size, rules |
| Shared Mailbox | Team inbox, no license required | Access management, forwarding |
| Room/Equipment | Calendar resource booking | Availability, booking policies |
| Distribution Group | Email alias to multiple users | Membership, send-as |
GET /v1.0/users/{userId}/messages?$select=id,subject,from,receivedDateTime,isRead&$top=25&$orderby=receivedDateTime desc
GET /v1.0/users/{userId}/messages?$search="subject:invoice 2024"&$select=id,subject,from,receivedDateTime
Also supports KQL search operators:
$search="from:john@example.com" — by sender$search="subject:urgent hasAttachments:true" — combined$search="received>=2024-01-01" — date rangeGET /v1.0/users/{userId}/messages/{messageId}?$select=id,subject,from,body,receivedDateTime,attachments
GET /v1.0/users/{userId}/mailboxSettings
Response:
{
"automaticRepliesSetting": {
"status": "disabled",
"internalReplyMessage": "",
"externalReplyMessage": ""
},
"timeZone": "Eastern Standard Time",
"language": { "locale": "en-US" }
}
PATCH /v1.0/users/{userId}/mailboxSettings
Content-Type: application/json
{
"automaticRepliesSetting": {
"status": "alwaysEnabled",
"internalReplyMessage": "<html>I'm out of office until Jan 15.</html>",
"externalReplyMessage": "<html>I'm out of office. For urgent matters contact support@company.com.</html>"
}
}
PATCH /v1.0/users/{userId}/mailboxSettings
Content-Type: application/json
{
"automaticRepliesSetting": { "status": "disabled" }
}
GET /v1.0/users/{userId}/mailFolders/inbox?$select=totalItemCount,sizeInBytes
For full mailbox statistics (requires Exchange admin permissions):
GET /v1.0/reports/getMailboxUsageDetail(period='D7')
GET /v1.0/users/{userId}/mailFolders/inbox/messageRules
Response shows rules that may affect mail delivery:
{
"value": [
{
"id": "rule1",
"displayName": "Move newsletters",
"conditions": { "senderContains": ["newsletter"] },
"actions": { "moveToFolder": "Newsletters" },
"isEnabled": true
}
]
}
POST /v1.0/users/{userId}/sendMail
Content-Type: application/json
{
"message": {
"subject": "Your IT support request has been resolved",
"body": { "contentType": "HTML", "content": "<p>Your ticket #1234 is now closed.</p>" },
"toRecipients": [{ "emailAddress": { "address": "user@contoso.com" } }]
},
"saveToSentItems": true
}
Shared mailbox access is managed via Microsoft 365 admin or Exchange PowerShell, not directly via Graph mailbox endpoints. Use Graph group membership or delegate access patterns.
Access is represented as mailboxPermissions — check via admin APIs or Exchange PowerShell:
Get-MailboxPermission -Identity "sharedmailbox@contoso.com" | Where-Object { $_.AccessRights -eq "FullAccess" }
Look for NDRs (Non-Delivery Reports) in the user's inbox or sent items:
GET /v1.0/users/{userId}/messages?$filter=senderEmailAddress/address eq 'postmaster@domain.com'&$select=subject,receivedDateTime,body
| NDR Code | Meaning | Resolution |
|---|---|---|
5.1.1 | Recipient doesn't exist | Verify UPN / check aliases |
5.1.8 | Sender blocked (spam) | Review anti-spam policy |
5.2.2 | Mailbox full | Check quota, remove items |
5.7.1 | Unauthorized relay | SMTP auth settings |
5.7.606 | Sender IP blocked | Submit to Microsoft for delisting |
Option A: Convert to shared mailbox (no license needed, data accessible)
Option B: Forward and archive
Option C: Auto-reply and close
| Error | Cause | Resolution |
|---|---|---|
MailboxNotEnabledForRESTAPI | User has no Exchange license | Assign Exchange/M365 license |
ErrorItemNotFound | Message ID expired or moved | Search by subject/date instead |
AuthenticationError | Token expired | Re-authenticate via OAuth flow |
TooManyRequests | Graph throttling (429) | Retry with exponential backoff |
Forbidden (403) | Missing Mail.Read permission | Check app registration |
| Task | Microsoft Graph Permission |
|---|---|
| Read emails | Mail.Read or Mail.ReadWrite |
| Send email | Mail.Send |
| Mailbox settings | MailboxSettings.ReadWrite |
| All users' mail (admin) | Mail.Read (delegated + admin consent) |