@teamnetwork/m365-mcp-server 1.0.0 → 1.0.1
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/README.md +199 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# @teamnetwork/m365-mcp-server
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for Microsoft 365 Email and Calendar access, using **app-only (client credentials) authentication** — no user login flows required.
|
|
4
|
+
|
|
5
|
+
Supports multiple accounts, shared mailboxes, per-mailbox read-only access control, folder navigation, and date/content filtering. Designed to be extended with Teams support later.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
- Node.js 18+
|
|
12
|
+
- A Microsoft 365 tenant with an **Azure AD app registration** configured for app-only access (see [Admin Setup](#admin-setup) below)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @teamnetwork/m365-mcp-server
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or run directly without installing:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @teamnetwork/m365-mcp-server
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
|
|
32
|
+
Create a JSON config file (e.g. `m365-config.json`) based on the example below. **Keep this file secure — it contains your client secret.**
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"connection": {
|
|
37
|
+
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
38
|
+
"clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
39
|
+
"clientSecret": "your-client-secret"
|
|
40
|
+
},
|
|
41
|
+
"accounts": [
|
|
42
|
+
{
|
|
43
|
+
"id": "main",
|
|
44
|
+
"displayName": "Main Organisation",
|
|
45
|
+
"mailboxes": [
|
|
46
|
+
{ "email": "user@org.com", "readonly": false },
|
|
47
|
+
{ "email": "shared@org.com", "readonly": true, "displayName": "Shared (read-only)" }
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "partner",
|
|
52
|
+
"displayName": "Partner Tenant",
|
|
53
|
+
"tenantId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
|
|
54
|
+
"clientId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
|
|
55
|
+
"clientSecret": "partner-secret",
|
|
56
|
+
"mailboxes": [
|
|
57
|
+
{ "email": "partner@other.com", "readonly": false }
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Config notes
|
|
65
|
+
|
|
66
|
+
- The top-level `connection` block provides default credentials for all accounts.
|
|
67
|
+
- Each account can override `tenantId`, `clientId`, and/or `clientSecret` individually — useful for multi-tenant setups.
|
|
68
|
+
- `readonly: true` mailboxes block all write operations (send, reply, move, create/update events) at the server level.
|
|
69
|
+
|
|
70
|
+
Set the path to your config via the `M365_CONFIG_PATH` environment variable:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
export M365_CONFIG_PATH=/path/to/m365-config.json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Claude Desktop / Claude Code Setup
|
|
79
|
+
|
|
80
|
+
Add the following to your Claude Desktop config (`claude_desktop_config.json`):
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"m365": {
|
|
86
|
+
"command": "npx",
|
|
87
|
+
"args": ["@teamnetwork/m365-mcp-server"],
|
|
88
|
+
"env": {
|
|
89
|
+
"M365_CONFIG_PATH": "/path/to/m365-config.json"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If installed globally, you can use the `m365-mcp` command instead:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"m365": {
|
|
102
|
+
"command": "m365-mcp",
|
|
103
|
+
"env": {
|
|
104
|
+
"M365_CONFIG_PATH": "/path/to/m365-config.json"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Available Tools
|
|
114
|
+
|
|
115
|
+
### Email
|
|
116
|
+
|
|
117
|
+
| Tool | Description |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `list_mailboxes` | List configured accounts and mailboxes with read/write status |
|
|
120
|
+
| `list_folders` | List mail folders (top-level or child folders) |
|
|
121
|
+
| `list_messages` | List messages with optional filters: date range, subject, body keyword, sender |
|
|
122
|
+
| `get_message` | Get full message details including body |
|
|
123
|
+
| `send_message` | Send an email (non-readonly mailboxes only) |
|
|
124
|
+
| `reply_message` | Reply or reply-all to a message (non-readonly mailboxes only) |
|
|
125
|
+
| `move_message` | Move a message to another folder (non-readonly mailboxes only) |
|
|
126
|
+
|
|
127
|
+
### Calendar
|
|
128
|
+
|
|
129
|
+
| Tool | Description |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `list_calendars` | List calendars for a mailbox |
|
|
132
|
+
| `list_events` | List events in a date range (recurring events expanded into instances) |
|
|
133
|
+
| `get_event` | Get full event details |
|
|
134
|
+
| `create_event` | Create a new event (non-readonly mailboxes only) |
|
|
135
|
+
| `update_event` | Update an existing event (non-readonly mailboxes only) |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Admin Setup
|
|
140
|
+
|
|
141
|
+
Before the server can access mailboxes, a tenant admin must complete the following steps.
|
|
142
|
+
|
|
143
|
+
### 1. Register an Azure AD Application
|
|
144
|
+
|
|
145
|
+
In the [Azure Portal](https://portal.azure.com) → **App registrations → New registration**:
|
|
146
|
+
|
|
147
|
+
- Set a name (e.g. `M365 MCP Server`)
|
|
148
|
+
- Note the **Application (client) ID** and **Directory (tenant) ID**
|
|
149
|
+
- Under **Certificates & secrets**, create a client secret and note the value
|
|
150
|
+
|
|
151
|
+
Grant the following **Application permissions** (not Delegated) and click **Grant admin consent**:
|
|
152
|
+
|
|
153
|
+
| Permission | Required for |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `Mail.Read` | Reading email |
|
|
156
|
+
| `Mail.ReadWrite` | Moving messages |
|
|
157
|
+
| `Mail.Send` | Sending and replying |
|
|
158
|
+
| `Calendars.Read` | Reading calendar events |
|
|
159
|
+
| `Calendars.ReadWrite` | Creating and updating events |
|
|
160
|
+
|
|
161
|
+
### 2. Restrict Mailbox Access (Recommended)
|
|
162
|
+
|
|
163
|
+
By default, the above permissions grant access to **all mailboxes** in the tenant. Use an `ApplicationAccessPolicy` in Exchange Online to restrict access to only the mailboxes in your config.
|
|
164
|
+
|
|
165
|
+
Run the following in **Exchange Online PowerShell**:
|
|
166
|
+
|
|
167
|
+
```powershell
|
|
168
|
+
# Create a mail-enabled security group and add the allowed mailboxes
|
|
169
|
+
New-DistributionGroup -Name "MCP-Allowed-Mailboxes" -Type Security
|
|
170
|
+
Add-DistributionGroupMember -Identity "MCP-Allowed-Mailboxes" -Member "user@org.com"
|
|
171
|
+
Add-DistributionGroupMember -Identity "MCP-Allowed-Mailboxes" -Member "shared@org.com"
|
|
172
|
+
|
|
173
|
+
# Restrict the app to only those mailboxes
|
|
174
|
+
New-ApplicationAccessPolicy `
|
|
175
|
+
-AppId "<your-client-id>" `
|
|
176
|
+
-PolicyScopeGroupId "MCP-Allowed-Mailboxes" `
|
|
177
|
+
-AccessRight RestrictAccess `
|
|
178
|
+
-Description "Restrict MCP server to configured mailboxes"
|
|
179
|
+
|
|
180
|
+
# Verify (should return Granted for allowed mailboxes)
|
|
181
|
+
Test-ApplicationAccessPolicy -AppId "<your-client-id>" -Identity "user@org.com"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
> **Note:** Policy changes can take up to 1 hour to propagate. Shared mailboxes must be added to the group directly.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Security
|
|
189
|
+
|
|
190
|
+
- Credentials are never logged. The server scrubs secrets, tokens, and email body content from all log output.
|
|
191
|
+
- All Graph API calls use the `/users/{email}/...` path (application permissions), never `/me/`.
|
|
192
|
+
- Write operations are blocked at the server level for any mailbox marked `readonly: true` in the config — this check happens before any network call is made.
|
|
193
|
+
- The config file should be kept outside your project directory and never committed to source control. Use restrictive file permissions (`chmod 600` on Linux/macOS).
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamnetwork/m365-mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "MCP server for Microsoft 365 Email and Calendar access using client credentials (app-only auth). Supports multiple accounts, shared mailboxes, per-mailbox read-only access, folder navigation, and date/content filtering.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|