Guides · Setup

How to Connect Microsoft 365 Mail to AI Agents with Outloop

Last updated:

In short

There are two ways to connect Microsoft 365 mail to Outloop: unattended app access, which uses a certificate and no user sign-in, and delegated Outlook, which uses a person's Microsoft login.

For autonomous AI workers, use Microsoft 365 Mail — Unattended App Access. Your administrator authorizes one mailbox once, and Outloop mints its own short-lived Microsoft tokens from then on. There is no sign-in to expire and no refresh token to babysit. Delegated Outlook remains available when a user-bound login is specifically required.

Summarize this setup guide with AI ChatGPTClaudePerplexity

Two ways to connect Microsoft mail

Outloop exists to take the human out of routine agent operation. That single idea decides which of these two paths you should pick.

1. Microsoft 365 Mail — Unattended App Access Recommended · Verified

A certificate-based application, authorized by your Microsoft 365 administrator for exactly one mailbox. No user signs in. Nothing expires on a ninety-day timer. Outloop obtains its own Microsoft access tokens and renews them itself. This is the path we recommend for anything an agent runs on its own, and it is the path this guide walks end to end.

2. Delegated Outlook Mail Alternative · Not runtime-verified

The classic Microsoft sign-in: a person authenticates in a browser and Outloop holds the resulting user-bound credential. Choose it only when you specifically need the agent to act as a particular signed-in person. It carries the lifecycle costs the first path removes.

Outloop service picker filtered to Microsoft, showing Microsoft 365 Mail unattended app access and Microsoft Outlook Mail as two separate connectors.
Outloop lists both Microsoft mail connectors. The unattended one is the recommended path for autonomous agents.

The comparison that should decide it

Unattended App Access (recommended) Delegated Outlook Mail (alternative)
Routine login required None, ever A person signs in, and again whenever the credential lapses
Human dependency None after the one-time admin setup Tied to one person's account, password and MFA
Authentication type Certificate-based application credentials (OAuth client credentials) Delegated user OAuth with a rotating refresh token
Mailbox scope One mailbox, pinned by Outloop and scoped in Exchange Whatever the signed-in user can reach, plus Outloop's pin
Best use case Autonomous AI workers; shared info@ / support@ / leads@ desks Acting as a specific named person's mailbox
Runtime verification status Live verified through Outloop Real certificate proof, 2026-08-30 Not independently runtime-verified Supported and shipped; no runtime proof has been run
Honesty note. These are two separate connectors with separate credentials and separate evidence. The proof that verifies unattended app access says nothing about the delegated connector, and this page does not claim otherwise. They can sit side by side on the same workspace while you change over.

Everything from here to “When delegated Outlook is the right choice” is the recommended path.

What unattended access gives you

Outloop already connected to Microsoft 365 Outlook by signing a person in. That works, but the connection belongs to a person: Microsoft rotates the sign-in behind the scenes, it lapses after about ninety days of quiet, and a password change or a new Conditional Access policy ends it. Each time, an agent stops mid-task and somebody has to go and sign in again. For an assistant meant to run overnight, that is the wrong shape.

Application permissions remove the whole class. Microsoft's own documentation is explicit: “refresh tokens will never be granted with this flow.” There is nothing to expire from inactivity, nothing a password change revokes, and no MFA or Conditional Access re-prompt.

Concretely, on one named mailbox:

What you need

The union trap. Microsoft treats Entra consent and Exchange RBAC as a union. If you grant this app org-wide Mail.Read / Mail.ReadWrite / Mail.Send in Entra and scope it to one mailbox in Exchange, you have scoped nothing. Microsoft states it directly: “the union of an unscoped Mail.Read grant from Microsoft Entra and a resource-scoped Mail.Read grant in Application RBAC results in no effective resource scoping.” Do the Exchange RBAC assignment and grant no org-wide Mail.* consent in Entra.

1. Open App registrations in Microsoft Entra

Entra admin centre → Identity → Applications → App registrations → + New registration.

Microsoft Entra admin center App registrations page with the New registration button.
Start in Entra under App registrations. Everything on the Microsoft side begins with New registration.

2. Register it as single tenant, with no redirect URI

