@softeria/ms-365-mcp-server 0.30.0 → 0.30.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.
@@ -2,33 +2,26 @@ import logger from "./logger.js";
2
2
  import { refreshAccessToken } from "./lib/microsoft-auth.js";
3
3
  import { encode as toonEncode } from "@toon-format/toon";
4
4
  import { getCloudEndpoints } from "./cloud-config.js";
5
+ import { getRequestTokens } from "./request-context.js";
5
6
  class GraphClient {
6
7
  constructor(authManager, secrets, outputFormat = "json") {
7
- this.accessToken = null;
8
- this.refreshToken = null;
9
8
  this.outputFormat = "json";
10
9
  this.authManager = authManager;
11
10
  this.secrets = secrets;
12
11
  this.outputFormat = outputFormat;
13
12
  }
14
- setOAuthTokens(accessToken, refreshToken) {
15
- this.accessToken = accessToken;
16
- this.refreshToken = refreshToken || null;
17
- }
18
13
  async makeRequest(endpoint, options = {}) {
19
- let accessToken = options.accessToken || this.accessToken || await this.authManager.getToken();
20
- let refreshToken = options.refreshToken || this.refreshToken;
14
+ const contextTokens = getRequestTokens();
15
+ let accessToken = options.accessToken ?? contextTokens?.accessToken ?? await this.authManager.getToken();
16
+ const refreshToken = options.refreshToken ?? contextTokens?.refreshToken;
21
17
  if (!accessToken) {
22
18
  throw new Error("No access token available");
23
19
  }
24
20
  try {
25
21
  let response = await this.performRequest(endpoint, accessToken, options);
26
22
  if (response.status === 401 && refreshToken) {
27
- await this.refreshAccessToken(refreshToken);
28
- accessToken = this.accessToken || accessToken;
29
- if (!accessToken) {
30
- throw new Error("Failed to refresh access token");
31
- }
23
+ const newTokens = await this.refreshAccessToken(refreshToken);
24
+ accessToken = newTokens.accessToken;
32
25
  response = await this.performRequest(endpoint, accessToken, options);
33
26
  }
34
27
  if (response.status === 403) {
@@ -89,10 +82,10 @@ class GraphClient {
89
82
  tenantId,
90
83
  this.secrets.cloudType
91
84
  );
92
- this.accessToken = response.access_token;
93
- if (response.refresh_token) {
94
- this.refreshToken = response.refresh_token;
95
- }
85
+ return {
86
+ accessToken: response.access_token,
87
+ refreshToken: response.refresh_token
88
+ };
96
89
  }
97
90
  async performRequest(endpoint, accessToken, options) {
98
91
  const cloudEndpoints = getCloudEndpoints(this.secrets.cloudType);
@@ -0,0 +1,9 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const requestContext = new AsyncLocalStorage();
3
+ function getRequestTokens() {
4
+ return requestContext.getStore();
5
+ }
6
+ export {
7
+ getRequestTokens,
8
+ requestContext
9
+ };
package/dist/server.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  } from "./lib/microsoft-auth.js";
17
17
  import { getSecrets } from "./secrets.js";
18
18
  import { getCloudEndpoints } from "./cloud-config.js";
19
+ import { requestContext } from "./request-context.js";
19
20
  function parseHttpOption(httpOption) {
20
21
  if (typeof httpOption === "boolean") {
21
22
  return { host: void 0, port: 3e3 };
@@ -248,13 +249,7 @@ class MicrosoftGraphServer {
248
249
  "/mcp",
249
250
  microsoftBearerTokenAuthMiddleware,
250
251
  async (req, res) => {
251
- try {
252
- if (req.microsoftAuth) {
253
- this.graphClient.setOAuthTokens(
254
- req.microsoftAuth.accessToken,
255
- req.microsoftAuth.refreshToken
256
- );
257
- }
252
+ const handler = async () => {
258
253
  const transport = new StreamableHTTPServerTransport({
259
254
  sessionIdGenerator: void 0
260
255
  // Stateless mode
@@ -264,6 +259,19 @@ class MicrosoftGraphServer {
264
259
  });
265
260
  await this.server.connect(transport);
266
261
  await transport.handleRequest(req, res, void 0);
262
+ };
263
+ try {
264
+ if (req.microsoftAuth) {
265
+ await requestContext.run(
266
+ {
267
+ accessToken: req.microsoftAuth.accessToken,
268
+ refreshToken: req.microsoftAuth.refreshToken
269
+ },
270
+ handler
271
+ );
272
+ } else {
273
+ await handler();
274
+ }
267
275
  } catch (error) {
268
276
  logger.error("Error handling MCP GET request:", error);
269
277
  if (!res.headersSent) {
@@ -283,13 +291,7 @@ class MicrosoftGraphServer {
283
291
  "/mcp",
284
292
  microsoftBearerTokenAuthMiddleware,
285
293
  async (req, res) => {
286
- try {
287
- if (req.microsoftAuth) {
288
- this.graphClient.setOAuthTokens(
289
- req.microsoftAuth.accessToken,
290
- req.microsoftAuth.refreshToken
291
- );
292
- }
294
+ const handler = async () => {
293
295
  const transport = new StreamableHTTPServerTransport({
294
296
  sessionIdGenerator: void 0
295
297
  // Stateless mode
@@ -299,6 +301,19 @@ class MicrosoftGraphServer {
299
301
  });
300
302
  await this.server.connect(transport);
301
303
  await transport.handleRequest(req, res, req.body);
304
+ };
305
+ try {
306
+ if (req.microsoftAuth) {
307
+ await requestContext.run(
308
+ {
309
+ accessToken: req.microsoftAuth.accessToken,
310
+ refreshToken: req.microsoftAuth.refreshToken
311
+ },
312
+ handler
313
+ );
314
+ } else {
315
+ await handler();
316
+ }
302
317
  } catch (error) {
303
318
  logger.error("Error handling MCP POST request:", error);
304
319
  if (!res.headersSent) {
@@ -1,5 +1,5 @@
1
- 2026-01-12 13:28:46 INFO: Using environment variables for secrets
2
- 2026-01-12 13:28:46 INFO: Using environment variables for secrets
3
- 2026-01-12 13:28:46 INFO: Using environment variables for secrets
4
- 2026-01-12 13:28:46 INFO: Using environment variables for secrets
5
- 2026-01-12 13:28:46 INFO: Using environment variables for secrets
1
+ 2026-01-19 11:31:37 INFO: Using environment variables for secrets
2
+ 2026-01-19 11:31:37 INFO: Using environment variables for secrets
3
+ 2026-01-19 11:31:37 INFO: Using environment variables for secrets
4
+ 2026-01-19 11:31:37 INFO: Using environment variables for secrets
5
+ 2026-01-19 11:31:37 INFO: Using environment variables for secrets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softeria/ms-365-mcp-server",
3
- "version": "0.30.0",
3
+ "version": "0.30.1",
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",