msteams-mcp 0.2.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.

Potentially problematic release.


This version of msteams-mcp might be problematic. Click here for more details.

Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/dist/__fixtures__/api-responses.d.ts +254 -0
  4. package/dist/__fixtures__/api-responses.js +245 -0
  5. package/dist/api/calendar-api.d.ts +66 -0
  6. package/dist/api/calendar-api.js +179 -0
  7. package/dist/api/chatsvc-api.d.ts +352 -0
  8. package/dist/api/chatsvc-api.js +1100 -0
  9. package/dist/api/csa-api.d.ts +64 -0
  10. package/dist/api/csa-api.js +200 -0
  11. package/dist/api/index.d.ts +7 -0
  12. package/dist/api/index.js +7 -0
  13. package/dist/api/substrate-api.d.ts +50 -0
  14. package/dist/api/substrate-api.js +305 -0
  15. package/dist/auth/crypto.d.ts +32 -0
  16. package/dist/auth/crypto.js +66 -0
  17. package/dist/auth/index.d.ts +7 -0
  18. package/dist/auth/index.js +7 -0
  19. package/dist/auth/session-store.d.ts +87 -0
  20. package/dist/auth/session-store.js +230 -0
  21. package/dist/auth/token-extractor.d.ts +185 -0
  22. package/dist/auth/token-extractor.js +674 -0
  23. package/dist/auth/token-refresh.d.ts +25 -0
  24. package/dist/auth/token-refresh.js +85 -0
  25. package/dist/browser/auth.d.ts +53 -0
  26. package/dist/browser/auth.js +603 -0
  27. package/dist/browser/context.d.ts +40 -0
  28. package/dist/browser/context.js +122 -0
  29. package/dist/constants.d.ts +104 -0
  30. package/dist/constants.js +195 -0
  31. package/dist/index.d.ts +8 -0
  32. package/dist/index.js +12 -0
  33. package/dist/research/auth-research.d.ts +10 -0
  34. package/dist/research/auth-research.js +175 -0
  35. package/dist/research/explore.d.ts +11 -0
  36. package/dist/research/explore.js +270 -0
  37. package/dist/research/search-research.d.ts +17 -0
  38. package/dist/research/search-research.js +317 -0
  39. package/dist/server.d.ts +66 -0
  40. package/dist/server.js +295 -0
  41. package/dist/test/debug-search.d.ts +10 -0
  42. package/dist/test/debug-search.js +147 -0
  43. package/dist/test/mcp-harness.d.ts +17 -0
  44. package/dist/test/mcp-harness.js +474 -0
  45. package/dist/tools/auth-tools.d.ts +26 -0
  46. package/dist/tools/auth-tools.js +191 -0
  47. package/dist/tools/index.d.ts +56 -0
  48. package/dist/tools/index.js +34 -0
  49. package/dist/tools/meeting-tools.d.ts +33 -0
  50. package/dist/tools/meeting-tools.js +64 -0
  51. package/dist/tools/message-tools.d.ts +269 -0
  52. package/dist/tools/message-tools.js +856 -0
  53. package/dist/tools/people-tools.d.ts +46 -0
  54. package/dist/tools/people-tools.js +112 -0
  55. package/dist/tools/registry.d.ts +23 -0
  56. package/dist/tools/registry.js +63 -0
  57. package/dist/tools/search-tools.d.ts +91 -0
  58. package/dist/tools/search-tools.js +222 -0
  59. package/dist/types/errors.d.ts +58 -0
  60. package/dist/types/errors.js +132 -0
  61. package/dist/types/result.d.ts +43 -0
  62. package/dist/types/result.js +51 -0
  63. package/dist/types/server.d.ts +27 -0
  64. package/dist/types/server.js +7 -0
  65. package/dist/types/teams.d.ts +85 -0
  66. package/dist/types/teams.js +4 -0
  67. package/dist/utils/api-config.d.ts +103 -0
  68. package/dist/utils/api-config.js +158 -0
  69. package/dist/utils/auth-guards.d.ts +67 -0
  70. package/dist/utils/auth-guards.js +147 -0
  71. package/dist/utils/http.d.ts +29 -0
  72. package/dist/utils/http.js +112 -0
  73. package/dist/utils/parsers.d.ts +247 -0
  74. package/dist/utils/parsers.js +731 -0
  75. package/dist/utils/parsers.test.d.ts +7 -0
  76. package/dist/utils/parsers.test.js +511 -0
  77. package/package.json +62 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Token refresh via headless browser.