Name it something recognisable, for example Outloop mailbox agent. Under supported account types choose Accounts in this organizational directory only (single tenant). Leave the redirect URI empty — this application never signs a user in, so it needs no reply URL and no platform.

Microsoft Entra Register an application form with Single tenant only selected and the Redirect URI left blank.
Choose Single tenant only and leave Redirect URI empty — this application never signs a user in.

3. Copy the client ID and tenant ID

After registering, the Overview blade carries the two values Outloop needs: Application (client) ID and Directory (tenant) ID. It also confirms what you are building — client credentials showing 1 certificate, 0 secret, and supported account types My organization only.

Microsoft Entra app registration Overview showing Application client ID, Object ID and Directory tenant ID, with client credentials listed as one certificate and zero secrets.
The Overview blade carries the two values Outloop needs, and confirms client credentials as one certificate and zero secrets.
Close-up of the Microsoft Entra app Overview essentials panel highlighting where the client ID and tenant ID appear.
These are the two values to copy into Outloop — Application (client) ID and Directory (tenant) ID.

4. Choose certificate authentication

Open Certificates & secrets. Use the Certificates tab, not Client secrets.

Why certificate over secret: Entra caps app client secrets at 24 months and the portal default is far shorter; a growing number of tenants block secret-based app authentication outright; and a secret is a bearer credential — anyone who obtains it can use it. A certificate's private key only signs a short-lived assertion. It is never transmitted to Microsoft, and in Outloop it never leaves your Mac.

Microsoft Entra Certificates and secrets blade showing one certificate uploaded, zero client secrets, and its start and expiry dates.
Use the Certificates tab, not Client secrets. A certificate lasts far longer and its private key is never transmitted.

If you need a self-signed pair, this produces one valid for two years:

openssl req -x509 -newkey rsa:2048 -keyout outloop-m365.key -out outloop-m365.cer \
  -days 730 -nodes -subj "/CN=Outloop mailbox agent"
Passphrase-protected keys are not accepted. Outloop has nowhere to hold a passphrase. The -nodes flag produces an unencrypted key. Keep it somewhere safe and delete your copy once Outloop has stored it in the Mac Keychain.

5. Upload the public certificate

Upload certificate accepts .cer, .pem or .crt — the public half only. Your private key stays with you.

Microsoft Entra Upload certificate panel showing the accepted public key file types cer, pem and crt.
Upload only the public certificate. Client secrets stays empty — the private key never leaves your Mac.

Leave the Client secrets tab empty. If both a certificate and a secret are present, Outloop refuses the credential as ambiguous rather than guessing which one you meant.

6. Find the app under Enterprise applications

Exchange does not use the ID from App registrations. Open Enterprise applications → All applications and find the same app there; this list carries the Object ID that New-ServicePrincipal needs.

Microsoft Entra Enterprise applications list showing the registered application with its Object ID and Application ID columns.
Find the same app under Enterprise applications. This list carries the Object ID that New-ServicePrincipal needs.
Microsoft Entra Enterprise application Properties blade showing the Application ID and Object ID fields used by New-ServicePrincipal.
New-ServicePrincipal needs the Object ID from Enterprise applications — not the one on the App registrations page. They are different values.
The two Object IDs are not the same. Microsoft's own note: “Don't use the IDs from the App Registrations page, as it shows different values.” App registrations shows the application object; Exchange needs the service principal object. Using the wrong one produces a pointer that never matches, and the failure surfaces much later as a permissions problem that is not one.

7. Point Exchange at the application

Everything from here is Exchange Online PowerShell; there is no admin-centre UI for it. You need membership of Organization Management (or a delegating assignment for the Application RBAC roles), and the Exchange Administrator role in Entra.

Install-Module ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName admin@yourtenant.onmicrosoft.com

New-ServicePrincipal -AppId <Application (client) ID> `
                     -ObjectId <Object ID from Enterprise applications> `
                     -DisplayName "Outloop mailbox agent"

8. Scope access to exactly one mailbox

