auth-status
Check authentication status with Microsoft Graph API to verify token validity and determine if refresh is needed for Microsoft Todo task management.
Instructions
Check if you're authenticated with Microsoft Graph API. Shows current token status and expiration time, and indicates if the token needs to be refreshed.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/todo-index.ts:301-358 (registration)Registration of the 'auth-status' tool. Includes empty input schema {}, detailed description, and inline async handler function that reads tokens from file or memory, checks expiration, determines if personal Microsoft account, and returns markdown text with authentication status.server.tool( "auth-status", "Check if you're authenticated with Microsoft Graph API. Shows current token status and expiration time, and indicates if the token needs to be refreshed.", {}, async () => { const tokens = readTokens(); if (!tokens && !currentAccessToken) { return { content: [ { type: "text", text: "Not authenticated. Please run auth-server.js to authenticate with Microsoft.", }, ], }; } const tokenData = tokens || { accessToken: currentAccessToken || "", refreshToken: currentRefreshToken || "", expiresAt: 0 }; const isExpired = Date.now() > tokenData.expiresAt; const expiryTime = new Date(tokenData.expiresAt).toLocaleString(); // Check if it's a personal account const isPersonal = await isPersonalMicrosoftAccount(); let accountMessage = ""; if (isPersonal) { accountMessage = "\n\n⚠️ WARNING: You are using a personal Microsoft account. " + "Microsoft To Do API access is typically not available for personal accounts " + "through the Microsoft Graph API. You may encounter 'MailboxNotEnabledForRESTAPI' errors. " + "This is a Microsoft limitation, not an authentication issue."; } if (isExpired) { return { content: [ { type: "text", text: `Authentication expired at ${expiryTime}. Will attempt to refresh when you call any API.${accountMessage}`, }, ], }; } else { return { content: [ { type: "text", text: `Authenticated. Token expires at ${expiryTime}.${accountMessage}`, }, ], }; } } );
- src/todo-index.ts:305-357 (handler)Inline handler function for the auth-status tool. Checks if tokens exist, determines expiration status, calls helper to check for personal account, constructs warning message if applicable, and returns structured content with authentication status and expiration info.async () => { const tokens = readTokens(); if (!tokens && !currentAccessToken) { return { content: [ { type: "text", text: "Not authenticated. Please run auth-server.js to authenticate with Microsoft.", }, ], }; } const tokenData = tokens || { accessToken: currentAccessToken || "", refreshToken: currentRefreshToken || "", expiresAt: 0 }; const isExpired = Date.now() > tokenData.expiresAt; const expiryTime = new Date(tokenData.expiresAt).toLocaleString(); // Check if it's a personal account const isPersonal = await isPersonalMicrosoftAccount(); let accountMessage = ""; if (isPersonal) { accountMessage = "\n\n⚠️ WARNING: You are using a personal Microsoft account. " + "Microsoft To Do API access is typically not available for personal accounts " + "through the Microsoft Graph API. You may encounter 'MailboxNotEnabledForRESTAPI' errors. " + "This is a Microsoft limitation, not an authentication issue."; } if (isExpired) { return { content: [ { type: "text", text: `Authentication expired at ${expiryTime}. Will attempt to refresh when you call any API.${accountMessage}`, }, ], }; } else { return { content: [ { type: "text", text: `Authenticated. Token expires at ${expiryTime}.${accountMessage}`, }, ], }; } }
- src/todo-index.ts:246-297 (helper)Helper function specifically used by auth-status handler to determine if the authenticated Microsoft account is personal (non-business) by fetching /me endpoint and checking email domain against known personal domains, logging detailed warning if so.async function isPersonalMicrosoftAccount(): Promise<boolean> { try { const token = await getAccessToken(); if (!token) return false; // Make a request to get user info const url = `${MS_GRAPH_BASE}/me`; const response = await fetch(url, { method: "GET", headers: { "Authorization": `Bearer ${token}`, "Accept": "application/json" } }); if (!response.ok) { console.error(`Error getting user info: ${response.status}`); return false; } const userData = await response.json(); const email = userData.mail || userData.userPrincipalName || ''; // Check if the email domain indicates a personal account const personalDomains = ['outlook.com', 'hotmail.com', 'live.com', 'msn.com', 'passport.com']; const domain = email.split('@')[1]?.toLowerCase(); if (domain && personalDomains.some(d => domain.includes(d))) { console.error(` ================================================================= WARNING: Personal Microsoft Account Detected Your Microsoft account (${email}) appears to be a personal account. Microsoft To Do API access is typically not available for personal accounts through the Microsoft Graph API, only for Microsoft 365 business accounts. You may encounter the "MailboxNotEnabledForRESTAPI" error when trying to access To Do lists or tasks. This is a limitation of the Microsoft Graph API, not an issue with your authentication or this application. You can still use Microsoft To Do through the web interface or mobile apps, but API access is restricted for personal accounts. ================================================================= `); return true; } return false; } catch (error) { console.error("Error checking account type:", error); return false; }
- src/todo-index.ts:42-58 (helper)Helper function to read authentication tokens from tokens.json file, parse JSON, log details, used by auth-status to check current token status.function readTokens(): TokenData | null { try { console.error(`Attempting to read tokens from: ${TOKEN_FILE_PATH}`); if (!existsSync(TOKEN_FILE_PATH)) { console.error('Token file does not exist'); return null; } const data = readFileSync(TOKEN_FILE_PATH, 'utf8'); console.error('Token file content length:', data.length); const tokenData = JSON.parse(data) as TokenData; console.error('Token parsed successfully, expires at:', new Date(tokenData.expiresAt).toLocaleString()); return tokenData; } catch (error) { console.error('Failed to read tokens from file:', error); return null; }