3
+ *
4
+ * Teams uses SPA OAuth2 which restricts refresh tokens to browser-based CORS
5
+ * requests. We open a headless browser with saved session state, let MSAL
6
+ * silently refresh tokens, then save the updated state. Seamless to the user.
7
+ */
8
+ import { TOKEN_REFRESH_THRESHOLD_MS } from '../constants.js';
9
+ import { ErrorCode, createError } from '../types/errors.js';
10
+ import { ok, err } from '../types/result.js';
11
+ import { extractSubstrateToken, clearTokenCache, } from './token-extractor.js';
12
+ import { hasSessionState, isSessionLikelyExpired, } from './session-store.js';
13
+ /**
14
+ * Refreshes tokens by opening a headless browser with saved session state.
15
+ * MSAL only refreshes tokens when an API call requires them, so we trigger
16
+ * a search via ensureAuthenticated to force token acquisition.
17
+ */
18
+ export async function refreshTokensViaBrowser() {
19
+ // Check we have a session to work with
20
+ if (!hasSessionState()) {
21
+ return err(createError(ErrorCode.AUTH_REQUIRED, 'No session state available. Please run teams_login to authenticate.', { suggestions: ['Call teams_login to authenticate'] }));
22
+ }
23
+ if (isSessionLikelyExpired()) {
24
+ return err(createError(ErrorCode.AUTH_EXPIRED, 'Session is too old and likely expired. Please re-authenticate.', { suggestions: ['Call teams_login to re-authenticate'] }));
25
+ }
26
+ // Get current token expiry for comparison
27
+ const beforeToken = extractSubstrateToken();
28
+ if (!beforeToken) {
29
+ return err(createError(ErrorCode.AUTH_REQUIRED, 'No token found in session. Please run teams_login to authenticate.', { suggestions: ['Call teams_login to authenticate'] }));
30
+ }
31
+ const previousExpiry = beforeToken.expiry;
32
+ // Import browser functions dynamically to avoid circular dependencies
33
+ const { createBrowserContext, closeBrowser } = await import('../browser/context.js');
34
+ let manager = null;
35
+ try {
36
+ // Open headless browser with saved session
37
+ manager = await createBrowserContext({ headless: true });
38
+ // Import auth functions
39
+ const { ensureAuthenticated } = await import('../browser/auth.js');
40
+ // Use the same auth flow that works for login - this triggers token acquisition
41
+ // showOverlay: false since headless browser has no visible window
42
+ // headless: true to fail fast if user interaction is required
43
+ await ensureAuthenticated(manager.page, manager.context, (msg) => {
44
+ // Silent logging for headless refresh
45
+ console.log(`[token-refresh] ${msg}`);
46
+ }, false, true);
47
+ // Close browser (ensureAuthenticated already saved the session)
48
+ await closeBrowser(manager, false);
49
+ manager = null;
50
+ // Clear our token cache to force re-extraction from the new session
51
+ clearTokenCache();
52
+ // Extract the new token to verify we still have valid tokens
53
+ const afterToken = extractSubstrateToken();
54
+ if (!afterToken) {
55
+ return err(createError(ErrorCode.AUTH_EXPIRED, 'Token refresh failed - no token found after refresh attempt.', { suggestions: ['Call teams_login to re-authenticate'] }));
56
+ }
57
+ const newExpiry = afterToken.expiry;
58
+ const minutesGained = Math.round((newExpiry.getTime() - previousExpiry.getTime()) / 1000 / 60);
59
+ // Check if the token was close to expiry and needed refresh
60
+ const wasCloseToExpiry = previousExpiry.getTime() - Date.now() < TOKEN_REFRESH_THRESHOLD_MS;
61
+ // If we needed a refresh but didn't get one, that's an error
62
+ if (wasCloseToExpiry && newExpiry.getTime() <= previousExpiry.getTime()) {
63
+ return err(createError(ErrorCode.AUTH_EXPIRED, 'Token was not refreshed despite being close to expiry. Session may need re-authentication.', { suggestions: ['Call teams_login to re-authenticate'] }));
64
+ }
65
+ return ok({
66
+ newExpiry,
67
+ previousExpiry,
68
+ minutesGained,
69
+ refreshNeeded: wasCloseToExpiry,
70
+ });
71
+ }
72
+ catch (error) {
73
+ // Clean up browser if still open
74
+ if (manager) {
75
+ try {
76
+ await closeBrowser(manager, false);
77
+ }
78
+ catch {
79
+ // Ignore cleanup errors
80
+ }
81
+ }
82
+ const message = error instanceof Error ? error.message : 'Unknown error';
83
+ return err(createError(ErrorCode.UNKNOWN, `Token refresh via browser failed: ${message}`, { suggestions: ['Call teams_login to re-authenticate'] }));
84
+ }
85
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Authentication handling for Microsoft Teams.
3
+ * Manages login detection and manual authentication flows.
4
+ */
5
+ import type { Page, BrowserContext } from 'playwright';
6
+ export interface AuthStatus {
7
+ isAuthenticated: boolean;
8
+ isOnLoginPage: boolean;
9
+ currentUrl: string;
10
+ }
11
+ /**
12
+ * Gets the current authentication status.
13
+ */
14
+ export declare function getAuthStatus(page: Page): Promise<AuthStatus>;
15
+ /**
16
+ * Navigates to Teams and checks authentication status.
17
+ *
18
+ * Uses a fast redirect-based detection: if we're not redirected to a login
19
+ * page within a few seconds, the session is valid. This is much faster than
20
+ * waiting for the full Teams SPA to render (which can take 30+ seconds).
21
+ *
22
+ * Returns isAuthenticated: false if we can't confirm we're on Teams, to avoid
23
+ * silently failing with an invisible browser stuck on an unexpected page.
24
+ */
25
+ export declare function navigateToTeams(page: Page): Promise<AuthStatus>;
26
+ /**
27
+ * Waits for the user to complete manual authentication.
28
+ * Returns when authenticated or throws after timeout.
29
+ *
30
+ * @param page - The page to monitor
31
+ * @param context - Browser context for saving session
32
+ * @param timeoutMs - Maximum time to wait (default: 5 minutes)
33
+ * @param onProgress - Callback for progress updates
34
+ * @param showOverlay - Whether to show progress overlay (default: true for visible browsers)
35
+ */
36
+ export declare function waitForManualLogin(page: Page, context: BrowserContext, timeoutMs?: number, onProgress?: (message: string) => void, showOverlay?: boolean): Promise<void>;
37
+ /**
38
+ * Performs a full authentication flow:
39
+ * 1. Navigate to Teams
40
+ * 2. Check if already authenticated
41
+ * 3. If not, wait for manual login (or throw if headless)
42
+ *
43
+ * @param page - The page to use
44
+ * @param context - Browser context for session management
45
+ * @param onProgress - Callback for progress updates
46
+ * @param showOverlay - Whether to show progress overlay (default: true for visible browsers)
47
+ * @param headless - If true, throw immediately if user interaction is required (default: false)
48
+ */
49
+ export declare function ensureAuthenticated(page: Page, context: BrowserContext, onProgress?: (message: string) => void, showOverlay?: boolean, headless?: boolean): Promise<void>;
50
+ /**
51
+ * Forces a new login by clearing session and navigating to Teams.
52
+ */
53
+ export declare function forceNewLogin(page: Page, context: BrowserContext, onProgress?: (message: string) => void): Promise<void>;