New-ManagementScope -Name "Outloop AI mailbox" `
  -RecipientRestrictionFilter "PrimarySmtpAddress -eq 'shared.mailbox@yourtenant.onmicrosoft.com'"

New-ManagementRoleAssignment -App <Object ID> -Role "Application Mail.ReadWrite" `
  -CustomResourceScope "Outloop AI mailbox"

New-ManagementRoleAssignment -App <Object ID> -Role "Application Mail.Send" `
  -CustomResourceScope "Outloop AI mailbox"

Match the roles to the tier you will pick in Outloop. Application Mail.ReadWrite does not include sending — Microsoft documents that split and Outloop enforces the same one. For read-only, assign Application Mail.Read alone.

Verify it, and verify the negative case too:

Test-ServicePrincipalAuthorization -Identity "Outloop mailbox agent" `
  -Resource shared.mailbox@yourtenant.onmicrosoft.com | Format-Table

Test-ServicePrincipalAuthorization -Identity "Outloop mailbox agent" `
  -Resource someone.else@yourtenant.onmicrosoft.com | Format-Table

The approved mailbox must return InScope True; any other mailbox must return InScope False. Both halves matter — the second is what proves the scope is real.

Changes are cached. Microsoft caches app permission changes for 30 minutes to 2 hours (30 minutes for an idle app, up to 2 hours for an active one). A correct configuration can legitimately be refused for a while. Test-ServicePrincipalAuthorization bypasses that cache, which is why it is what to trust while you wait.

9. Confirm you did NOT grant org-wide consent

Back in Entra → your app → API permissions. There should be no application Mail.* permission here. If one is present, remove it. This is the union trap, and it is the single most common way a mailbox-scoped setup silently becomes tenant-wide.

Microsoft Entra API permissions blade showing only the default delegated User.Read permission and no application Mail permissions.
The union trap, avoided. No application Mail.* permission is granted here — only the default delegated User.Read.

10. Add the connector in Outloop

Outloop → API Keys Add an API key Microsoft 365 Mail (unattended app access).

Outloop add-key panel explaining that Microsoft 365 Mail unattended app access is an organization-level connection requiring an administrator.
Outloop says up front that this is an organization-level connection with no browser sign-in and no refresh token to expire.

Fill in the client ID and the tenant ID from step 3:

Outloop credential fields for Microsoft 365 Mail showing Client ID, Directory tenant ID and the optional client secret alternative.
Paste the client ID and tenant ID from the Entra Overview blade. The client secret field is the alternative to a certificate, not an addition.

Then the certificate and its private key. The private key signs locally and is never sent to Microsoft; it goes straight into the macOS Keychain over loopback and is never echoed back, never written into your project folders, never placed in the policy file, and never shown to an agent:

Outloop certificate and private key PEM input fields for the Microsoft 365 Mail unattended connector.
The certificate and its private key. The private key signs locally and is never sent to Microsoft. The example key material is redacted here.

Finally, the one mailbox this workspace may reach, and the scope tier matching the Exchange roles you assigned:

Outloop mailbox pin field and OAuth scope tier selector for the Microsoft 365 Mail connector.
The one mailbox this workspace may reach, and the scope tier matching the Exchange roles you assigned. The example address is redacted here.

11. Check the bounds

The saved connector is bounded to graph.microsoft.com, to the /v1.0/ path prefix, and to the methods Outloop allows.

Outloop bridge and runtime panel for Microsoft 365 Mail showing the pinned Microsoft Graph host, allowed methods GET POST PUT PATCH, and secret exposed false.
Bounded to graph.microsoft.com with the methods Outloop allows. There is no DELETE — deletion is refused structurally, not by a switch.
Outloop workspace access row for the Microsoft 365 Mail connector showing bridge and runtime settings.
The connector's per-workspace row. Access is bounded to this workspace and every request is audited.

Note what is not there: no DELETE. Deletion is refused structurally on this connector, not by a switch you could turn on. There is no destructive-actions toggle to find.

The first safe proof

The first call is always a read, against the pinned mailbox's inbox folder — a route Mail.Read covers. Runtime access turns on only if it succeeds.

GET /v1.0/users/{pinned-mailbox}/mailFolders/inbox

decision:         allow
http_status:      200
token_source:     mint
secret_exposed:   false
runtime_verified: yes

The isolation property is proven by the negative case, which costs nothing to run:

GET /v1.0/users/someone.else@yourtenant.onmicrosoft.com/mailFolders/inbox

decision:        deny
code:            RESOURCE_ID_NOT_ALLOWED
http_status:     null          <- no Microsoft call was made at all
secret_exposed:  false

http_status: null is the point. The request was refused before the credential was read and before Microsoft was contacted.

Once the proof passes, the key row reads Runtime verified · API bridge , and the certificate's own expiry appears as Valid until 2028-08-28 (your date will differ) — Outloop reads it off the certificate rather than asking you to type it.

Full API capabilities and write actions

What is verified vs what is not claimed

Tested here: everything in the verified list above, on the installed app against a live Microsoft 365 tenant with a certificate credential, on 2026-08-30. Twenty-one audit lines, zero secret exposures, leak scan clean.

Not claimed:

When delegated Outlook is the right choice

Delegated Outlook Mail is worth choosing in one situation: when the agent must act as a specific signed-in person — replying from their address, working their drafts and folders — rather than from a shared mailbox.

Selecting it in Outloop shows a visibly different setup: instead of a certificate, it offers Connect in your browser, because the credential is obtained by a person signing in.

Outloop add-key panel with the delegated Microsoft Outlook Mail connector selected, showing a Connect in your browser button instead of certificate fields.
Selecting the delegated connector shows a visibly different setup — Connect in your browser, because a person signs in.

What you take on by choosing it:

Status, stated plainly. The delegated connector is shipped and supported, and it is not independently runtime-verified. It carries no runtime proof of its own, and the certificate proof on this page does not transfer to it. Treat it as the alternative, not the default.

The two connectors are separate service ids with separate credentials, grants and proof state, so a workspace may hold both at once while you change over. Outloop never migrates one to the other.

Microsoft Graph through Outloop vs a Microsoft 365 MCP server

For this workspace, Microsoft Graph through Outloop is the only Microsoft mail path that is live and verified right now.
Area Graph through OutloopMicrosoft 365 MCP (community)
Provenance This connector, shipped in Outloop 1.25.0. No official Microsoft first-party Graph mail MCP. The prominent option is a third-party MIT project.
Authentication Certificate-based app-only. No user. Device-code interactive sign-in by default, with refresh tokens cached locally.
Survives unattended Proven: 8h42m re-mint with nobody present. A user sign-in that can lapse — the class this connector exists to remove.
Mailbox boundary Enforced pre-credential by Outloop's pin, plus Exchange RBAC. Client-side flags and parameters.
Surface Mail routes only; non-mail Graph refused. 300+ tools across most of Graph.
Audit Every request audited, response redacted, secret_exposed:false. Not applicable here.
Status here Live verified through Outloop Real certificate proof, 2026-08-30. Not connected here Not verified in this guide.
Honesty note. This comparison is intentionally conservative. A Microsoft 365 MCP server can expose a far broader toolset than this connector, and breadth is a real advantage for exploratory work. It is not connected in this workspace, so nothing in its column is marked verified. What is live and verified here is the Outloop API-bridge path, and its distinguishing property is not breadth — it is that it keeps working when nobody is at the keyboard. The general mechanism is covered in credential broker vs MCP authentication.

When something is refused

Certificate expiry and rotation

Outloop reads the certificate's own notAfter date, shows it on the key row, and warns well before it lapses. Where no reliable date exists, Outloop shows nothing rather than guessing.

To rotate: create a new certificate, upload it to the same Entra app (both can coexist), then use Rotate key on the Outloop key row to paste the new pair. Remove the old certificate from Entra afterwards. The tenant, client ID, mailbox pin and Exchange RBAC assignment are untouched.

Official documentation

Outloop is available with guided onboarding for agency teams. Outloop is an independent tool and is not affiliated with or endorsed by Microsoft. See the security model for how credentials are stored and used, or the other connector setup guides.

Summarize this setup guide with AI ChatGPTClaudePerplexity

Let an agent work the mailbox while you sleep.

One mailbox, one certificate, no sign-in to expire.

Frequently Asked Questions

Microsoft 365 Mail + Outloop — FAQ