@softeria/ms-365-mcp-server 0.24.1 → 0.24.3
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/Dockerfile +13 -0
- package/README.md +18 -7
- package/dist/auth.js +46 -11
- package/package.json +5 -3
package/Dockerfile
ADDED
package/README.md
CHANGED
|
@@ -287,19 +287,30 @@ registration:
|
|
|
287
287
|
- Navigate to Azure Active Directory → App registrations → New registration
|
|
288
288
|
- Set name: "MS365 MCP Server"
|
|
289
289
|
|
|
290
|
-
|
|
291
|
-
Add these redirect URIs for testing with MCP Inspector (`npm run inspector`):
|
|
290
|
+
2. **Configure Redirect URIs**:
|
|
292
291
|
|
|
293
|
-
-
|
|
294
|
-
-
|
|
295
|
-
-
|
|
292
|
+
- **Configure the OAuth callback URI**: Go to your app registration and on the left side, go to Authentication.
|
|
293
|
+
- Under Platform configurations:
|
|
294
|
+
- Click Add a platform (if you don’t already see one for "Mobile and desktop applications" / "Public client").
|
|
295
|
+
- Choose Mobile and desktop applications or Public client/native (mobile & desktop) (label depends on portal version).
|
|
296
296
|
|
|
297
|
-
|
|
297
|
+
3. **Testing with MCP Inspector (`npm run inspector`)**:
|
|
298
|
+
|
|
299
|
+
- Go to your app registration and on the left side, go to Authentication.
|
|
300
|
+
- Under Platform configurations:
|
|
301
|
+
- Click Add a platform (if you don’t already see one for "Web").
|
|
302
|
+
- Choose Web.
|
|
303
|
+
- Configure the following redirect URIs
|
|
304
|
+
- `http://localhost:6274/oauth/callback`
|
|
305
|
+
- `http://localhost:6274/oauth/callback/debug`
|
|
306
|
+
- `http://localhost:3000/callback` (optional, for server callback)
|
|
307
|
+
|
|
308
|
+
4. **Get Credentials**:
|
|
298
309
|
|
|
299
310
|
- Copy the **Application (client) ID** from Overview page
|
|
300
311
|
- Go to Certificates & secrets → New client secret → Copy the secret value
|
|
301
312
|
|
|
302
|
-
|
|
313
|
+
5. **Configure Environment Variables**:
|
|
303
314
|
Create a `.env` file in your project root:
|
|
304
315
|
```env
|
|
305
316
|
MS365_MCP_CLIENT_ID=your-azure-ad-app-client-id-here
|
package/dist/auth.js
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import { PublicClientApplication } from "@azure/msal-node";
|
|
2
|
-
import keytar from "keytar";
|
|
3
2
|
import logger from "./logger.js";
|
|
4
3
|
import fs, { existsSync, readFileSync } from "fs";
|
|
5
4
|
import { fileURLToPath } from "url";
|
|
6
5
|
import path from "path";
|
|
6
|
+
let keytar = null;
|
|
7
|
+
async function getKeytar() {
|
|
8
|
+
if (keytar === void 0) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
if (keytar === null) {
|
|
12
|
+
try {
|
|
13
|
+
keytar = await import("keytar");
|
|
14
|
+
return keytar;
|
|
15
|
+
} catch (error) {
|
|
16
|
+
logger.info("keytar not available, using file-based credential storage");
|
|
17
|
+
keytar = void 0;
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return keytar;
|
|
22
|
+
}
|
|
7
23
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
24
|
const __dirname = path.dirname(__filename);
|
|
9
25
|
const endpointsData = JSON.parse(
|
|
@@ -87,9 +103,12 @@ class AuthManager {
|
|
|
87
103
|
try {
|
|
88
104
|
let cacheData;
|
|
89
105
|
try {
|
|
90
|
-
const
|
|
91
|
-
if (
|
|
92
|
-
|
|
106
|
+
const kt = await getKeytar();
|
|
107
|
+
if (kt) {
|
|
108
|
+
const cachedData = await kt.getPassword(SERVICE_NAME, TOKEN_CACHE_ACCOUNT);
|
|
109
|
+
if (cachedData) {
|
|
110
|
+
cacheData = cachedData;
|
|
111
|
+
}
|
|
93
112
|
}
|
|
94
113
|
} catch (keytarError) {
|
|
95
114
|
logger.warn(
|
|
@@ -111,9 +130,12 @@ class AuthManager {
|
|
|
111
130
|
try {
|
|
112
131
|
let selectedAccountData;
|
|
113
132
|
try {
|
|
114
|
-
const
|
|
115
|
-
if (
|
|
116
|
-
|
|
133
|
+
const kt = await getKeytar();
|
|
134
|
+
if (kt) {
|
|
135
|
+
const cachedData = await kt.getPassword(SERVICE_NAME, SELECTED_ACCOUNT_KEY);
|
|
136
|
+
if (cachedData) {
|
|
137
|
+
selectedAccountData = cachedData;
|
|
138
|
+
}
|
|
117
139
|
}
|
|
118
140
|
} catch (keytarError) {
|
|
119
141
|
logger.warn(
|
|
@@ -136,7 +158,12 @@ class AuthManager {
|
|
|
136
158
|
try {
|
|
137
159
|
const cacheData = this.msalApp.getTokenCache().serialize();
|
|
138
160
|
try {
|
|
139
|
-
await
|
|
161
|
+
const kt = await getKeytar();
|
|
162
|
+
if (kt) {
|
|
163
|
+
await kt.setPassword(SERVICE_NAME, TOKEN_CACHE_ACCOUNT, cacheData);
|
|
164
|
+
} else {
|
|
165
|
+
fs.writeFileSync(FALLBACK_PATH, cacheData);
|
|
166
|
+
}
|
|
140
167
|
} catch (keytarError) {
|
|
141
168
|
logger.warn(
|
|
142
169
|
`Keychain save failed, falling back to file storage: ${keytarError.message}`
|
|
@@ -151,7 +178,12 @@ class AuthManager {
|
|
|
151
178
|
try {
|
|
152
179
|
const selectedAccountData = JSON.stringify({ accountId: this.selectedAccountId });
|
|
153
180
|
try {
|
|
154
|
-
await
|
|
181
|
+
const kt = await getKeytar();
|
|
182
|
+
if (kt) {
|
|
183
|
+
await kt.setPassword(SERVICE_NAME, SELECTED_ACCOUNT_KEY, selectedAccountData);
|
|
184
|
+
} else {
|
|
185
|
+
fs.writeFileSync(SELECTED_ACCOUNT_PATH, selectedAccountData);
|
|
186
|
+
}
|
|
155
187
|
} catch (keytarError) {
|
|
156
188
|
logger.warn(
|
|
157
189
|
`Keychain save failed for selected account, falling back to file storage: ${keytarError.message}`
|
|
@@ -304,8 +336,11 @@ class AuthManager {
|
|
|
304
336
|
this.tokenExpiry = null;
|
|
305
337
|
this.selectedAccountId = null;
|
|
306
338
|
try {
|
|
307
|
-
await
|
|
308
|
-
|
|
339
|
+
const kt = await getKeytar();
|
|
340
|
+
if (kt) {
|
|
341
|
+
await kt.deletePassword(SERVICE_NAME, TOKEN_CACHE_ACCOUNT);
|
|
342
|
+
await kt.deletePassword(SERVICE_NAME, SELECTED_ACCOUNT_KEY);
|
|
343
|
+
}
|
|
309
344
|
} catch (keytarError) {
|
|
310
345
|
logger.warn(`Keychain deletion failed: ${keytarError.message}`);
|
|
311
346
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softeria/ms-365-mcp-server",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.3",
|
|
4
4
|
"description": " A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Office services through the Graph API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -40,12 +40,14 @@
|
|
|
40
40
|
"dotenv": "^17.0.1",
|
|
41
41
|
"express": "^5.1.0",
|
|
42
42
|
"js-yaml": "^4.1.0",
|
|
43
|
-
"keytar": "^7.9.0",
|
|
44
43
|
"winston": "^3.17.0",
|
|
45
44
|
"zod": "^3.24.2"
|
|
46
45
|
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"keytar": "^7.9.0"
|
|
48
|
+
},
|
|
47
49
|
"devDependencies": {
|
|
48
|
-
"@redocly/cli": "^
|
|
50
|
+
"@redocly/cli": "^2.11.1",
|
|
49
51
|
"@semantic-release/exec": "^7.1.0",
|
|
50
52
|
"@semantic-release/git": "^10.0.1",
|
|
51
53
|
"@semantic-release/github": "^11.0.3",
|