loading…
Search for a command to run...
loading…
MCP server that connects to Microsoft Office and the whole Microsoft 365 suite using Graph API (including Outlook, mail, files, Excel, calendar)
MCP server that connects to Microsoft Office and the whole Microsoft 365 suite using Graph API (including Outlook, mail, files, Excel, calendar)
npm version build status license
Microsoft 365 MCP Server
A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Microsoft Office services through the Graph API.
This server supports multiple Microsoft cloud environments:
| Cloud | Description | Auth Endpoint | Graph API Endpoint |
|---|---|---|---|
| Global (default) | International Microsoft 365 | login.microsoftonline.com | graph.microsoft.com |
| China (21Vianet) | Microsoft 365 operated by 21Vianet | login.chinacloudapi.cn | microsoftgraph.chinacloudapi.cn |
The server supports two output formats that can be configured globally:
Standard JSON output with pretty-printing:
{
"value": [
{
"id": "1",
"displayName": "Alice Johnson",
"mail": "[email protected]",
"jobTitle": "Software Engineer"
}
]
}
Token-Oriented Object Notation for efficient LLM token usage:
value[1]{id,displayName,mail,jobTitle}:
"1",Alice Johnson,[email protected],Software Engineer
Benefits:
Usage: (experimental) Enable TOON format globally:
Via CLI flag:
npx @softeria/ms-365-mcp-server --toon
Via Claude Desktop configuration:
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@softeria/ms-365-mcp-server", "--toon"]
}
}
}
Via environment variable:
MS365_MCP_OUTPUT_FORMAT=toon npx @softeria/ms-365-mcp-server
The server provides 200+ tools covering most of the Microsoft Graph API surface. Each tool maps 1-to-1 to a Graph API endpoint and is defined declaratively in src/endpoints.json.
Email (Outlook), Calendar, OneDrive Files, Excel, OneNote, To Do Tasks, Planner, Contacts, User Profile, Search
Teams & Chats, Online Meetings, Transcripts & Recordings, Attendance Reports, SharePoint Sites & Lists, Shared Mailboxes & Calendars, User Management, Presence, Virtual Events
Permissions are requested dynamically based on which tools are enabled. Use --list-permissions to see the exact permissions for your configuration:
# Personal mode (default)
npx @softeria/ms-365-mcp-server --list-permissions
# Organization mode (includes Teams, SharePoint, etc.)
npx @softeria/ms-365-mcp-server --org-mode --list-permissions
# Filtered by preset
npx @softeria/ms-365-mcp-server --preset mail --list-permissions
This is useful for enterprise environments where Graph API permissions must be pre-approved and admin-consented before deploying a new version.
To access work/school features (Teams, SharePoint, etc.), enable organization mode using any of these flags:
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@softeria/ms-365-mcp-server", "--org-mode"]
}
}
}
Organization mode must be enabled from the start to access work account features. Without this flag, only personal account features (email, calendar, OneDrive, etc.) are available.
To access shared mailboxes, you need:
--org-mode flag (work/school accounts only)Mail.Read.Shared or Mail.Send.Shared scopesuser-id parameter in the shared mailbox toolsFinding shared mailboxes: Use the list-users tool to discover available users and shared mailboxes in your
organization.
Example: list-shared-mailbox-messages with user-id set to [email protected]
Test login in Claude Desktop:
To add this MCP server to Claude Desktop, edit the config file under Settings > Developer.
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@softeria/ms-365-mcp-server"]
}
}
}
{
"mcpServers": {
"ms365": {
"command": "npx",
"args": ["-y", "@softeria/ms-365-mcp-server", "--org-mode"]
}
}
}
{
"mcpServers": {
"ms365-china": {
"command": "npx",
"args": ["-y", "@softeria/ms-365-mcp-server", "--org-mode", "--cloud", "china"]
}
}
}
claude mcp add ms365 -- npx -y @softeria/ms-365-mcp-server
# macOS/Linux
claude mcp add ms365 -- npx -y @softeria/ms-365-mcp-server --org-mode
# Windows (use cmd /c wrapper)
claude mcp add ms365 -s user -- cmd /c "npx -y @softeria/ms-365-mcp-server --org-mode"
# macOS/Linux
claude mcp add ms365-china -- npx -y @softeria/ms-365-mcp-server --org-mode --cloud china
# Windows (use cmd /c wrapper)
claude mcp add ms365-china -s user -- cmd /c "npx -y @softeria/ms-365-mcp-server --org-mode --cloud china"
For other interfaces that support MCPs, please refer to their respective documentation for the correct integration method.
Open WebUI supports MCP servers via HTTP transport with OAuth 2.1.
Start the server with HTTP mode:
npx @softeria/ms-365-mcp-server --http
In Open WebUI, go to Admin Settings → Tools (/admin/settings/tools) → Add Connection:
/mcp pathClick Register Client.
Note: Dynamic client registration is enabled by default in HTTP mode. Use
--no-dynamic-registrationto disable it. If using a custom Azure Entra app, add your redirect URI under "Mobile and desktop applications" platform (not "Single-page application").
Quick test setup using the default Azure app (ID ms-365 and localhost:8080 are pre-configured):
docker run -d -p 8080:8080 \
-e WEBUI_AUTH=false \
-e OPENAI_API_KEY \
ghcr.io/open-webui/open-webui:main
npx @softeria/ms-365-mcp-server --http
Then add connection with URL http://localhost:3000/mcp and ID ms-365.
Running in Docker behind a reverse proxy? Set
--public-url https://your-domain.comso the OAuth authorize URL handed to the user's browser is reachable from outside the container network. See docs/deployment.md for the full guide.
For local development or testing:
# From the project directory
claude mcp add ms -- npx tsx src/index.ts --org-mode
Or configure Claude Desktop manually:
{
"mcpServers": {
"ms365": {
"command": "node",
"args": ["/absolute/path/to/ms-365-mcp-server/dist/index.js", "--org-mode"]
}
}
}
Note: Run
npm run buildafter code changes to update thedist/folder.
⚠️ You must authenticate before using tools.
The server supports three authentication methods:
For interactive authentication via device code:
login tool (auto-checks existing token)verify-login tool to confirmnpx @softeria/ms-365-mcp-server --login
Follow the URL and code prompt in the terminal.Tokens are cached securely in your OS credential store (fallback to file).
When running with --http, the server requires OAuth authentication:
npx @softeria/ms-365-mcp-server --http 3000
This mode:
/auth/* (authorize, token, metadata)Authorization: Bearer <token> for all MCP requests--enable-auth-tools to enable them)MCP clients will automatically handle the OAuth flow when they see the advertised capabilities.
To use OAuth mode with custom Azure credentials (recommended for production), you'll need to set up an Azure AD app registration:
npm run inspector):http://localhost:6274/oauth/callbackhttp://localhost:6274/oauth/callback/debughttp://localhost:3000/callback (optional, for server callback).env file in your project root:MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here
MS365_MCP_CLIENT_SECRET=your-secret-here # Optional for public apps
MS365_MCP_TENANT_ID=common
With these configured, the server will use your custom Azure app instead of the built-in one.
If you are running ms-365-mcp-server as part of a larger system that manages Microsoft OAuth tokens externally, you can provide an access token directly to this MCP server:
MS365_MCP_OAUTH_TOKEN=your_oauth_token npx @softeria/ms-365-mcp-server
This method:
Note: HTTP mode requires authentication. For unauthenticated testing, use stdio mode with device code flow.
Authentication Tools: In HTTP mode, login/logout tools are disabled by default since OAuth handles authentication. Use
--enable-auth-toolsif you need them available.
Use a single server instance to serve multiple Microsoft accounts. When more than one account is logged in, an account parameter is automatically injected into every tool, allowing you to specify which account to use per tool call.
Login multiple accounts (one-time per account):
# Login first account (device code flow)
npx @softeria/ms-365-mcp-server --login
# Follow the device code prompt, sign in as [email protected]
# Login second account
npx @softeria/ms-365-mcp-server --login
# Follow the device code prompt, sign in as [email protected]
List configured accounts:
npx @softeria/ms-365-mcp-server --list-accounts
Use in tool calls: Pass "account": "[email protected]" in any tool request:
{ "tool": "list-mail-messages", "arguments": { "account": "[email protected]" } }
Behavior:
account parameter needed).account parameter, the server uses the selected default or returns a helpful error listing available accounts.account parameter accepts email address (e.g. [email protected]) or MSAL homeAccountId.For MCP multiplexers (Legate, Governor): Multi-account mode replaces the N-process pattern. Instead of spawning one server per account, a single instance handles all accounts via the
accountparameter, reducing tool duplication from N×110 to 110.
To reduce initial connection overhead, use preset tool categories instead of loading all 90+ tools:
npx @softeria/ms-365-mcp-server --preset mail
npx @softeria/ms-365-mcp-server --list-presets # See all available presets
Available presets: mail, calendar, files, personal, work, excel, contacts, tasks, onenote, search, users, all
Instead of loading all 90+ tools upfront, use dynamic discovery so the LLM finds and loads tools only when it needs them:
npx @softeria/ms-365-mcp-server --discovery
Keeps the initial context small and cuts token usage, especially useful for long sessions or cost-sensitive setups (e.g. Open WebUI running against a paid API).
The following options can be used when running ms-365-mcp-server directly from the command line:
--login Login using device code flow
--logout Log out and clear saved credentials
--verify-login Verify login without starting the server
--list-permissions List all required Graph API permissions and exit (respects --org-mode, --preset, --enabled-tools)
--org-mode Enable organization/work mode from start (includes Teams, SharePoint, etc.)
--work-mode Alias for --org-mode
--force-work-scopes Backwards compatibility alias for --org-mode (deprecated)
--cloud <type> Microsoft cloud environment: global (default) or china (21Vianet)
When running as an MCP server, the following options can be used:
-v Enable verbose logging
--read-only Start server in read-only mode, disabling write operations
--http [port] Use Streamable HTTP transport instead of stdio (optionally specify port, default: 3000)
Starts Express.js server with MCP endpoint at /mcp
--enable-auth-tools Enable login/logout tools when using HTTP mode (disabled by default in HTTP mode)
--no-dynamic-registration Disable OAuth Dynamic Client Registration (enabled by default in HTTP mode)
--enabled-tools <pattern> Filter tools using regex pattern (e.g., "excel|contact" to enable Excel and Contact tools)
--preset <names> Use preset tool categories (comma-separated). See "Tool Presets" section above
--list-presets List all available presets and exit
--toon (experimental) Enable TOON output format for 30-60% token reduction
--discovery Dynamic tool discovery: loads tools on demand to reduce initial token usage (see "Dynamic Tool Discovery" above)
--public-url <url> Public base URL for OAuth when behind a reverse proxy (see Open WebUI section and docs/deployment.md)
Environment variables:
READ_ONLY=true|1: Alternative to --read-only flagENABLED_TOOLS: Filter tools using a regex pattern (alternative to --enabled-tools flag)MS365_MCP_ORG_MODE=true|1: Enable organization/work mode (alternative to --org-mode flag)MS365_MCP_FORCE_WORK_SCOPES=true|1: Backwards compatibility for MS365_MCP_ORG_MODEMS365_MCP_OUTPUT_FORMAT=toon: Enable TOON output format (alternative to --toon flag)MS365_MCP_MAX_TOP=<n>: Hard cap for Graph $top / top on list requests (positive integer). When the model passes a larger value, the server clamps it to n so responses stay smaller. Example: MS365_MCP_MAX_TOP=15MS365_MCP_BODY_FORMAT=html: Return email bodies as HTML instead of plain text (default: text)MS365_MCP_CLOUD_TYPE=global|china: Microsoft cloud environment (alternative to --cloud flag)LOG_LEVEL: Set logging level (default: 'info')SILENT=true|1: Disable console outputMS365_MCP_CLIENT_ID: Custom Azure app client ID (defaults to built-in app)MS365_MCP_TENANT_ID: Custom tenant ID (defaults to 'common' for multi-tenant)MS365_MCP_OAUTH_TOKEN: Pre-existing OAuth token for Microsoft Graph API (BYOT method)MS365_MCP_KEYVAULT_URL: Azure Key Vault URL for secrets management (see Azure Key Vault section)MS365_MCP_TOKEN_CACHE_PATH: Custom file path for MSAL token cache (see Token Storage below)MS365_MCP_SELECTED_ACCOUNT_PATH: Custom file path for selected account metadata (see Token Storage below)Authentication tokens are stored using the OS credential store (via keytar) when available. If keytar is not installed or fails (common on headless Linux), the server falls back to file-based storage.
Default fallback paths are relative to the installed package directory. This means tokens can be lost when the package is reinstalled or updated via npm.
To persist tokens across updates, set custom paths outside the package directory:
export MS365_MCP_TOKEN_CACHE_PATH="$HOME/.config/ms365-mcp/.token-cache.json"
export MS365_MCP_SELECTED_ACCOUNT_PATH="$HOME/.config/ms365-mcp/.selected-account.json"
Parent directories are created automatically. Files are written with 0600 permissions.
Security note: File-based token storage writes sensitive credentials to disk. Ensure the chosen directory has appropriate access controls. The OS credential store (keytar) is preferred when available.
Hosted/sandboxed environments (e.g. Anthropic Cowork): Set
MS365_MCP_TOKEN_CACHE_PATHandMS365_MCP_SELECTED_ACCOUNT_PATHto a persistent mount so tokens survive between sessions.
For production deployments, you can store secrets in Azure Key Vault instead of environment variables. This is particularly useful for Azure Container Apps with managed identity.
Create a Key Vault (if you don't have one):
az keyvault create --name your-keyvault-name --resource-group your-rg --location eastus
Add secrets to Key Vault:
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-id --value "your-client-id"
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-tenant-id --value "your-tenant-id"
# Optional: if using confidential client flow
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-secret --value "your-secret"
Grant access to Key Vault:
For Azure Container Apps with managed identity:
# Get the managed identity principal ID
PRINCIPAL_ID=$(az containerapp show --name your-app --resource-group your-rg --query identity.principalId -o tsv)
# Grant access to Key Vault secrets
az keyvault set-policy --name your-keyvault-name --object-id $PRINCIPAL_ID --secret-permissions get list
For local development with Azure CLI:
# Your Azure CLI identity already has access if you have appropriate RBAC roles
az login
Configure the server:
MS365_MCP_KEYVAULT_URL=https://your-keyvault-name.vault.azure.net npx @softeria/ms-365-mcp-server
| Key Vault Secret Name | Environment Variable | Required |
|---|---|---|
| ms365-mcp-client-id | MS365_MCP_CLIENT_ID | Yes |
| ms365-mcp-tenant-id | MS365_MCP_TENANT_ID | No (defaults to 'common') |
| ms365-mcp-client-secret | MS365_MCP_CLIENT_SECRET | No |
The Key Vault integration uses DefaultAzureCredential from the Azure Identity SDK, which automatically tries multiple authentication methods in order:
The Azure Key Vault packages (@azure/identity and @azure/keyvault-secrets) are optional dependencies. They are only loaded when MS365_MCP_KEYVAULT_URL is configured. If you don't use Key Vault, these packages are not required.
See docs/deployment.md for a full guide to hosting the server for organization-wide access, including Docker, Azure Container Apps, Azure App Service, Azure AD app registration, reverse proxy setup, client configuration, and exposed endpoints.
We welcome contributions! Before submitting a pull request, please ensure your changes meet our quality standards.
Run the verification script to check all code quality requirements:
npm run verify
After cloning the repository, you may need to generate the client code from the Microsoft Graph OpenAPI specification:
npm run generate
If you're having problems or need help:
MIT © 2026 Softeria
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"softeria-ms-365-mcp-server": {
"command": "npx",
"args": []
}
}
}Read, send and search emails from Claude
Send, search and summarize Slack messages
No-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)