Delegated permissions¶
Every tool and the Microsoft Graph delegated permission it needs. Generated from the tool descriptions, so it cannot drift from the code.
This server only ever uses delegated permissions — it acts as the signed-in user and can never see more than they can. There are no application permissions anywhere in the tool surface.
See the README for the app-registration walkthrough, and configuration.md for the settings. This document is the reference for which permissions to grant.
Consent sets¶
Paste one of these into GRAPH_MCP_SCOPES, and add the matching permissions under API permissions → Microsoft Graph → Delegated in the portal. The two must agree: if a scope is requested but not consented, sign-in still succeeds and the tool later returns SCOPE_DENIED naming the one that is missing.
Read-only — 53 tools, nothing can be changed or sent¶
Calendars.Read,Calendars.Read.Shared,Calendars.ReadBasic,Channel.ReadBasic.All,ChannelMessage.Read.All,Chat.Read,Contacts.Read,Files.Read,Files.Read.All,Group.Read.All,GroupMember.Read.All,Mail.Read,Notes.Read,OnlineMeetingArtifact.Read.All,OnlineMeetingTranscript.Read.All,OnlineMeetings.Read,People.Read,Sites.Read.All,Tasks.Read,Team.ReadBasic.All,User.Read,User.Read.All
Adding write access — 23 further tools¶
Append these to the read set. They let an agent send mail, book meetings, post to Teams and change files as the user, so grant them deliberately.
Calendars.ReadWrite,ChatMessage.Send,Contacts.ReadWrite,Files.ReadWrite,Files.ReadWrite.All,Mail.ReadWrite,Mail.Send,Notes.Create,Tasks.ReadWrite
Write tools also need GRAPH_MCP_WRITE_SCOPE=true; the scopes alone are not enough. After changing scopes, delete ~/.ms-graph-mcp/token_cache.json to force a fresh consent — the cached token carries only what was originally granted.
Read tools¶
| Tool | Delegated permission | What it does |
|---|---|---|
| calendar | ||
calendar_find_meeting_times | Calendars.Read.Shared | Ask Microsoft Graph to suggest meeting times when the given attendees are free, ranked by how likely everyone is to attend. |
calendar_get_event | Calendars.Read | Get one calendar event in full by its id: subject, times, organiser, location, agenda preview, the Teams join URL and the complete attendee list with each person's response status. |
calendar_get_event_attendees | Calendars.Read | List who was invited to a calendar event and how each person replied — accepted, declined, tentative or no response. |
calendar_get_free_busy | Calendars.ReadBasic | Look up whether people are free or busy across a time window, without seeing what their meetings are. |
calendar_list_events_in_range | Calendars.Read | List calendar events between two dates, in chronological order. |
calendar_list_upcoming_events | Calendars.Read | List the signed-in user's upcoming calendar events for the next N days, soonest first. |
| chat | ||
chat_list | Chat.Read | List the signed-in user's Microsoft Teams chats — the 1:1 and group conversations, not team channels. |
chat_list_channel_messages | ChannelMessage.Read.All | Read the most recent messages in one Teams channel, newest first, given a team id and channel id from chat_list_teams and chat_list_channels. |
chat_list_channels | Channel.ReadBasic.All | List the channels in one Microsoft Teams team, with id, name and description. |
chat_list_members | Chat.Read | List who is in a Teams chat, with display name and email, given a chat id from chat_list. |
chat_list_messages | Chat.Read | Read recent messages from one Teams chat, newest first, given a chat id from chat_list. |
chat_list_teams | Team.ReadBasic.All | List the Microsoft Teams the signed-in user is a member of, with id, name and description. |
chat_search_messages | Chat.Read | Search Microsoft Teams messages the signed-in user can see, across every team and chat, by keyword. |
| directory | ||
directory_get_group | Group.Read.All | Get one Entra ID group's details by id: display name, description, type, email address, visibility and creation date. |
directory_get_user | User.Read.All | Get one tenant user's full directory profile by email or UPN, including their manager. |
directory_get_user_manager | User.Read.All | Get the person a given user reports to, identified by email or UPN. |
directory_list_group_members | GroupMember.Read.All | List the people in an Entra ID group, given a group id from directory_search_groups. |
directory_list_user_groups | GroupMember.Read.All | List the Entra ID groups a user is a direct member of, by email or UPN. |
directory_search_groups | Group.Read.All | Find Entra ID groups by name or keyword. |
directory_search_users | User.Read.All | Search every user account in the Entra ID tenant directory by display name, email or UPN. |
| files | ||
files_get_content | Files.Read.All | Read the text content of a file in OneDrive or SharePoint, given a drive id and item id from files_search or files_list_recent. |
files_get_group_drive | Files.Read.All, Group.Read.All | Get the document library backing a Microsoft 365 group or Teams team, given a group id from directory_search_groups. |
files_list_recent | Files.Read | List files the signed-in user has recently opened or edited, most recent first. |
files_list_shared_with_me | Files.Read.All | List files other people have shared directly with the signed-in user, with the owner and web URL for each. |
files_list_trending | Files.Read.All | List documents currently trending around the signed-in user — files their colleagues are actively working on, ranked by Microsoft 365 activity signals rather than by the user's own history. |
files_search | Files.Read.All | Search the signed-in user's OneDrive and the SharePoint sites they can reach, by filename or content keyword. |
mail_get_thread | Mail.Read | Read every message in one email conversation, oldest first, given a conversation id from any of the mail listing tools. |
mail_list_attachments | Mail.Read | List the file attachments on one email — name, content type and size in bytes. |
mail_list_flagged | Mail.Read | List emails the signed-in user has flagged for follow-up, newest first. |
mail_list_recent | Mail.Read | List the signed-in user's most recent emails from the last N days, newest first. |
mail_search | Mail.Read | Search the signed-in user's mailbox by keyword, subject or sender name. |
| meetings | ||
meetings_get_attendance_report | OnlineMeetingArtifact.Read.All | Get who actually attended a Teams meeting, with join and leave times and total duration per person, given an online meeting id. |
meetings_get_from_join_url | OnlineMeetings.Read | Resolve a Teams join URL to its online meeting record, returning the online meeting id, subject and start time. |
meetings_get_transcript | OnlineMeetingTranscript.Read.All | Get the spoken transcript of a Teams meeting as time-stamped speaker turns. |
meetings_get_transcript_by_event | OnlineMeetingTranscript.Read.All | Get a meeting transcript starting from a calendar event id, resolving the event to its join URL and then the online meeting. |
meetings_list_past | Calendars.Read | List the signed-in user's meetings from the last N days, most recent first, optionally restricted to online ones. |
meetings_list_transcripts | OnlineMeetingTranscript.Read.All | List the transcripts available for one online meeting, given an online meeting id from meetings_get_from_join_url. |
meetings_list_with_transcripts | Calendars.Read, OnlineMeetingTranscript.Read.All | List recent meetings and flag which ones actually have a transcript, checking each concurrently. |
| notes | ||
notes_get_page_content | Notes.Read | Read the contents of one OneNote page, given a page id from notes_list_pages. |
notes_list_notebooks | Notes.Read | List the signed-in user's OneNote notebooks, with id, name, last-modified date and web URL. |
notes_list_pages | Notes.Read | List the pages in one OneNote section, with id, title, creation date and web URL. |
notes_list_sections | Notes.Read | List the sections inside one OneNote notebook, with id, name and last-modified date. |
| people | ||
people_get | User.Read.All | Look up one person in the organisation by their exact email address and return their profile: display name, job title, department, office location and phone numbers. |
people_get_my_profile | User.Read | Get the signed-in user's own profile — their name, email address, job title, department and office. |
people_list_contacts | Contacts.Read | List the signed-in user's saved Outlook contacts, with names, email addresses and phone numbers. |
people_search | People.Read | Find colleagues the signed-in user actually works with, ranked by relevance from their own mail and meeting history — so it finds the right 'Priya' without exact spelling. |
people_search_contacts | Contacts.Read | Search the signed-in user's saved Outlook contacts by name or company, returning emails and phone numbers. |
| search | ||
search_query | Mail.Read, Calendars.Read, Files.Read.All, Sites.Read.All, People.Read | Search across Microsoft 365 in one call — email, calendar events, files, SharePoint sites and lists, and people. |
| tasks | ||
tasks_list_planner_buckets | Tasks.Read | List the buckets (columns) in a Planner plan, with id and name. |
tasks_list_planner_plans | Tasks.Read | List the Microsoft Planner plans the signed-in user can see, with id and title. |
tasks_list_planner_tasks | Tasks.Read | List the tasks on a Planner plan's board, given a plan id from tasks_list_planner_plans. |
tasks_list_todo | Tasks.Read | List the signed-in user's Microsoft To Do tasks, optionally narrowed to one list and to a status of notStarted, inProgress, completed or all. |
tasks_list_todo_lists | Tasks.Read | List the signed-in user's Microsoft To Do lists, with id and display name. |
Write tools¶
Reachable only when the caller supplies write scope, and never when GRAPH_MCP_READ_ONLY is set.
| Tool | Delegated permission | What it does |
|---|---|---|
| calendar | ||
calendar_cancel_event | Calendars.ReadWrite | Cancel a meeting the signed-in user organised, notifying every attendee with an optional note. |
calendar_create_event | Calendars.ReadWrite | Create a calendar event for the signed-in user and invite people to it. |
calendar_respond_to_event | Calendars.ReadWrite | Reply to a meeting invitation on the signed-in user's behalf — accept, decline or tentativelyAccept — with an optional note to the organiser. |
calendar_update_event | Calendars.ReadWrite | Change an existing calendar event — its title, time, location or agenda. |
| chat | ||
chat_send_message | ChatMessage.Send | Send a message to a Teams chat as the signed-in user, given a chat id from chat_list. |
| files | ||
files_create_folder | Files.ReadWrite | Create a folder in the signed-in user's OneDrive, creating any missing parent folders along the way. |
files_create_sharing_link | Files.ReadWrite.All | Create a shareable link to a OneDrive or SharePoint file and return the URL. |
files_update_content | Files.ReadWrite | Replace the contents of an existing OneDrive file, keeping its id, URL and sharing permissions intact. |
files_upload | Files.ReadWrite | Create a new text file in the signed-in user's OneDrive and return its id, name and web URL. |
mail_forward | Mail.Send | Forward an email to other people, with an optional note above it. |
mail_mark_read | Mail.ReadWrite | Mark an email as read or unread. |
mail_propose | Calendars.Read | Draft an email about a meeting for the user to review and send themselves — it does NOT send anything. |
mail_reply | Mail.Send | Reply to an email, sending only to its original sender. |
mail_reply_all | Mail.Send | Reply to an email, sending to the sender and everyone else on the thread. |
mail_send | Mail.Send | Send an email as the signed-in user, with an HTML body and optional CC recipients. |
| notes | ||
notes_create_page | Notes.Create | Create a new page in a OneNote section and return its id and web URL. |
| people | ||
people_create_contact | Contacts.ReadWrite | Save a new contact to the signed-in user's Outlook address book, with name and optional email, phone numbers, company and job title. |
| tasks | ||
tasks_complete_planner | Tasks.ReadWrite | Mark a Planner task as done by setting its progress to 100 percent, which is how Planner represents completion. |
tasks_complete_todo | Tasks.ReadWrite | Mark a Microsoft To Do task as done. |
tasks_create_planner | Tasks.ReadWrite | Create a task on a shared Planner board. |
tasks_create_todo | Tasks.ReadWrite | Add a task to the signed-in user's Microsoft To Do, optionally with a due date and notes. |
tasks_update_planner | Tasks.ReadWrite | Change a task on a Planner board — its title, progress percentage, bucket or due date. |
tasks_update_todo | Tasks.ReadWrite | Change a Microsoft To Do task — its title, status, importance, due date or notes. |
Internal tools¶
Not part of the agent surface. Reachable only by the shared-secret machine principal together with X-Internal-Scope: true, and never advertised to an LLM client. They exist for first-party ETL and service callers.
| Tool | Delegated permission | What it does |
|---|---|---|
| fetch | ||
fetch_message_attachments | — | INTERNAL — list + download a message's non-inline file attachments. |
| graph | ||
graph_download_drive_item | — | INTERNAL — download a DriveItem's raw bytes and return them base64-encoded. |
graph_ensure_drive_folder | — | INTERNAL — ensure a root-relative folder path exists on a drive, creating any missing intermediates. |
graph_get_group_drive | — | INTERNAL — resolve a Microsoft 365 group (Team) to its default SharePoint document-library drive. |
graph_request | — | INTERNAL passthrough — issue an arbitrary Microsoft Graph request. |
graph_update_drive_item_content | — | INTERNAL — overwrite the content of an existing OneDrive item (content base64-encoded). |
graph_upload_file_to_drive | — | INTERNAL — upload a file to a drive (content base64-encoded). |
graph_walk_drive_descendants | — | INTERNAL — recursively walk a drive folder server-side and return its descendant file items as a list. |
| probe | ||
probe_graph_access | — | INTERNAL app-only — GET a Graph path and return its HTTP status code without raising (RBAC revalidation). |
Notes¶
SCOPE_DENIEDnames the permission it needed. The error is terminal and not retryable — a model receiving it should tell the user what to request rather than trying again.- Guest accounts cannot enumerate the directory.
directory_search_usersanddirectory_search_groupsfail for guests regardless of consent; Microsoft blocks the query itself, not the permission. - The OneNote API has no application-permission support at all, so those tools are delegated by necessity rather than by choice.
X-Entra-App-Tokenis an optional separate app-only token, used only for tenant-wide group lookups that delegated permissions cannot cover. It is never required.