@dashflow/ms365-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +54 -0
- package/.releaserc.json +9 -0
- package/Dockerfile +22 -0
- package/LICENSE +21 -0
- package/README.md +590 -0
- package/bin/generate-graph-client.mjs +59 -0
- package/bin/modules/download-openapi.mjs +40 -0
- package/bin/modules/extract-descriptions.mjs +48 -0
- package/bin/modules/generate-mcp-tools.mjs +46 -0
- package/bin/modules/simplified-openapi.mjs +694 -0
- package/dist/auth-tools.js +202 -0
- package/dist/auth.js +422 -0
- package/dist/cli.js +78 -0
- package/dist/cloud-config.js +49 -0
- package/dist/endpoints.json +596 -0
- package/dist/generated/endpoint-types.js +0 -0
- package/dist/generated/hack.js +42 -0
- package/dist/graph-client.js +208 -0
- package/dist/graph-tools.js +401 -0
- package/dist/index.js +76 -0
- package/dist/lib/microsoft-auth.js +73 -0
- package/dist/logger.js +42 -0
- package/dist/oauth-provider.js +51 -0
- package/dist/request-context.js +9 -0
- package/dist/secrets.js +68 -0
- package/dist/server.js +387 -0
- package/dist/tool-categories.js +93 -0
- package/dist/version.js +10 -0
- package/eslint.config.js +43 -0
- package/glama.json +4 -0
- package/package.json +79 -0
- package/remove-recursive-refs.js +294 -0
- package/src/endpoints.json +596 -0
- package/src/generated/README.md +56 -0
- package/src/generated/endpoint-types.ts +27 -0
- package/src/generated/hack.ts +49 -0
- package/test-calendar-fix.js +62 -0
- package/test-real-calendar.js +96 -0
- package/tsup.config.ts +30 -0
package/.env.example
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Microsoft 365 OAuth Configuration
|
|
2
|
+
# Create an Azure AD app registration and get these values:
|
|
3
|
+
|
|
4
|
+
# Your Azure AD App Registration Client ID
|
|
5
|
+
MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here
|
|
6
|
+
|
|
7
|
+
# Your Azure AD App Registration Client Secret (optional, for confidential clients)
|
|
8
|
+
MS365_MCP_CLIENT_SECRET=your-azure-ad-app-client-secret-here
|
|
9
|
+
|
|
10
|
+
# Tenant ID - use "common" for multi-tenant or your specific tenant ID
|
|
11
|
+
MS365_MCP_TENANT_ID=common
|
|
12
|
+
|
|
13
|
+
# Cloud environment: global (default) or china (21Vianet)
|
|
14
|
+
# MS365_MCP_CLOUD_TYPE=global
|
|
15
|
+
|
|
16
|
+
# Instructions for Global Cloud:
|
|
17
|
+
# 1. Go to https://portal.azure.com
|
|
18
|
+
# 2. Navigate to Azure Active Directory → App registrations → New registration
|
|
19
|
+
# 3. Set name: "MS365 MCP Server"
|
|
20
|
+
# 4. Add these redirect URIs (for MCP Inspector testing):
|
|
21
|
+
# - http://localhost:6274/oauth/callback
|
|
22
|
+
# - http://localhost:6274/oauth/callback/debug
|
|
23
|
+
# - http://localhost:3000/callback (optional, for server callback)
|
|
24
|
+
# 5. Copy the Client ID from Overview page
|
|
25
|
+
# 6. Go to Certificates & secrets → New client secret → Copy the secret value
|
|
26
|
+
# 7. Replace the values above with your actual credentials
|
|
27
|
+
# 8. Rename this file to .env
|
|
28
|
+
|
|
29
|
+
# Instructions for China Cloud (21Vianet):
|
|
30
|
+
# 1. Go to https://portal.azure.cn
|
|
31
|
+
# 2. Navigate to Azure Active Directory → App registrations → New registration
|
|
32
|
+
# 3. Follow the same steps as above
|
|
33
|
+
# 4. Set MS365_MCP_CLOUD_TYPE=china
|
|
34
|
+
|
|
35
|
+
# -------------------------------------------------------------------
|
|
36
|
+
# Azure Key Vault Integration (Optional)
|
|
37
|
+
# -------------------------------------------------------------------
|
|
38
|
+
# When set, secrets are fetched from Azure Key Vault instead of environment variables.
|
|
39
|
+
# This is useful for production deployments, especially with Azure Container Apps.
|
|
40
|
+
#
|
|
41
|
+
# MS365_MCP_KEYVAULT_URL=https://your-keyvault-name.vault.azure.net
|
|
42
|
+
#
|
|
43
|
+
# Key Vault secret names (store these in your Key Vault):
|
|
44
|
+
# - ms365-mcp-client-id (required)
|
|
45
|
+
# - ms365-mcp-tenant-id (optional, defaults to "common")
|
|
46
|
+
# - ms365-mcp-client-secret (optional)
|
|
47
|
+
# - ms365-mcp-cloud-type (optional, defaults to "global")
|
|
48
|
+
#
|
|
49
|
+
# Authentication uses DefaultAzureCredential, which supports:
|
|
50
|
+
# - Managed Identity (recommended for Azure Container Apps)
|
|
51
|
+
# - Azure CLI credentials (for local development)
|
|
52
|
+
# - Environment variables (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)
|
|
53
|
+
#
|
|
54
|
+
# See README.md for detailed Azure Key Vault setup instructions.
|
package/.releaserc.json
ADDED
package/Dockerfile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
FROM node:24-alpine AS builder
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
COPY package*.json ./
|
|
6
|
+
RUN npm i
|
|
7
|
+
|
|
8
|
+
COPY . .
|
|
9
|
+
RUN npm run generate
|
|
10
|
+
RUN npm run build
|
|
11
|
+
|
|
12
|
+
FROM node:20-alpine AS release
|
|
13
|
+
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
|
|
16
|
+
COPY --from=builder /app/dist /app/dist
|
|
17
|
+
COPY --from=builder /app/package*.json ./
|
|
18
|
+
|
|
19
|
+
ENV NODE_ENV=production
|
|
20
|
+
RUN npm i --ignore-scripts --omit=dev
|
|
21
|
+
|
|
22
|
+
ENTRYPOINT ["node", "dist/index.js"]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Softeria
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
# ms365-mcp-server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@dashflow/ms365-mcp-server) [](https://github.com/dashflow/ms365-mcp-server/blob/main/LICENSE)
|
|
4
|
+
|
|
5
|
+
Microsoft 365 MCP Server (Dashflow Edition)
|
|
6
|
+
|
|
7
|
+
A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Microsoft Office services through the Graph
|
|
8
|
+
API.
|
|
9
|
+
|
|
10
|
+
## Supported Clouds
|
|
11
|
+
|
|
12
|
+
This server supports multiple Microsoft cloud environments:
|
|
13
|
+
|
|
14
|
+
| 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 |
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- Node.js >= 20 (recommended)
|
|
22
|
+
- Node.js 14+ may work with dependency warnings
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- Authentication via Microsoft Authentication Library (MSAL)
|
|
27
|
+
- Comprehensive Microsoft 365 service integration
|
|
28
|
+
- Read-only mode support for safe operations
|
|
29
|
+
- Tool filtering for granular access control
|
|
30
|
+
|
|
31
|
+
## Output Format: JSON vs TOON
|
|
32
|
+
|
|
33
|
+
The server supports two output formats that can be configured globally:
|
|
34
|
+
|
|
35
|
+
### JSON Format (Default)
|
|
36
|
+
|
|
37
|
+
Standard JSON output with pretty-printing:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"value": [
|
|
42
|
+
{
|
|
43
|
+
"id": "1",
|
|
44
|
+
"displayName": "Alice Johnson",
|
|
45
|
+
"mail": "alice@example.com",
|
|
46
|
+
"jobTitle": "Software Engineer"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### (experimental) TOON Format
|
|
53
|
+
|
|
54
|
+
[Token-Oriented Object Notation](https://github.com/toon-format/toon) for efficient LLM token usage:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
value[1]{id,displayName,mail,jobTitle}:
|
|
58
|
+
"1",Alice Johnson,alice@example.com,Software Engineer
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Benefits:**
|
|
62
|
+
|
|
63
|
+
- 30-60% fewer tokens vs JSON
|
|
64
|
+
- Best for uniform array data (lists of emails, calendar events, files, etc.)
|
|
65
|
+
- Ideal for cost-sensitive applications at scale
|
|
66
|
+
|
|
67
|
+
**Usage:**
|
|
68
|
+
(experimental) Enable TOON format globally:
|
|
69
|
+
|
|
70
|
+
Via CLI flag:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx @dashflow/ms365-mcp-server --toon
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Via Claude Desktop configuration:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"ms365": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["-y", "@dashflow/ms365-mcp-server", "--toon"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Via environment variable:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
MS365_MCP_OUTPUT_FORMAT=toon npx @dashflow/ms365-mcp-server
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Supported Services & Tools
|
|
96
|
+
|
|
97
|
+
### Personal Account Tools (Available by default)
|
|
98
|
+
|
|
99
|
+
**Email (Outlook)**
|
|
100
|
+
<sub>list-mail-messages, list-mail-folders, list-mail-folder-messages, get-mail-message, send-mail,
|
|
101
|
+
delete-mail-message, create-draft-email, move-mail-message</sub>
|
|
102
|
+
|
|
103
|
+
**Calendar**
|
|
104
|
+
<sub>list-calendars, list-calendar-events, get-calendar-event, get-calendar-view, create-calendar-event,
|
|
105
|
+
update-calendar-event, delete-calendar-event</sub>
|
|
106
|
+
|
|
107
|
+
**OneDrive Files**
|
|
108
|
+
<sub>list-drives, get-drive-root-item, list-folder-files, download-onedrive-file-content, upload-file-content,
|
|
109
|
+
upload-new-file, delete-onedrive-file</sub>
|
|
110
|
+
|
|
111
|
+
**Excel Operations**
|
|
112
|
+
<sub>list-excel-worksheets, get-excel-range, create-excel-chart, format-excel-range, sort-excel-range</sub>
|
|
113
|
+
|
|
114
|
+
**OneNote**
|
|
115
|
+
<sub>list-onenote-notebooks, list-onenote-notebook-sections, list-onenote-section-pages, get-onenote-page-content,
|
|
116
|
+
create-onenote-page</sub>
|
|
117
|
+
|
|
118
|
+
**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>
|
|
120
|
+
|
|
121
|
+
**Planner**
|
|
122
|
+
<sub>list-planner-tasks, get-planner-plan, list-plan-tasks, get-planner-task, create-planner-task</sub>
|
|
123
|
+
|
|
124
|
+
**Contacts**
|
|
125
|
+
<sub>list-outlook-contacts, get-outlook-contact, create-outlook-contact, update-outlook-contact,
|
|
126
|
+
delete-outlook-contact</sub>
|
|
127
|
+
|
|
128
|
+
**User Profile**
|
|
129
|
+
<sub>get-current-user</sub>
|
|
130
|
+
|
|
131
|
+
**Search**
|
|
132
|
+
<sub>search-query</sub>
|
|
133
|
+
|
|
134
|
+
### Organization Account Tools (Requires --org-mode flag)
|
|
135
|
+
|
|
136
|
+
**Teams & Chats**
|
|
137
|
+
<sub>list-chats, get-chat, list-chat-messages, get-chat-message, send-chat-message, list-chat-message-replies,
|
|
138
|
+
reply-to-chat-message, list-joined-teams, get-team, list-team-channels, get-team-channel, list-channel-messages,
|
|
139
|
+
get-channel-message, send-channel-message, list-team-members</sub>
|
|
140
|
+
|
|
141
|
+
**SharePoint Sites**
|
|
142
|
+
<sub>search-sharepoint-sites, get-sharepoint-site, get-sharepoint-site-by-path, list-sharepoint-site-drives,
|
|
143
|
+
get-sharepoint-site-drive-by-id, list-sharepoint-site-items, get-sharepoint-site-item, list-sharepoint-site-lists,
|
|
144
|
+
get-sharepoint-site-list, list-sharepoint-site-list-items, get-sharepoint-site-list-item,
|
|
145
|
+
get-sharepoint-sites-delta</sub>
|
|
146
|
+
|
|
147
|
+
**Shared Mailboxes**
|
|
148
|
+
<sub>list-shared-mailbox-messages, list-shared-mailbox-folder-messages, get-shared-mailbox-message,
|
|
149
|
+
send-shared-mailbox-mail</sub>
|
|
150
|
+
|
|
151
|
+
**User Management**
|
|
152
|
+
<sub>list-users</sub>
|
|
153
|
+
|
|
154
|
+
## Organization/Work Mode
|
|
155
|
+
|
|
156
|
+
To access work/school features (Teams, SharePoint, etc.), enable organization mode using any of these flags:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"mcpServers": {
|
|
161
|
+
"ms365": {
|
|
162
|
+
"command": "npx",
|
|
163
|
+
"args": ["-y", "@dashflow/ms365-mcp-server", "--org-mode"]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Organization mode must be enabled from the start to access work account features. Without this flag, only personal
|
|
170
|
+
account features (email, calendar, OneDrive, etc.) are available.
|
|
171
|
+
|
|
172
|
+
## Shared Mailbox Access
|
|
173
|
+
|
|
174
|
+
To access shared mailboxes, you need:
|
|
175
|
+
|
|
176
|
+
1. **Organization mode**: Shared mailbox tools require `--org-mode` flag (work/school accounts only)
|
|
177
|
+
2. **Delegated permissions**: `Mail.Read.Shared` or `Mail.Send.Shared` scopes
|
|
178
|
+
3. **Exchange permissions**: The signed-in user must have been granted access to the shared mailbox
|
|
179
|
+
4. **Usage**: Use the shared mailbox's email address as the `user-id` parameter in the shared mailbox tools
|
|
180
|
+
|
|
181
|
+
**Finding shared mailboxes**: Use the `list-users` tool to discover available users and shared mailboxes in your
|
|
182
|
+
organization.
|
|
183
|
+
|
|
184
|
+
Example: `list-shared-mailbox-messages` with `user-id` set to `shared-mailbox@company.com`
|
|
185
|
+
|
|
186
|
+
## Quick Start Example
|
|
187
|
+
|
|
188
|
+
Test login in Claude Desktop:
|
|
189
|
+
|
|
190
|
+

|
|
191
|
+
|
|
192
|
+
## Examples
|
|
193
|
+
|
|
194
|
+

|
|
195
|
+
|
|
196
|
+
## Integration
|
|
197
|
+
|
|
198
|
+
### Claude Desktop
|
|
199
|
+
|
|
200
|
+
To add this MCP server to Claude Desktop, edit the config file under Settings > Developer.
|
|
201
|
+
|
|
202
|
+
#### Personal Account (MSA)
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"mcpServers": {
|
|
207
|
+
"ms365": {
|
|
208
|
+
"command": "npx",
|
|
209
|
+
"args": ["-y", "@dashflow/ms365-mcp-server"]
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### Work/School Account (Global)
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"mcpServers": {
|
|
220
|
+
"ms365": {
|
|
221
|
+
"command": "npx",
|
|
222
|
+
"args": ["-y", "@dashflow/ms365-mcp-server", "--org-mode"]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Work/School Account (China 21Vianet)
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"mcpServers": {
|
|
233
|
+
"ms365-china": {
|
|
234
|
+
"command": "npx",
|
|
235
|
+
"args": ["-y", "@dashflow/ms365-mcp-server", "--org-mode", "--cloud", "china"]
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Claude Code CLI
|
|
242
|
+
|
|
243
|
+
#### Personal Account (MSA)
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
claude mcp add ms365 -- npx -y @dashflow/ms365-mcp-server
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### Work/School Account (Global)
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# macOS/Linux
|
|
253
|
+
claude mcp add ms365 -- npx -y @dashflow/ms365-mcp-server --org-mode
|
|
254
|
+
|
|
255
|
+
# Windows (use cmd /c wrapper)
|
|
256
|
+
claude mcp add ms365 -s user -- cmd /c "npx -y @dashflow/ms365-mcp-server --org-mode"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### Work/School Account (China 21Vianet)
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# macOS/Linux
|
|
263
|
+
claude mcp add ms365-china -- npx -y @dashflow/ms365-mcp-server --org-mode --cloud china
|
|
264
|
+
|
|
265
|
+
# Windows (use cmd /c wrapper)
|
|
266
|
+
claude mcp add ms365-china -s user -- cmd /c "npx -y @dashflow/ms365-mcp-server --org-mode --cloud china"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
For other interfaces that support MCPs, please refer to their respective documentation for the correct
|
|
270
|
+
integration method.
|
|
271
|
+
|
|
272
|
+
### Open WebUI
|
|
273
|
+
|
|
274
|
+
Open WebUI supports MCP servers via HTTP transport with OAuth 2.1.
|
|
275
|
+
|
|
276
|
+
1. Start the server with HTTP mode and dynamic registration enabled:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
npx @dashflow/ms365-mcp-server --http --enable-dynamic-registration
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
2. In Open WebUI, go to **Admin Settings → Tools** (`/admin/settings/tools`) → **Add Connection**:
|
|
283
|
+
- **Type**: MCP Streamable HTTP
|
|
284
|
+
- **URL**: Your MCP server URL with `/mcp` path
|
|
285
|
+
- **Auth**: OAuth 2.1
|
|
286
|
+
|
|
287
|
+
3. Click **Register Client**.
|
|
288
|
+
|
|
289
|
+
> **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").
|
|
290
|
+
|
|
291
|
+
**Quick test setup** using the default Azure app (ID `ms-365` and `localhost:8080` are pre-configured):
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
docker run -d -p 8080:8080 \
|
|
295
|
+
-e WEBUI_AUTH=false \
|
|
296
|
+
-e OPENAI_API_KEY \
|
|
297
|
+
ghcr.io/open-webui/open-webui:main
|
|
298
|
+
|
|
299
|
+
npx @dashflow/ms365-mcp-server --http --enable-dynamic-registration
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Then add connection with URL `http://localhost:3000/mcp` and ID `ms-365`.
|
|
303
|
+
|
|
304
|
+

|
|
305
|
+
|
|
306
|
+
### Local Development
|
|
307
|
+
|
|
308
|
+
For local development or testing:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
# From the project directory
|
|
312
|
+
claude mcp add ms -- npx tsx src/index.ts --org-mode
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Or configure Claude Desktop manually:
|
|
316
|
+
|
|
317
|
+
```json
|
|
318
|
+
{
|
|
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
|
+
```
|
|
327
|
+
|
|
328
|
+
> **Note**: Run `npm run build` after code changes to update the `dist/` folder.
|
|
329
|
+
|
|
330
|
+
### Authentication
|
|
331
|
+
|
|
332
|
+
> ⚠️ You must authenticate before using tools.
|
|
333
|
+
|
|
334
|
+
The server supports three authentication methods:
|
|
335
|
+
|
|
336
|
+
#### 1. Device Code Flow (Default)
|
|
337
|
+
|
|
338
|
+
For interactive authentication via device code:
|
|
339
|
+
|
|
340
|
+
- **MCP client login**:
|
|
341
|
+
- Call the `login` tool (auto-checks existing token)
|
|
342
|
+
- If needed, get URL+code, visit in browser
|
|
343
|
+
- Use `verify-login` tool to confirm
|
|
344
|
+
- **CLI login**:
|
|
345
|
+
```bash
|
|
346
|
+
npx @dashflow/ms365-mcp-server --login
|
|
347
|
+
```
|
|
348
|
+
Follow the URL and code prompt in the terminal.
|
|
349
|
+
|
|
350
|
+
Tokens are cached securely in your OS credential store (fallback to file).
|
|
351
|
+
|
|
352
|
+
#### 2. OAuth Authorization Code Flow (HTTP mode only)
|
|
353
|
+
|
|
354
|
+
When running with `--http`, the server **requires** OAuth authentication:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
npx @dashflow/ms365-mcp-server --http 3000
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
This mode:
|
|
361
|
+
|
|
362
|
+
- Advertises OAuth capabilities to MCP clients
|
|
363
|
+
- Provides OAuth endpoints at `/auth/*` (authorize, token, metadata)
|
|
364
|
+
- **Requires** `Authorization: Bearer <token>` for all MCP requests
|
|
365
|
+
- Validates tokens with Microsoft Graph API
|
|
366
|
+
- **Disables** login/logout tools by default (use `--enable-auth-tools` to enable them)
|
|
367
|
+
|
|
368
|
+
MCP clients will automatically handle the OAuth flow when they see the advertised capabilities.
|
|
369
|
+
|
|
370
|
+
##### Setting up Azure AD for OAuth Testing
|
|
371
|
+
|
|
372
|
+
To use OAuth mode with custom Azure credentials (recommended for production), you'll need to set up an Azure AD app
|
|
373
|
+
registration:
|
|
374
|
+
|
|
375
|
+
1. **Create Azure AD App Registration**:
|
|
376
|
+
|
|
377
|
+
- Go to [Azure Portal](https://portal.azure.com)
|
|
378
|
+
- Navigate to Azure Active Directory → App registrations → New registration
|
|
379
|
+
- Set name: "MS365 MCP Server"
|
|
380
|
+
|
|
381
|
+
2. **Configure Redirect URIs**:
|
|
382
|
+
|
|
383
|
+
- **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).
|
|
387
|
+
|
|
388
|
+
3. **Testing with MCP Inspector (`npm run inspector`)**:
|
|
389
|
+
|
|
390
|
+
- 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 URIs
|
|
395
|
+
- `http://localhost:6274/oauth/callback`
|
|
396
|
+
- `http://localhost:6274/oauth/callback/debug`
|
|
397
|
+
- `http://localhost:3000/callback` (optional, for server callback)
|
|
398
|
+
|
|
399
|
+
4. **Get Credentials**:
|
|
400
|
+
|
|
401
|
+
- Copy the **Application (client) ID** from Overview page
|
|
402
|
+
- Go to Certificates & secrets → New client secret → Copy the secret value (optional for public apps)
|
|
403
|
+
|
|
404
|
+
5. **Configure Environment Variables**:
|
|
405
|
+
Create a `.env` file in your project root:
|
|
406
|
+
```env
|
|
407
|
+
MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here
|
|
408
|
+
MS365_MCP_CLIENT_SECRET=your-secret-here # Optional for public apps
|
|
409
|
+
MS365_MCP_TENANT_ID=common
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
With these configured, the server will use your custom Azure app instead of the built-in one.
|
|
413
|
+
|
|
414
|
+
#### 3. Bring Your Own Token (BYOT)
|
|
415
|
+
|
|
416
|
+
If you are running ms-365-mcp-server as part of a larger system that manages Microsoft OAuth tokens externally, you can
|
|
417
|
+
provide an access token directly to this MCP server:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
MS365_MCP_OAUTH_TOKEN=your_oauth_token npx @dashflow/ms365-mcp-server
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
This method:
|
|
424
|
+
|
|
425
|
+
- Bypasses the interactive authentication flows
|
|
426
|
+
- Use your pre-existing OAuth token for Microsoft Graph API requests
|
|
427
|
+
- Does not handle token refresh (token lifecycle management is your responsibility)
|
|
428
|
+
|
|
429
|
+
> **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.
|
|
433
|
+
|
|
434
|
+
## Tool Presets
|
|
435
|
+
|
|
436
|
+
To reduce initial connection overhead, use preset tool categories instead of loading all 90+ tools:
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
npx @dashflow/ms365-mcp-server --preset mail
|
|
440
|
+
npx @dashflow/ms365-mcp-server --list-presets # See all available presets
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Available presets: `mail`, `calendar`, `files`, `personal`, `work`, `excel`, `contacts`, `tasks`, `onenote`, `search`, `users`, `all`
|
|
444
|
+
|
|
445
|
+
**Experimental:** `--discovery` starts with only 2 tools (`search-tools`, `execute-tool`) for minimal token usage.
|
|
446
|
+
|
|
447
|
+
## CLI Options
|
|
448
|
+
|
|
449
|
+
The following options can be used when running ms-365-mcp-server directly from the command line:
|
|
450
|
+
|
|
451
|
+
```
|
|
452
|
+
--login Login using device code flow
|
|
453
|
+
--logout Log out and clear saved credentials
|
|
454
|
+
--verify-login Verify login without starting the server
|
|
455
|
+
--org-mode Enable organization/work mode from start (includes Teams, SharePoint, etc.)
|
|
456
|
+
--work-mode Alias for --org-mode
|
|
457
|
+
--force-work-scopes Backwards compatibility alias for --org-mode (deprecated)
|
|
458
|
+
--cloud <type> Microsoft cloud environment: global (default) or china (21Vianet)
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Server Options
|
|
462
|
+
|
|
463
|
+
When running as an MCP server, the following options can be used:
|
|
464
|
+
|
|
465
|
+
```
|
|
466
|
+
-v Enable verbose logging
|
|
467
|
+
--read-only Start server in read-only mode, disabling write operations
|
|
468
|
+
--http [port] Use Streamable HTTP transport instead of stdio (optionally specify port, default: 3000)
|
|
469
|
+
Starts Express.js server with MCP endpoint at /mcp
|
|
470
|
+
--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 above
|
|
474
|
+
--list-presets List all available presets and exit
|
|
475
|
+
--toon (experimental) Enable TOON output format for 30-60% token reduction
|
|
476
|
+
--discovery (experimental) Start with search-tools + execute-tool only
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
Environment variables:
|
|
480
|
+
|
|
481
|
+
- `READ_ONLY=true|1`: Alternative to --read-only flag
|
|
482
|
+
- `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_MODE
|
|
485
|
+
- `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 output
|
|
489
|
+
- `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
|
+
|
|
494
|
+
## Azure Key Vault Integration
|
|
495
|
+
|
|
496
|
+
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.
|
|
497
|
+
|
|
498
|
+
### Setup
|
|
499
|
+
|
|
500
|
+
1. **Create a Key Vault** (if you don't have one):
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
az keyvault create --name your-keyvault-name --resource-group your-rg --location eastus
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
2. **Add secrets to Key Vault**:
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-id --value "your-client-id"
|
|
510
|
+
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-tenant-id --value "your-tenant-id"
|
|
511
|
+
# Optional: if using confidential client flow
|
|
512
|
+
az keyvault secret set --vault-name your-keyvault-name --name ms365-mcp-client-secret --value "your-secret"
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
3. **Grant access to Key Vault**:
|
|
516
|
+
|
|
517
|
+
For Azure Container Apps with managed identity:
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
# Get the managed identity principal ID
|
|
521
|
+
PRINCIPAL_ID=$(az containerapp show --name your-app --resource-group your-rg --query identity.principalId -o tsv)
|
|
522
|
+
|
|
523
|
+
# Grant access to Key Vault secrets
|
|
524
|
+
az keyvault set-policy --name your-keyvault-name --object-id $PRINCIPAL_ID --secret-permissions get list
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
For local development with Azure CLI:
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
# Your Azure CLI identity already has access if you have appropriate RBAC roles
|
|
531
|
+
az login
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
4. **Configure the server**:
|
|
535
|
+
```bash
|
|
536
|
+
MS365_MCP_KEYVAULT_URL=https://your-keyvault-name.vault.azure.net npx @dashflow/ms365-mcp-server
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Secret Name Mapping
|
|
540
|
+
|
|
541
|
+
| Key Vault Secret Name | Environment Variable | Required |
|
|
542
|
+
| ----------------------- | ----------------------- | ------------------------- |
|
|
543
|
+
| ms365-mcp-client-id | MS365_MCP_CLIENT_ID | Yes |
|
|
544
|
+
| ms365-mcp-tenant-id | MS365_MCP_TENANT_ID | No (defaults to 'common') |
|
|
545
|
+
| ms365-mcp-client-secret | MS365_MCP_CLIENT_SECRET | No |
|
|
546
|
+
|
|
547
|
+
### Authentication
|
|
548
|
+
|
|
549
|
+
The Key Vault integration uses `DefaultAzureCredential` from the Azure Identity SDK, which automatically tries multiple authentication methods in order:
|
|
550
|
+
|
|
551
|
+
1. Environment variables (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)
|
|
552
|
+
2. Managed Identity (recommended for Azure Container Apps)
|
|
553
|
+
3. Azure CLI credentials (for local development)
|
|
554
|
+
4. Visual Studio Code credentials
|
|
555
|
+
5. Azure PowerShell credentials
|
|
556
|
+
|
|
557
|
+
### Optional Dependencies
|
|
558
|
+
|
|
559
|
+
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.
|
|
560
|
+
|
|
561
|
+
## Contributing
|
|
562
|
+
|
|
563
|
+
We welcome contributions! Before submitting a pull request, please ensure your changes meet our quality standards.
|
|
564
|
+
|
|
565
|
+
Run the verification script to check all code quality requirements:
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
npm run verify
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### For Developers
|
|
572
|
+
|
|
573
|
+
After cloning the repository, you may need to generate the client code from the Microsoft Graph OpenAPI specification:
|
|
574
|
+
|
|
575
|
+
```bash
|
|
576
|
+
npm run generate
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
## Support
|
|
580
|
+
|
|
581
|
+
If you're having problems or need help:
|
|
582
|
+
|
|
583
|
+
- Create an [issue](https://github.com/softeria/ms-365-mcp-server/issues)
|
|
584
|
+
- Start a [discussion](https://github.com/softeria/ms-365-mcp-server/discussions)
|
|
585
|
+
- Email: eirikb@eirikb.no
|
|
586
|
+
- Discord: https://discord.gg/WvGVNScrAZ or @eirikb
|
|
587
|
+
|
|
588
|
+
## License
|
|
589
|
+
|
|
590
|
+
MIT © 2026 Softeria
|