| name | msgraph |
| description | Work with Microsoft 365 services via the Graph API — emails, calendar events, SharePoint sites (read and write), Teams chats and channel messages, OneDrive files, OneNote notebooks, contacts, and org chart. Use this skill whenever the user asks about their emails, inbox, unread messages, meetings, calendar, Teams messages or chats, channel messages, SharePoint documents, OneDrive files, OneNote notes or notebooks, colleagues, manager, direct reports, or any personal/organizational Microsoft data. Invoke proactively any time the user mentions Outlook, Teams, SharePoint, OneDrive, OneNote, or wants to interact with their Microsoft 365 account. The skill uses a local Node.js CLI (msgraph.js) that handles authentication, token caching, and all API calls.
|
Microsoft Graph API Skill
This skill lets you interact with Microsoft 365 services on behalf of the user using the
Microsoft Graph API. The Node.js CLI at scripts/msgraph.js handles everything — no Python
or extra packages needed, only the Node.js that CodeMie already requires.
Setup & Authentication
Check login status first — always run this before any other command:
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js status
Output interpretation:
Logged in as: user@company.com → proceed with any command below
NOT_LOGGED_IN → follow the Login Flow below
TOKEN_EXPIRED → session expired, also follow the Login Flow below
Login Flow (first time or after expiry)
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js login
This opens the system browser for Microsoft authentication (PKCE flow). If the browser
does not open automatically, a URL will be printed in the terminal — navigate to it manually.
After successful sign-in, the token is cached at ~/.ms_graph_token_cache.json and all
subsequent commands run silently.
Use --force to re-authenticate even when already logged in:
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js login --force
When NOT logged in or token expired
If status returns NOT_LOGGED_IN or TOKEN_EXPIRED, tell the user:
"You need to log in to Microsoft first. Run this command in your terminal:
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js login
Your browser will open for Microsoft sign-in. If it doesn't open automatically, a URL
will appear in the terminal — navigate to it to complete authentication."
Available Commands
Profile & Org
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js me
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js org --manager
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js org --reports
Emails
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --limit 25
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --unread
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --search "invoice Q4"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --read MESSAGE_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --send recipient@example.com --subject "Hello" --body "Message text"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --folder sentitems --limit 5
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js emails --json
Calendar
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js calendar
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js calendar --limit 20
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js calendar --create "Team Standup" \
--start "2024-03-20T09:00" --end "2024-03-20T09:30" \
--location "Teams" --timezone "Europe/Berlin"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js calendar --availability \
--start "2024-03-20T09:00:00" --end "2024-03-20T18:00:00"
SharePoint
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js sharepoint --sites
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js sharepoint --site SITE_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js sharepoint --site SITE_ID --path "Documents/Reports"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js sharepoint --download ITEM_ID --output report.xlsx
Teams
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js teams --chats
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js teams --messages CHAT_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js teams --send "Hello team!" --chat-id CHAT_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js teams --teams-list
OneDrive
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onedrive
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onedrive --path "Documents"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onedrive --upload ./report.pdf --dest "Documents/report.pdf"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onedrive --download ITEM_ID --output local_copy.pdf
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onedrive --info ITEM_ID
OneNote
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --notebooks
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --sections NOTEBOOK_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --pages SECTION_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --read PAGE_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --search "meeting notes"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --create "My Note" \
--section SECTION_ID --body "Note content here"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js onenote --notebooks --json
Channels
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js channels --team-id TEAM_ID --list
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js channels --team-id TEAM_ID --channel-id CHANNEL_ID --messages
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js channels --team-id TEAM_ID --channel-id CHANNEL_ID --send "Hello channel!"
Transcripts
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --start 2026-03-06
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --start 2026-03-06 --end 2026-03-07
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --start 2026-03-06 --subject "standup"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --meeting MEETING_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --meeting MEETING_ID --transcript TRANSCRIPT_ID
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --meeting MEETING_ID --transcript TRANSCRIPT_ID --output meeting.txt
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js transcripts --meeting MEETING_ID --transcript TRANSCRIPT_ID --vtt --output meeting.vtt
People & Contacts
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js people
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js people --search "Alice"
node ${CLAUDE_PLUGIN_ROOT}/skills/msgraph/scripts/msgraph.js people --contacts
Workflow Patterns
"Show me my emails"
- Run
status → check login
- Run
emails --limit 15 → show results
- If user wants to read one, run
emails --read ID
"What's on my calendar today/this week?"
- Run
calendar --limit 10
- Parse dates in output and filter for user's timeframe
"Find a file in SharePoint"
- Run
sharepoint --sites → list sites
- Run
sharepoint --site SITE_ID → browse files
- Use
--path to drill into folders
- Offer
--download ITEM_ID if user wants the file
"Check my Teams messages"
- Run
teams --chats → list chats
- User picks a chat → run
teams --messages CHAT_ID
"Show me my OneNote notes" / "Find a note about X"
- Run
onenote --notebooks → list notebooks
- Run
onenote --sections NOTEBOOK_ID → list sections
- Run
onenote --pages SECTION_ID → list pages, or use onenote --search "keyword" to search directly
- Run
onenote --read PAGE_ID → display page content
"Show me the transcript from yesterday's standup"
- Run
transcripts --start YYYY-MM-DD --subject "standup" → finds the meeting and lists transcript IDs
- Run
transcripts --meeting MEETING_ID --transcript TRANSCRIPT_ID → reads full transcript text
"Get all meeting transcripts for today"
- Run
transcripts --start YYYY-MM-DD → lists all online meetings for the day
- Run
transcripts --meeting MEETING_ID → lists available transcripts per meeting
- Run
transcripts --meeting MEETING_ID --transcript TRANSCRIPT_ID --output meeting.txt → saves each transcript
"Post a message to a Teams channel"
- Run
teams --teams-list → get the team ID
- Run
channels --team-id TEAM_ID --list → get the channel ID
- Run
channels --team-id TEAM_ID --channel-id CHANNEL_ID --send "message"
"Who's my manager?" / "Who reports to me?"
- Run
org --manager or org --reports
Error Handling
| Exit code | Meaning |
|---|
| 0 | Success |
| 1 | API error (shown in output) |
| 2 | NOT_LOGGED_IN — user must run login |
When you see Permission denied errors, it means the OAuth scope isn't granted for that operation.
This can happen if the user's organization has restricted certain Graph API permissions.
Dependencies
None — the script uses only built-in Node.js modules (https, fs, path, os).
Node.js >= 18 is required, which is already a CodeMie prerequisite.
IMPORTANT: you must work with current date (get it from sh/bash)