Secure Microsoft 365 access for AI agents, without a Copilot license
Mail, calendar, contacts, OneNote, files, Teams chats and channels, and meeting data via Microsoft Graph – no Copilot license required
Microsoft 365 Graph connects your agents to mail, calendar, contacts, OneNote, and OneDrive files, plus Teams chats, channels, and meeting recordings, transcripts, and attendance data, by calling Microsoft Graph directly with each user's own signed-in token. Every call runs through your policies and is logged for audit. It needs only a standard Microsoft 365 subscription, with no Microsoft 365 Copilot license required.
Credential modes
Microsoft 365 Graph supports bring your own app only. It does not support dynamic client registration, so your organization registers its own Entra app in Azure and supplies the client ID and secret. See Credential modes for how the modes compare.
Before you begin
- A Microsoft Entra admin able to register an application in your tenant, and to grant admin consent for it. Any user can register an app by default unless your tenant restricts this, but the consent step needs an admin.
- Administrator access to your Agent Authority workspace, to add the resource.
Setup moves between two consoles. You copy a redirect URI in the Agent Authority console, register an app in Microsoft Entra and grant consent, then return to the console and paste the credentials. Keep both tabs open as you work.
Setup
1. Copy the redirect URI
In the Agent Authority console, go to Resources → Add Resource and select Microsoft 365 Graph. This resource is bring-your-own-app only, so the credentials form opens as soon as you select it, with no mode to pick.
Copy the Redirect URI shown on the form. It includes your tenant's region, so copy it rather than typing it. It takes the form https://oauth.aisecurity.services.<region>.connect.secureauth.com/auth/callback.
Leave this page open. You come back to it in step 4.
2. Register an Entra app in Azure
Sign in to portal.azure.com and go to Microsoft Entra ID → App registrations → New registration.
Register the app
Configure:
- Name – your preferred name, for example
<your-company> AI Gateway - Microsoft 365 Graph - Supported account types – Multiple Entra ID tenants, with Allow all tenants as the sub-option, which is the default. Multi-tenant is required because the gateway's OAuth flow uses Microsoft's
/commonendpoint, which does not accept single-tenant apps. - Redirect URI – choose the Web platform and paste the Redirect URI from the form in the Agent Authority console, using the Copy button next to it
Click Register.
Add the API permissions
On the new app's API permissions page, click Add a permission → Microsoft Graph → Delegated permissions, and add the scopes listed under Required scopes.
The three OpenID Connect scopes (offline_access, openid, profile) live under the OpenId permissions section near the bottom of the picker, which is easy to miss because they are not in the main alphabetical list.
Create a client secret
On Certificates & secrets, click New client secret and set an expiry. Copy the secret value immediately, because Microsoft only displays it once. This is your Client Secret.
Then copy the Application (client) ID from the app's Overview page. This is your Client ID.
3. Grant admin consent
On the API permissions page, click Grant admin consent for <your tenant> at the top of the permissions list.
Without admin consent, users cannot connect at all
Several of the Teams scopes are not user-consentable, so this step is required
rather than optional. Skip it and users fail to connect with an AADSTS65001
consent error.
4. Finish in the console
Back on the Microsoft 365 Graph form in the Agent Authority console, paste the Client ID and Client Secret. Leave Token Endpoint Authentication on Auto-detect. Then click Add.
The resource is added with all tools and scopes pre-configured, and an Admin setup required dialog appears with a Setup guide button linking back to this page.
Upgrading an existing installation
This connector's catalog entry added 13 delegated scopes for Teams chats, channels, and teams. If you installed this resource before Teams support shipped, add the new scopes listed under Required scopes to your existing Entra app registration, then re-grant admin consent.
Existing connections also need to reconnect: the new Teams tools do not appear on a connection until it is re-authenticated.
Verify the connection
The gateway syncs the Microsoft 365 tools automatically. To check the connection end to end, ask your agent to run a request:
Show my Microsoft 365 profileIf your name and email come back, the connection is working.
How users connect
Access is per user. Each additional user connects their own Microsoft 365 account the first time their agent calls a Microsoft 365 tool: the gateway returns a sign-in link, the user authorizes once, and the tools work from then on. Go to Connections to manage linked accounts.
Each call uses the signed-in user's own token, so Microsoft 365's own permissions control what they can reach. The gateway does not widen access beyond what the authenticated user could already do in Microsoft 365.
Available tools
All 125 tools ship with the catalog entry, so they appear in tool lists and policy pickers as soon as the resource is installed. Each is a direct pass-through to a Microsoft Graph operation, so the agent composes them the same way it would call Graph.
Mail – search & read
| Tool | Description |
|---|---|
list_messages | List messages in the mailbox, newest first; select/top/filter/search supported |
get_messages | Get a single message by ID |
list_mail_folders | List mail folders (Inbox, Drafts, Sent Items, and so on) |
list_mail_child_folders | List child folders of a mail folder |
list_mail_folder_messages | List messages within a specific mail folder |
Mail – drafts & sending
| Tool | Description |
|---|---|
create_draft | Create a draft message (send later with send_draft) |
send_draft | Send an existing draft by ID |
send_mail | Send a message directly |
reply_message | Reply to the sender; saved to Sent Items |
reply_all_message | Reply to all recipients; saved to Sent Items |
create_reply_draft | Create a draft reply to the sender, without sending it |
create_reply_all_draft | Create a draft reply to all recipients, without sending it |
forward_message | Forward a message to new recipients |
Mail – manage & organize
| Tool | Description |
|---|---|
update_message | Update a message by ID (mark read/unread, flag) |
delete_message | Delete a message by ID |
move_mail_message | Move a message to another folder |
create_mail_folder | Create a mail folder |
create_mail_child_folder | Create a child folder inside a mail folder |
update_mail_folder | Rename a mail folder |
delete_mail_folder | Delete a mail folder |
Mail – inbox rules
| Tool | Description |
|---|---|
list_mail_rules | List inbox message rules |
create_mail_rule | Create an inbox rule (conditions and actions) |
update_mail_rule | Update an inbox rule by ID |
delete_mail_rule | Delete an inbox rule by ID |
Mail – attachments
| Tool | Description |
|---|---|
list_attachments | List attachment metadata for a message |
get_attachment | Get a single attachment (includes base64 content for file attachments) |
add_attachment | Add an attachment to a message or draft (inline, under 3 MB) |
delete_attachment | Delete an attachment from a message by ID |
Calendar – events
| Tool | Description |
|---|---|
list_events | List event objects in the mailbox |
list_calendar_view | List events in a time range, with recurrences expanded |
get_events | Get a single event's properties |
create_events | Create an event |
update_event | Update an event by ID |
delete_event | Delete an event by ID |
cancel_event | Cancel an organized event, notifying attendees |
Calendar – invitations
| Tool | Description |
|---|---|
accept_event | Accept an event invitation |
decline_event | Decline an event invitation |
tentatively_accept_event | Tentatively accept an event invitation |
forward_event | Forward an event to additional recipients |
Calendar – calendars & scheduling
| Tool | Description |
|---|---|
list_calendars | List the user's calendars |
create_calendar | Create a secondary calendar |
update_calendar | Rename or recolor a calendar |
delete_calendar | Delete a calendar |
get_schedule | Get free/busy for one or more people over a window |
find_meeting_times | Suggest meeting times from attendee free/busy |
Contacts
| Tool | Description |
|---|---|
list_contacts | List personal contacts |
get_contact | Get a single contact by ID |
create_contact | Create a contact |
update_contact | Update a contact by ID |
delete_contact | Delete a contact by ID |
list_contact_folders | List contact folders |
create_contact_folder | Create a contact folder |
update_contact_folder | Rename a contact folder |
delete_contact_folder | Delete a contact folder |
list_contact_folder_child_folders | List child folders of a contact folder |
create_contact_child_folder | Create a child folder inside a contact folder |
create_contact_in_folder | Create a contact inside a specific folder |
list_folder_contacts | List contacts within a specific folder |
Teams meetings
| Tool | Description |
|---|---|
create_online_meeting | Create a Teams online meeting |
get_online_meeting | Get an online meeting by ID |
update_online_meeting | Update an online meeting by ID |
delete_online_meeting | Delete an online meeting by ID |
list_online_meetings | Find online meetings; filter by join URL to resolve an ID |
list_recordings | List recording metadata for an online meeting |
list_transcripts | List transcripts available for an online meeting |
get_transcript_content | Get a transcript's content (WebVTT) |
list_attendance_reports | List attendance reports for a meeting (one per session) |
list_attendance_records | List per-attendee attendance records for a report |
Teams – chats
| Tool | Description |
|---|---|
list_chats | List the chats the signed-in user is part of |
create_chat | Create a new one-on-one or group chat |
get_chat | Get a single chat by ID |
list_chat_members | List a chat's members |
list_chat_messages | List messages in a chat |
get_chat_message | Get a single message or reply from a chat |
send_chat_message | Send a message in a chat |
reply_to_chat_message | Reply to a message in a chat |
list_chat_message_replies | List replies to a chat message |
list_chat_message_hosted_contents | List hosted content (for example, inline images) on a chat message |
set_chat_message_reaction | Add a reaction to a chat message |
unset_chat_message_reaction | Remove a reaction from a chat message |
list_pinned_chat_messages | List messages pinned in a chat |
pin_chat_message | Pin a message in a chat |
unpin_chat_message | Unpin a message from a chat |
Teams – teams & channels
| Tool | Description |
|---|---|
list_joined_teams | List the teams the signed-in user has joined |
list_my_associated_teams | List teams the user is associated with, including shared-channel host teams |
get_team | Get a team by ID |
list_team_members | List a team's members |
list_team_channels | List a team's channels |
get_team_channel | Get a single channel by ID |
create_team_channel | Create a channel in a team |
update_team_channel | Update a channel's properties |
list_channel_messages | List messages in a channel |
get_channel_message | Get a single message from a channel |
send_channel_message | Send a message in a channel |
reply_to_channel_message | Reply to a message in a channel |
list_channel_message_replies | List replies to a channel message |
list_channel_message_hosted_contents | List hosted content on a channel message |
set_channel_message_reaction | Add a reaction to a channel message |
unset_channel_message_reaction | Remove a reaction from a channel message |
list_channel_tabs | List the tabs configured in a channel |
get_channel_files_folder | Get the drive folder backing a channel's Files tab |
list_my_installed_teams_apps | List Teams apps installed in the signed-in user's personal scope |
OneNote
| Tool | Description |
|---|---|
list_onenote_notebooks | List the user's OneNote notebooks |
create_onenote_notebook | Create a notebook |
get_onenote_notebook_from_web_url | Resolve a notebook from its web URL |
list_onenote_notebook_sections | List the sections in a notebook |
create_onenote_section | Create a section in a notebook |
list_all_onenote_sections | List all sections across notebooks |
list_onenote_section_groups | List section groups |
list_onenote_section_pages | List pages in a section |
list_onenote_pages | List all pages |
get_onenote_page_content | Get a page's HTML content |
delete_onenote_page | Delete a page by ID |
Files & search (OneDrive + SharePoint)
Read-only file access and search across the user's OneDrive and any SharePoint document libraries they can reach. To search a specific library, resolve its drive-id with list_drives first.
| Tool | Description |
|---|---|
list_drives | List the OneDrive and SharePoint drives the user can access |
get_drive_root_item | Get a drive's root item – the starting point for browsing a library |
search_drive | Search a drive (OneDrive or a SharePoint document library) for files by query |
search_folder | Search within a specific folder for files by query |
list_recent_files | List the files the user most recently used across OneDrive and SharePoint |
list_shared_with_me | List files and folders shared with the user, including SharePoint items |
People, presence & search
| Tool | Description |
|---|---|
list_relevant_people | List the people most relevant to the signed-in user |
get_my_presence | Get the signed-in user's Teams presence |
search_query | Run a Microsoft Search query across content types – use entityTypes: ["driveItem"] to find SharePoint & OneDrive documents by keyword |
Profile & settings
| Tool | Description |
|---|---|
user_get_user | Get the signed-in user's profile |
get_mailbox_settings | Get time zone, working hours, language, and auto-reply configuration |
update_mailbox_settings | Update mailbox settings (time zone, working hours, auto-reply) |
Known limitations
A few Graph operations can't be driven by a pure JSON pass-through tool, so they aren't exposed:
- OneNote page creation is not available. You can create notebooks and sections and list, read, and delete pages, but creating a page requires a multipart HTML request body that a pass-through tool can't send.
- Meeting recording content download is not available.
list_recordingsreturns recording metadata; downloading the recording video is a binary stream, not a pass-through call. Transcript content is available viaget_transcript_content. - Large attachment upload is not available. Uploading files over 3 MB requires a chunked upload session. Attachments under 3 MB work via
add_attachment. - Online-meeting AI insights are not available. Microsoft's Copilot-generated meeting summaries and action items are a beta-only API, not present in the pinned Graph spec this connector generates from.
Required scopes
Add all of these under API permissions as delegated permissions, in step 2. Each tool requests the least-privilege scope Microsoft's own permissions data maps to its operation, and the catalog requests the collapsed union across all 125 tools.
openid,profile– sign-in identityoffline_access– maintain access when the user is offlineUser.Read– read the signed-in user's profileMail.ReadWrite– list, search, read, draft, update, move, and delete mail, folders, and attachmentsMail.Send– send mail directly, reply, reply all, and forwardCalendars.ReadWrite– read, create, update, delete, cancel, and respond to calendar events and calendarsCalendars.Read.Shared– suggest meeting times and read free/busy from attendees' shared calendarsContacts.ReadWrite– read, create, update, and delete contacts and contact foldersMailboxSettings.ReadWrite– read and update mailbox settings, and manage inbox rulesNotes.ReadWrite– read and create OneNote notebooks, sections, and pagesFiles.Read.All– list the OneDrive drives the user can accessOnlineMeetings.ReadWrite– create, read, update, and delete the user's online meetingsOnlineMeetingTranscript.Read.All– list and read Teams meeting transcriptsOnlineMeetingRecording.Read.All– list Teams meeting recordingsOnlineMeetingArtifact.Read.All– read meeting attendance reports and recordsPeople.Read– read the user's relevant people listPresence.Read– read the user's presenceChat.Create– create new chatsChat.ReadWrite– read and write chat messagesChatMember.Read– list chat membersChatMessage.Send– send and react to chat messagesChannelMessage.Send– send and react to channel messagesTeam.ReadBasic.All– list and read teamsTeamMember.Read.All– list team membersChannel.ReadBasic.All– list and read channelsChannel.Create– create channelsChannelSettings.ReadWrite.All– update channel propertiesChannelMessage.Read.All– read channel messagesTeamsTab.Read.All– list a channel's tabsTeamsAppInstallation.ReadForUser– list the user's installed Teams apps
Policy examples
Rules are evaluated top to bottom and the first match wins. Allow rules on their own restrict nothing, your org starts with a seeded Allow all rule, so any tools your allows don't cover still fall through to it. A restrictive recipe needs a catch-all deny scoped to this resource, ordered below the allows. New rules are inserted at the top of the list, so create them in reverse order or drag them into place. See Policies.
- Read-only access. Allow
list_*,get_*, andfind_*, then deny*below them. - Block sending and replies. Deny
send_*,reply_*, andforward_*above any allow rules. - Block destructive operations. Deny
delete_*,cancel_*,move_*, andupdate_*. - Allow mail triage but block calendar changes. Allow
*message*,get_*, andlist_*, then deny*event*, then deny*(list_eventsstill reads if you allow it explicitly above the*event*deny). - Allow reading Teams meeting artifacts only. Allow
list_transcripts,get_transcript_content,list_recordings, andlist_attendance_*, then deny*. - Allow reading Teams chats and channels, block sending. Allow
list_chat*,get_chat*,list_channel*,get_channel*,list_team*,get_team*,list_joined_teams,list_my_*,list_pinned_chat_messages, then deny*. - Allow full access for a specific agent. Scope an allow rule for
*to that agent on this MCP server.
Tool patterns are case-sensitive and match exactly unless they contain *. This connector's tools are snake_case, for example list_messages.
Next steps
- Create a policy – start from the read-only pattern in Policy examples above.
- Connections – manage the Microsoft 365 accounts your users have linked.