@softeria/ms-365-mcp-server 0.114.2 → 0.114.4

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 CHANGED
@@ -9,7 +9,7 @@ COPY . .
9
9
  RUN npm run generate
10
10
  RUN npm run build
11
11
 
12
- FROM node:20-alpine AS release
12
+ FROM node:24-alpine AS release
13
13
 
14
14
  WORKDIR /app
15
15
 
package/README.md CHANGED
@@ -504,7 +504,19 @@ npx @softeria/ms-365-mcp-server --preset mail
504
504
  npx @softeria/ms-365-mcp-server --list-presets # See all available presets
505
505
  ```
506
506
 
507
- Available presets: `mail`, `calendar`, `files`, `personal`, `work`, `excel`, `contacts`, `tasks`, `onenote`, `search`, `users`, `all`
507
+ Available presets: `mail`, `calendar`, `files`, `personal`, `work`, `excel`, `contacts`, `tasks`, `onenote`, `search`, `users`, `outlook`, `onedrive`, `teams`, `all`
508
+
509
+ Each endpoint in `endpoints.json` declares which presets it belongs to via a `presets` array, so every preset is an exact tool-name allow-list that never over-matches across apps (e.g. `mail` does not include shared-mailbox tools; those are in `work`).
510
+
511
+ The `outlook`, `onedrive` and `teams` presets are app-scoped: they expose exactly one Microsoft app. Use these for "expose exactly one app" deployments:
512
+
513
+ ```bash
514
+ # Outlook only (mail + calendar + contacts; no shared mailboxes, no files)
515
+ npx @softeria/ms-365-mcp-server --preset outlook
516
+
517
+ # Teams only (requires --org-mode)
518
+ npx @softeria/ms-365-mcp-server --org-mode --preset teams
519
+ ```
508
520
 
509
521
  ## Dynamic Tool Discovery
510
522
 
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { getRequestTokens } from "./request-context.js";
2
3
  function registerAuthTools(server, authManager) {
3
4
  server.tool(
4
5
  "login",
@@ -121,6 +122,7 @@ function registerAuthTools(server, authManager) {
121
122
  const accounts = await authManager.listAccounts();
122
123
  const selectedAccountId = authManager.getSelectedAccountId();
123
124
  const pinnedMode = authManager.hasExpectedAccount();
125
+ const oauthBearerMode = authManager.isOAuthModeEnabled() || Boolean(getRequestTokens());
124
126
  const result = accounts.map((account) => ({
125
127
  email: account.username || "unknown",
126
128
  name: account.name,
@@ -133,7 +135,7 @@ function registerAuthTools(server, authManager) {
133
135
  text: JSON.stringify({
134
136
  accounts: result,
135
137
  count: result.length,
136
- tip: pinnedMode ? "Expected account pinning is configured; account parameters are disabled." : "Pass the 'email' value as the 'account' parameter in any tool call to target a specific account."
138
+ tip: pinnedMode ? "Expected account pinning is configured; account parameters are disabled." : oauthBearerMode ? "This server is in HTTP/OAuth mode: every request uses the identity of the connecting client's bearer token. The cached accounts listed here cannot be targeted via the 'account' parameter; reconnect the MCP client as the desired account instead." : "Pass the 'email' value as the 'account' parameter in any tool call to target a specific account."
137
139
  })
138
140
  }
139
141
  ]
package/dist/auth.js CHANGED
@@ -718,6 +718,11 @@ class AuthManager {
718
718
  */
719
719
  async getTokenForAccount(identifier) {
720
720
  if (this.isOAuthMode && this.oauthToken) {
721
+ if (identifier) {
722
+ throw new Error(
723
+ `Cannot switch to account '${identifier}': the server is in OAuth mode and always uses the identity of the supplied bearer token. Account switching requires stdio mode (or HTTP with --trust-proxy-auth).`
724
+ );
725
+ }
721
726
  return this.oauthToken;
722
727
  }
723
728
  let targetAccount = null;