| name | exo-teams |
| description | CLI tool for Microsoft Teams internal API - no admin consent required. Use when working with Teams messages, DMs, assignments, class materials, file uploads, calendar, or deadlines. Trigger on "teams", "exo-teams", "microsoft teams", "assignments", "class materials", "send message teams", "teams files", "uni automation", "deadlines", or "submit assignment". |
| argument-hint | [command or 'help'] |
exo-teams
Go CLI for Microsoft Teams using the internal (desktop app) API. No admin consent, no Graph API registration, no IT department. Tokens stored at ~/.exo-teams/.
Auth
Five token scopes, all acquired via device code OAuth (exo-teams auth):
| Token | Used for |
|---|
| skype | messaging, activity feed, read receipts |
| chatsvcagg | teams/channels/chats listing |
| teams | middle tier ops |
| graph | calendar, files, search, user profiles |
| assignments | education assignments via assignments.onenote.com (bypasses admin consent) |
Tokens auto-refresh. Check status with exo-teams whoami.
Skypetoken quirk: messaging uses Authentication: skypetoken=<value> header, NOT Authorization: Bearer. The skypetoken is derived from the raw skype JWT via an authz exchange endpoint.
Quick Start
exo-teams auth
exo-teams whoami
exo-teams list-teams
exo-teams list-chats
Command Reference
See references/commands.md for full flag docs. Quick map:
| Command | What it does |
|---|
auth [--import|--refresh] | login, import from fossteams, or force refresh |
whoami | account info + per-token expiry |
list-teams | all teams + channels with IDs |
list-chats | all DMs + group chats with IDs |
get-messages <search> | channel messages by name search or ID |
get-chat <search> | DM/group chat messages |
send <conv-id> <message> | send text to any conversation |
send-file <conv-id> --file <path> | upload file to OneDrive, send share link |
new-dm <name> <message> | find user by name, open DM, send message |
files <team-search> | list SharePoint files |
upload <team-search> --path --file | upload to SharePoint |
download <team-search> --path | download from SharePoint |
calendar [--days N] | upcoming calendar events (default 7 days) |
assignments [--classes] | all assignments with submission status |
submit <class> <assignment> --file | submit a file to an assignment |
deadlines | pending assignments sorted by due date |
unread | unread conversations at a glance |
activity | activity feed (mentions, replies, reactions) |
search <query> | search messages + files |
mark-read <conv-id> | mark conversation as read |
All commands accept --json for machine-readable output.
Data Discovery Guide
See references/data-discovery.md for full patterns. Critical ones:
Find team/channel IDs:
exo-teams list-teams
Find chat/DM IDs:
exo-teams list-chats
Find your user ID:
exo-teams whoami --json
Find assignment IDs:
exo-teams assignments --classes
exo-teams assignments --json
Key Gotchas
- Conversation IDs contain
: and @ - they are always URL-encoded internally, but pass them raw to CLI args
chat.hidden is unreliable - most active DMs have hidden=true, use list-chats not hidden filter
annotationsSummary.emotions returns either []any or map[string]any depending on message
- File upload to DMs uses OneDrive ("Microsoft Teams Chat Files" folder) + share link, not AMS
- SharePoint upload (team files) uses Graph PUT to
/groups/{id}/drive/root:/{path}:/content
- 423 on OneDrive upload means file is locked - tool auto-retries with deduped name up to 5 times
- Activity feed reads from a special conversation ID
48:notifications
- Unread status comes from
isRead field on Chat which can be bool or null - null means read
- Search uses Graph
/search/query with message + driveItem entity types (no Chat.Read needed)
assignments command uses assignments.onenote.com API not Graph /education/ (bypasses admin consent)
Common Patterns
exo-teams deadlines
exo-teams get-messages "Academic Writing" --replies --count 50
exo-teams get-messages "General" --all
exo-teams get-messages "General" --since 2026-03-01
exo-teams send-file "19:abc@unq.gbl.spaces" --file report.pdf --message "here it is"
exo-teams send-file "19:abc@unq.gbl.spaces" --file a.pdf --file b.docx
exo-teams files "Academic Writing" --drive "Class Materials"
exo-teams download "Academic Writing" --path "Class Materials/week1.pdf" --drive "Class Materials"
exo-teams submit "Academic Writing" "Essay 1" --file essay.docx
exo-teams get-messages "General" --all --json > general.json
Scripting Patterns
See references/scripting.md for full automation examples including:
- Fetch all pending assignments + download class materials
- Monitor channel for new messages (poll loop)
- Export full conversation to markdown
- Bulk-send files across multiple conversations