@softeria/ms-365-mcp-server 0.27.1 → 0.28.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/dist/cli.js CHANGED
@@ -9,8 +9,8 @@ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
9
9
  const version = packageJson.version;
10
10
  const program = new Command();
11
11
  program.name("ms-365-mcp-server").description("Microsoft 365 MCP Server").version(version).option("-v", "Enable verbose logging").option("--login", "Login using device code flow").option("--logout", "Log out and clear saved credentials").option("--verify-login", "Verify login without starting the server").option("--list-accounts", "List all cached accounts").option("--select-account <accountId>", "Select a specific account by ID").option("--remove-account <accountId>", "Remove a specific account by ID").option("--read-only", "Start server in read-only mode, disabling write operations").option(
12
- "--http [port]",
13
- "Use Streamable HTTP transport instead of stdio (optionally specify port, default: 3000)"
12
+ "--http [address]",
13
+ 'Use Streamable HTTP transport instead of stdio. Format: [host:]port (e.g., "localhost:3000", ":3000", "3000"). Default: all interfaces on port 3000'
14
14
  ).option(
15
15
  "--enable-auth-tools",
16
16
  "Enable login/logout tools when using HTTP mode (disabled by default in HTTP mode)"
@@ -75,8 +75,10 @@ class GraphClient {
75
75
  const tenantId = process.env.MS365_MCP_TENANT_ID || "common";
76
76
  const clientId = process.env.MS365_MCP_CLIENT_ID || "084a3e9f-a9f4-43f7-89f9-d229cf97853e";
77
77
  const clientSecret = process.env.MS365_MCP_CLIENT_SECRET;
78
- if (!clientSecret) {
79
- throw new Error("MS365_MCP_CLIENT_SECRET not configured");
78
+ if (clientSecret) {
79
+ logger.info("GraphClient: Refreshing token with confidential client");
80
+ } else {
81
+ logger.info("GraphClient: Refreshing token with public client");
80
82
  }
81
83
  const response = await refreshAccessToken(refreshToken, clientId, clientSecret, tenantId);
82
84
  this.accessToken = response.access_token;
package/dist/server.js CHANGED
@@ -16,6 +16,20 @@ import {
16
16
  refreshAccessToken
17
17
  } from "./lib/microsoft-auth.js";
18
18
  const registeredClients = /* @__PURE__ */ new Map();
19
+ function parseHttpOption(httpOption) {
20
+ if (typeof httpOption === "boolean") {
21
+ return { host: void 0, port: 3e3 };
22
+ }
23
+ const httpString = httpOption.trim();
24
+ if (httpString.includes(":")) {
25
+ const [hostPart, portPart] = httpString.split(":");
26
+ const host = hostPart || void 0;
27
+ const port2 = parseInt(portPart) || 3e3;
28
+ return { host, port: port2 };
29
+ }
30
+ const port = parseInt(httpString) || 3e3;
31
+ return { host: void 0, port };
32
+ }
19
33
  class MicrosoftGraphServer {
20
34
  constructor(authManager, options = {}) {
21
35
  this.authManager = authManager;
@@ -66,7 +80,7 @@ class MicrosoftGraphServer {
66
80
  logger.info("Server running in READ-ONLY mode. Write operations are disabled.");
67
81
  }
68
82
  if (this.options.http) {
69
- const port = typeof this.options.http === "string" ? parseInt(this.options.http) : 3e3;
83
+ const { host, port } = parseHttpOption(this.options.http);
70
84
  const app = express();
71
85
  app.set("trust proxy", true);
72
86
  app.use(express.json());
@@ -200,13 +214,10 @@ class MicrosoftGraphServer {
200
214
  const tenantId = process.env.MS365_MCP_TENANT_ID || "common";
201
215
  const clientId = process.env.MS365_MCP_CLIENT_ID || "084a3e9f-a9f4-43f7-89f9-d229cf97853e";
202
216
  const clientSecret = process.env.MS365_MCP_CLIENT_SECRET;
203
- if (!clientSecret) {
204
- logger.error("Token endpoint: MS365_MCP_CLIENT_SECRET is not configured");
205
- res.status(500).json({
206
- error: "server_error",
207
- error_description: "Server configuration error"
208
- });
209
- return;
217
+ if (clientSecret) {
218
+ logger.info("Token endpoint: Using confidential client with client_secret");
219
+ } else {
220
+ logger.info("Token endpoint: Using public client without client_secret");
210
221
  }
211
222
  const result = await exchangeCodeForToken(
212
223
  body.code,
@@ -221,13 +232,10 @@ class MicrosoftGraphServer {
221
232
  const tenantId = process.env.MS365_MCP_TENANT_ID || "common";
222
233
  const clientId = process.env.MS365_MCP_CLIENT_ID || "084a3e9f-a9f4-43f7-89f9-d229cf97853e";
223
234
  const clientSecret = process.env.MS365_MCP_CLIENT_SECRET;
224
- if (!clientSecret) {
225
- logger.error("Token endpoint: MS365_MCP_CLIENT_SECRET is not configured");
226
- res.status(500).json({
227
- error: "server_error",
228
- error_description: "Server configuration error"
229
- });
230
- return;
235
+ if (clientSecret) {
236
+ logger.info("Refresh endpoint: Using confidential client with client_secret");
237
+ } else {
238
+ logger.info("Refresh endpoint: Using public client without client_secret");
231
239
  }
232
240
  const result = await refreshAccessToken(
233
241
  body.refresh_token,
@@ -329,14 +337,25 @@ class MicrosoftGraphServer {
329
337
  app.get("/", (req, res) => {
330
338
  res.send("Microsoft 365 MCP Server is running");
331
339
  });
332
- app.listen(port, () => {
333
- logger.info(`Server listening on HTTP port ${port}`);
334
- logger.info(` - MCP endpoint: http://localhost:${port}/mcp`);
335
- logger.info(` - OAuth endpoints: http://localhost:${port}/auth/*`);
336
- logger.info(
337
- ` - OAuth discovery: http://localhost:${port}/.well-known/oauth-authorization-server`
338
- );
339
- });
340
+ if (host) {
341
+ app.listen(port, host, () => {
342
+ logger.info(`Server listening on ${host}:${port}`);
343
+ logger.info(` - MCP endpoint: http://${host}:${port}/mcp`);
344
+ logger.info(` - OAuth endpoints: http://${host}:${port}/auth/*`);
345
+ logger.info(
346
+ ` - OAuth discovery: http://${host}:${port}/.well-known/oauth-authorization-server`
347
+ );
348
+ });
349
+ } else {
350
+ app.listen(port, () => {
351
+ logger.info(`Server listening on all interfaces (0.0.0.0:${port})`);
352
+ logger.info(` - MCP endpoint: http://localhost:${port}/mcp`);
353
+ logger.info(` - OAuth endpoints: http://localhost:${port}/auth/*`);
354
+ logger.info(
355
+ ` - OAuth discovery: http://localhost:${port}/.well-known/oauth-authorization-server`
356
+ );
357
+ });
358
+ }
340
359
  } else {
341
360
  const transport = new StdioServerTransport();
342
361
  await this.server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softeria/ms-365-mcp-server",
3
- "version": "0.27.1",
3
+ "version": "0.28.0",
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",
@@ -13,7 +13,7 @@
13
13
  "test": "vitest run",
14
14
  "test:watch": "vitest",
15
15
  "dev": "tsx src/index.ts",
16
- "dev:http": "tsx --watch src/index.ts --http 3000 -v",
16
+ "dev:http": "tsx --watch src/index.ts --http 127.0.0.1:3000 -v",
17
17
  "format": "prettier --write \"**/*.{ts,mts,js,mjs,json,md}\"",
18
18
  "format:check": "prettier --check \"**/*.{ts,mts,js,mjs,json,md}\"",
19
19
  "lint": "eslint .",