Microsoft 365 MCP Server A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Microsoft Office services through the Graph This server supports multiple Microsoft cloud environments: - Node.js >= 20 (recommended) - Node.js 14+ may work with dependency warnings - Authentication via Microsoft Authentication Library (MSAL) - Comprehensive Microsoft 365 service integration - Rea
Add this skill
npx mdskills install softeria/ms-365-mcp-serverComprehensive Microsoft 365 integration with extensive tool coverage, OAuth support, and multi-cloud capabilities
1# ms-365-mcp-server23[](https://www.npmjs.com/package/@softeria/ms-365-mcp-server) [](https://github.com/softeria/ms-365-mcp-server/actions/workflows/build.yml) [](https://github.com/softeria/ms-365-mcp-server/blob/main/LICENSE)45Microsoft 365 MCP Server67A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Microsoft Office services through the Graph8API.910## Supported Clouds1112This server supports multiple Microsoft cloud environments:1314| Cloud | Description | Auth Endpoint | Graph API Endpoint |15| -------------------- | ---------------------------------- | ------------------------- | ------------------------------- |16| **Global** (default) | International Microsoft 365 | login.microsoftonline.com | graph.microsoft.com |17| **China** (21Vianet) | Microsoft 365 operated by 21Vianet | login.chinacloudapi.cn | microsoftgraph.chinacloudapi.cn |1819## Prerequisites2021- Node.js >= 20 (recommended)22- Node.js 14+ may work with dependency warnings2324## Features2526- Authentication via Microsoft Authentication Library (MSAL)27- Comprehensive Microsoft 365 service integration28- Read-only mode support for safe operations29- Tool filtering for granular access control3031## Output Format: JSON vs TOON3233The server supports two output formats that can be configured globally:3435### JSON Format (Default)3637Standard JSON output with pretty-printing:3839```json40{41 "value": [42 {43 "id": "1",44 "displayName": "Alice Johnson",45 "mail": "alice@example.com",46 "jobTitle": "Software Engineer"47 }48 ]49}50```5152### (experimental) TOON Format5354[Token-Oriented Object Notation](https://github.com/toon-format/toon) for efficient LLM token usage:5556```57value[1]{id,displayName,mail,jobTitle}:58 "1",Alice Johnson,alice@example.com,Software Engineer59```6061**Benefits:**6263- 30-60% fewer tokens vs JSON64- Best for uniform array data (lists of emails, calendar events, files, etc.)65- Ideal for cost-sensitive applications at scale6667**Usage:**68(experimental) Enable TOON format globally:6970Via CLI flag:7172```bash73npx @softeria/ms-365-mcp-server --toon74```7576Via Claude Desktop configuration:7778```json79{80 "mcpServers": {81 "ms365": {82 "command": "npx",83 "args": ["-y", "@softeria/ms-365-mcp-server", "--toon"]84 }85 }86}87```8889Via environment variable:9091```bash92MS365_MCP_OUTPUT_FORMAT=toon npx @softeria/ms-365-mcp-server93```9495## Supported Services & Tools9697### Personal Account Tools (Available by default)9899**Email (Outlook)**100<sub>list-mail-messages, list-mail-folders, list-mail-folder-messages, get-mail-message, send-mail,101delete-mail-message, create-draft-email, move-mail-message</sub>102103**Calendar**104<sub>list-calendars, list-calendar-events, get-calendar-event, get-calendar-view, create-calendar-event,105update-calendar-event, delete-calendar-event</sub>106107**OneDrive Files**108<sub>list-drives, get-drive-root-item, list-folder-files, download-onedrive-file-content, upload-file-content,109upload-new-file, delete-onedrive-file</sub>110111**Excel Operations**112<sub>list-excel-worksheets, get-excel-range, create-excel-chart, format-excel-range, sort-excel-range</sub>113114**OneNote**115<sub>list-onenote-notebooks, list-onenote-notebook-sections, list-onenote-section-pages, get-onenote-page-content,116create-onenote-page</sub>117118**To Do Tasks**119<sub>list-todo-task-lists, list-todo-tasks, get-todo-task, create-todo-task, update-todo-task, delete-todo-task</sub>120121**Planner**122<sub>list-planner-tasks, get-planner-plan, list-plan-tasks, get-planner-task, create-planner-task</sub>123124**Contacts**125<sub>list-outlook-contacts, get-outlook-contact, create-outlook-contact, update-outlook-contact,126delete-outlook-contact</sub>127128**User Profile**129<sub>get-current-user</sub>130131**Search**132<sub>search-query</sub>133134### Organization Account Tools (Requires --org-mode flag)135136**Teams & Chats**137<sub>list-chats, get-chat, list-chat-messages, get-chat-message, send-chat-message, list-chat-message-replies,138reply-to-chat-message, list-joined-teams, get-team, list-team-channels, get-team-channel, list-channel-messages,139get-channel-message, send-channel-message, list-team-members</sub>140141**SharePoint Sites**142<sub>search-sharepoint-sites, get-sharepoint-site, get-sharepoint-site-by-path, list-sharepoint-site-drives,143get-sharepoint-site-drive-by-id, list-sharepoint-site-items, get-sharepoint-site-item, list-sharepoint-site-lists,144get-sharepoint-site-list, list-sharepoint-site-list-items, get-sharepoint-site-list-item,145get-sharepoint-sites-delta</sub>146147**Shared Mailboxes**148<sub>list-shared-mailbox-messages, list-shared-mailbox-folder-messages, get-shared-mailbox-message,149send-shared-mailbox-mail</sub>150151**User Management**152<sub>list-users</sub>153154## Organization/Work Mode155156To access work/school features (Teams, SharePoint, etc.), enable organization mode using any of these flags:157158```json159{160 "mcpServers": {161 "ms365": {162 "command": "npx",163 "args": ["-y", "@softeria/ms-365-mcp-server", "--org-mode"]164 }165 }166}167```168169Organization mode must be enabled from the start to access work account features. Without this flag, only personal170account features (email, calendar, OneDrive, etc.) are available.171172## Shared Mailbox Access173174To access shared mailboxes, you need:1751761. **Organization mode**: Shared mailbox tools require `--org-mode` flag (work/school accounts only)1772. **Delegated permissions**: `Mail.Read.Shared` or `Mail.Send.Shared` scopes1783. **Exchange permissions**: The signed-in user must have been granted access to the shared mailbox1794. **Usage**: Use the shared mailbox's email address as the `user-id` parameter in the shared mailbox tools180181**Finding shared mailboxes**: Use the `list-users` tool to discover available users and shared mailboxes in your182organization.183184Example: `list-shared-mailbox-messages` with `user-id` set to `shared-mailbox@company.com`185186## Quick Start Example187188Test login in Claude Desktop:189190191192## Examples193194195196## Integration197198### Claude Desktop199200To add this MCP server to Claude Desktop, edit the config file under Settings > Developer.201202#### Personal Account (MSA)203204```json205{206 "mcpServers": {207 "ms365": {208 "command": "npx",209 "args": ["-y", "@softeria/ms-365-mcp-server"]210 }211 }212}213```214215#### Work/School Account (Global)216217```json218{219 "mcpServers": {220 "ms365": {221 "command": "npx",222 "args": ["-y", "@softeria/ms-365-mcp-server", "--org-mode"]223 }224 }225}226```227228#### Work/School Account (China 21Vianet)229230```json231{232 "mcpServers": {233 "ms365-china": {234 "command": "npx",235 "args": ["-y", "@softeria/ms-365-mcp-server", "--org-mode", "--cloud", "china"]236 }237 }238}239```240241### Claude Code CLI242243#### Personal Account (MSA)244245```bash246claude mcp add ms365 -- npx -y @softeria/ms-365-mcp-server247```248249#### Work/School Account (Global)250251```bash252# macOS/Linux253claude mcp add ms365 -- npx -y @softeria/ms-365-mcp-server --org-mode254255# Windows (use cmd /c wrapper)256claude mcp add ms365 -s user -- cmd /c "npx -y @softeria/ms-365-mcp-server --org-mode"257```258259#### Work/School Account (China 21Vianet)260261```bash262# macOS/Linux263claude mcp add ms365-china -- npx -y @softeria/ms-365-mcp-server --org-mode --cloud china264265# Windows (use cmd /c wrapper)266claude mcp add ms365-china -s user -- cmd /c "npx -y @softeria/ms-365-mcp-server --org-mode --cloud china"267```268269For other interfaces that support MCPs, please refer to their respective documentation for the correct270integration method.271272### Open WebUI273274Open WebUI supports MCP servers via HTTP transport with OAuth 2.1.2752761. Start the server with HTTP mode and dynamic registration enabled:277278 ```bash279 npx @softeria/ms-365-mcp-server --http --enable-dynamic-registration280 ```2812822. In Open WebUI, go to **Admin Settings → Tools** (`/admin/settings/tools`) → **Add Connection**:283 - **Type**: MCP Streamable HTTP284 - **URL**: Your MCP server URL with `/mcp` path285 - **Auth**: OAuth 2.12862873. Click **Register Client**.288289> **Note**: The `--enable-dynamic-registration` is required for Open WebUI to work. If using a custom Azure Entra app, add your redirect URI under "Mobile and desktop applications" platform (not "Single-page application").290291**Quick test setup** using the default Azure app (ID `ms-365` and `localhost:8080` are pre-configured):292293```bash294docker run -d -p 8080:8080 \295 -e WEBUI_AUTH=false \296 -e OPENAI_API_KEY \297 ghcr.io/open-webui/open-webui:main298299npx @softeria/ms-365-mcp-server --http --enable-dynamic-registration300```301302Then add connection with URL `http://localhost:3000/mcp` and ID `ms-365`.303304305306### Local Development307308For local development or testing:309310```bash311# From the project directory312claude mcp add ms -- npx tsx src/index.ts --org-mode313```314315Or configure Claude Desktop manually:316317```json318{319 "mcpServers": {320 "ms365": {321 "command": "node",322 "args": ["/absolute/path/to/ms-365-mcp-server/dist/index.js", "--org-mode"]323 }324 }325}326```327328> **Note**: Run `npm run build` after code changes to update the `dist/` folder.329330### Authentication331332> ⚠️ You must authenticate before using tools.333334The server supports three authentication methods:335336#### 1. Device Code Flow (Default)337338For interactive authentication via device code:339340- **MCP client login**:341 - Call the `login` tool (auto-checks existing token)342 - If needed, get URL+code, visit in browser343 - Use `verify-login` tool to confirm344- **CLI login**:345 ```bash346 npx @softeria/ms-365-mcp-server --login347 ```348 Follow the URL and code prompt in the terminal.349350Tokens are cached securely in your OS credential store (fallback to file).351352#### 2. OAuth Authorization Code Flow (HTTP mode only)353354When running with `--http`, the server **requires** OAuth authentication:355356```bash357npx @softeria/ms-365-mcp-server --http 3000358```359360This mode:361362- Advertises OAuth capabilities to MCP clients363- Provides OAuth endpoints at `/auth/*` (authorize, token, metadata)364- **Requires** `Authorization: Bearer <token>` for all MCP requests365- Validates tokens with Microsoft Graph API366- **Disables** login/logout tools by default (use `--enable-auth-tools` to enable them)367368MCP clients will automatically handle the OAuth flow when they see the advertised capabilities.369370##### Setting up Azure AD for OAuth Testing371372To use OAuth mode with custom Azure credentials (recommended for production), you'll need to set up an Azure AD app373registration:3743751. **Create Azure AD App Registration**:376377- Go to [Azure Portal](https://portal.azure.com)378- Navigate to Azure Active Directory → App registrations → New registration379- Set name: "MS365 MCP Server"3803812. **Configure Redirect URIs**:382383- **Configure the OAuth callback URI**: Go to your app registration and on the left side, go to Authentication.384- Under Platform configurations:385 - Click Add a platform (if you don’t already see one for "Mobile and desktop applications" / "Public client").386 - Choose Mobile and desktop applications or Public client/native (mobile & desktop) (label depends on portal version).3873883. **Testing with MCP Inspector (`npm run inspector`)**:389390- Go to your app registration and on the left side, go to Authentication.391- Under Platform configurations:392 - Click Add a platform (if you don’t already see one for "Web").393 - Choose Web.394 - Configure the following redirect URIs395 - `http://localhost:6274/oauth/callback`396 - `http://localhost:6274/oauth/callback/debug`397 - `http://localhost:3000/callback` (optional, for server callback)3983994. **Get Credentials**:400401- Copy the **Application (client) ID** from Overview page402- Go to Certificates & secrets → New client secret → Copy the secret value (optional for public apps)4034045. **Configure Environment Variables**:405 Create a `.env` file in your project root:406 ```env407 MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here408 MS365_MCP_CLIENT_SECRET=your-secret-here # Optional for public apps409 MS365_MCP_TENANT_ID=common410 ```411412With these configured, the server will use your custom Azure app instead of the built-in one.413414#### 3. Bring Your Own Token (BYOT)415416If you are running ms-365-mcp-server as part of a larger system that manages Microsoft OAuth tokens externally, you can417provide an access token directly to this MCP server:418419```bash420MS365_MCP_OAUTH_TOKEN=your_oauth_token npx @softeria/ms-365-mcp-server421```422423This method:424425- Bypasses the interactive authentication flows426- Use your pre-existing OAuth token for Microsoft Graph API requests427- Does not handle token refresh (token lifecycle management is your responsibility)428429> **Note**: HTTP mode requires authentication. For unauthenticated testing, use stdio mode with device code flow.430>431> **Authentication Tools**: In HTTP mode, login/logout tools are disabled by default since OAuth handles authentication.432> Use `--enable-auth-tools` if you need them available.433434## Tool Presets435436To reduce initial connection overhead, use preset tool categories instead of loading all 90+ tools:437438```bash439npx @softeria/ms-365-mcp-server --preset mail440npx @softeria/ms-365-mcp-server --list-presets # See all available presets441```442443Available presets: `mail`, `calendar`, `files`, `personal`, `work`, `excel`, `contacts`, `tasks`, `onenote`, `search`, `users`, `all`444445**Experimental:** `--discovery` starts with only 2 tools (`search-tools`, `execute-tool`) for minimal token usage.446447## CLI Options448449The following options can be used when running ms-365-mcp-server directly from the command line:450451```452--login Login using device code flow453--logout Log out and clear saved credentials454--verify-login Verify login without starting the server455--org-mode Enable organization/work mode from start (includes Teams, SharePoint, etc.)456--work-mode Alias for --org-mode457--force-work-scopes Backwards compatibility alias for --org-mode (deprecated)458--cloud <type> Microsoft cloud environment: global (default) or china (21Vianet)459```460461### Server Options462463When running as an MCP server, the following options can be used:464465```466-v Enable verbose logging467--read-only Start server in read-only mode, disabling write operations468--http [port] Use Streamable HTTP transport instead of stdio (optionally specify port, default: 3000)469 Starts Express.js server with MCP endpoint at /mcp470--enable-auth-tools Enable login/logout tools when using HTTP mode (disabled by default in HTTP mode)471--enable-dynamic-registration Enable OAuth Dynamic Client Registration endpoint (required for Open WebUI)472--enabled-tools <pattern> Filter tools using regex pattern (e.g., "excel|contact" to enable Excel and Contact tools)473--preset <names> Use preset tool categories (comma-separated). See "Tool Presets" section above474--list-presets List all available presets and exit475--toon (experimental) Enable TOON output format for 30-60% token reduction476--discovery (experimental) Start with search-tools + execute-tool only477```478479Environment variables:480481- `READ_ONLY=true|1`: Alternative to --read-only flag482- `ENABLED_TOOLS`: Filter tools using a regex pattern (alternative to --enabled-tools flag)483- `MS365_MCP_ORG_MODE=true|1`: Enable organization/work mode (alternative to --org-mode flag)484- `MS365_MCP_FORCE_WORK_SCOPES=true|1`: Backwards compatibility for MS365_MCP_ORG_MODE485- `MS365_MCP_OUTPUT_FORMAT=toon`: Enable TOON output format (alternative to --toon flag)486- `MS365_MCP_CLOUD_TYPE=global|china`: Microsoft cloud environment (alternative to --cloud flag)487- `LOG_LEVEL`: Set logging level (default: 'info')488- `SILENT=true|1`: Disable console output489- `MS365_MCP_CLIENT_ID`: Custom Azure app client ID (defaults to built-in app)490- `MS365_MCP_TENANT_ID`: Custom tenant ID (defaults to 'common' for multi-tenant)491- `MS365_MCP_OAUTH_TOKEN`: Pre-existing OAuth token for Microsoft Graph API (BYOT method)492- `MS365_MCP_KEYVAULT_URL`: Azure Key Vault URL for secrets management (see Azure Key Vault section)493- `MS365_MCP_TOKEN_CACHE_PATH`: Custom file path for MSAL token cache (see Token Storage below)494- `MS365_MCP_SELECTED_ACCOUNT_PATH`: Custom file path for selected account metadata (see Token Storage below)495496## Token Storage497498Authentication 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.499500**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.501502To persist tokens across updates, set custom paths outside the package directory:503504```bash505export MS365_MCP_TOKEN_CACHE_PATH="$HOME/.config/ms365-mcp/.token-cache.json"506export MS365_MCP_SELECTED_ACCOUNT_PATH="$HOME/.config/ms365-mcp/.selected-account.json"507```508509Parent directories are created automatically. Files are written with `0600` permissions.510511> **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.512513## Azure Key Vault Integration514515For 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.516517### Setup5185191. **Create a Key Vault** (if you don't have one):520521 ```bash522 az keyvault create --name your-keyvault-name --resource-group your-rg --location eastus523 ```5245252. **Add secrets to Key Vault**:526527 ```bash528 az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-id --value "your-client-id"529 az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-tenant-id --value "your-tenant-id"530 # Optional: if using confidential client flow531 az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-secret --value "your-secret"532 ```5335343. **Grant access to Key Vault**:535536 For Azure Container Apps with managed identity:537538 ```bash539 # Get the managed identity principal ID540 PRINCIPAL_ID=$(az containerapp show --name your-app --resource-group your-rg --query identity.principalId -o tsv)541542 # Grant access to Key Vault secrets543 az keyvault set-policy --name your-keyvault-name --object-id $PRINCIPAL_ID --secret-permissions get list544 ```545546 For local development with Azure CLI:547548 ```bash549 # Your Azure CLI identity already has access if you have appropriate RBAC roles550 az login551 ```5525534. **Configure the server**:554 ```bash555 MS365_MCP_KEYVAULT_URL=https://your-keyvault-name.vault.azure.net npx @softeria/ms-365-mcp-server556 ```557558### Secret Name Mapping559560| Key Vault Secret Name | Environment Variable | Required |561| ----------------------- | ----------------------- | ------------------------- |562| ms365-mcp-client-id | MS365_MCP_CLIENT_ID | Yes |563| ms365-mcp-tenant-id | MS365_MCP_TENANT_ID | No (defaults to 'common') |564| ms365-mcp-client-secret | MS365_MCP_CLIENT_SECRET | No |565566### Authentication567568The Key Vault integration uses `DefaultAzureCredential` from the Azure Identity SDK, which automatically tries multiple authentication methods in order:5695701. Environment variables (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)5712. Managed Identity (recommended for Azure Container Apps)5723. Azure CLI credentials (for local development)5734. Visual Studio Code credentials5745. Azure PowerShell credentials575576### Optional Dependencies577578The 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.579580## Contributing581582We welcome contributions! Before submitting a pull request, please ensure your changes meet our quality standards.583584Run the verification script to check all code quality requirements:585586```bash587npm run verify588```589590### For Developers591592After cloning the repository, you may need to generate the client code from the Microsoft Graph OpenAPI specification:593594```bash595npm run generate596```597598## Support599600If you're having problems or need help:601602- Create an [issue](https://github.com/softeria/ms-365-mcp-server/issues)603- Start a [discussion](https://github.com/softeria/ms-365-mcp-server/discussions)604- Email: eirikb@eirikb.no605- Discord: https://discord.gg/WvGVNScrAZ or @eirikb606607## License608609MIT © 2026 Softeria610
Full transparency — inspect the skill content before installing.