[BUG] MS365 connector: Mail.ReadWrite not honored despite tenant-side admin consent

Status Fixed / completed
Maintainer reply None cached
Activity 3 comments · opened Jul 24, 2026 · closed Jul 24, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The Microsoft 365 connector returns a FORBIDDEN / access-denied error on any write operation against my mailbox (e.g. moving an email thread to Deleted Items), even though Mail.ReadWrite (delegated) is confirmed admin-consented on the tenant side. Read operations (search, read mail) work correctly — only writes fail. Disconnecting and reconnecting the connector to force a fresh OAuth token did not change the result.

What Should Happen?

Since Mail.ReadWrite is admin-consented in our Entra tenant, write operations (move/trash/delete on messages) should succeed the same way read operations already do.

Error Messages/Logs

FORBIDDEN: Graph denied access; this tool requires the 'Mail.ReadWrite' delegated permission. The hosted OBO path requests '.default', so 'Mail.ReadWrite' may not be admin-consented on the confidential client app registration (see docs/entra-auth.md, Step 1 > API permissions), or the signed-in user lacks permission to the target resource. caused by: FORBIDDEN: Graph API Error: Access is denied. Check credentials and try again.

Debug context:
- Tenant ID: ba15b0ef-208d-4d6a-ada1-0460fbc6ca4a
- Client ID: api://07c030f6-5743-41b7-ba00-0a6e85f37c17
- User: laurie@phnxdevelopment.com

Steps to Reproduce

  1. Connect the Microsoft 365 connector in Claude to a business M365/Exchange account.
  2. In Entra ID, confirm Mail.ReadWrite (delegated) shows as admin-consented for the connector's enterprise app ("Claude for Office" in our tenant — also found "M365 MCP client for Claude" and "M365 MCP server for Claude" as related enterprise apps).
  3. Ask Claude to perform any mailbox write action (e.g. move a message/thread to Deleted Items).
  4. Observe the FORBIDDEN error above — read actions on the same mailbox succeed normally.
  5. Disconnect and reconnect the connector (forcing a new token) and retry step 3 — error is identical.

Claude Model

Sonnet (default)

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

Claude 1.24012.1 (0adcae) 2026-07-21T20:59:53.000Z

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Environment: Hosted Claude environment (accessed via connector-enabled Claude app) — no local claude CLI/version file accessible from the session to confirm an exact version number.

Additional context: The error message references "the confidential client app registration" and internal docs (docs/entra-auth.md), which suggests the actual Graph API call is made via a separate backend/OBO (on-behalf-of) app registration on Anthropic's side — distinct from the tenant-visible enterprise applications we found and checked in Entra ("Claude for Office", "M365 MCP client for Claude", "M365 MCP server for Claude"). If that's correct, tenant-side admin consent alone can't resolve this — it would need a corresponding admin-consent or configuration step on that backend confidential client, which isn't visible or actionable from our Entra admin console.

We also tried granting admin consent directly on the "Claude for Office" enterprise app via its Permissions page — this appeared to reset its permission list down to just the baseline User.Read scope rather than adding Mail.ReadWrite, suggesting Mail.ReadWrite may have been granted through a different (dynamic/incremental) consent path not reflected in that app's static permission manifest. Worth flagging in case that's a separate, related UI/behavior issue.

View original on GitHub ↗

3 Comments

lagitane · 2 months ago

Update: confirmed this isn't mail-specific.

Tried accepting a calendar invite (Outlook connector's respond-to-event action) and got the identical FORBIDDEN error, this time for Calendars.ReadWrite instead of Mail.ReadWrite:

FORBIDDEN: Graph denied access; this tool requires the 'Calendars.ReadWrite' delegated permission. The hosted OBO path requests '.default', so 'Calendars.ReadWrite' may not be admin-consented on the confidential client app registration (see docs/entra-auth.md, Step 1 > API permissions), or the signed-in user lacks permission to the target resource. caused by: FORBIDDEN: Graph API Error: Access is denied. Check credentials and try again.

Same tenant ID, same client ID, same failure shape — just a different scope. Calendar reads work fine (search/list events succeeds), same pattern as mail (reads fine, writes blocked). This points more strongly at a systemic gap in the confidential client's own app registration — it looks like it may be missing write scopes broadly, not just Mail.ReadWrite specifically.

Debug context:

  • Tenant ID: ba15b0ef-208d-4d6a-ada1-0460fbc6ca4a
  • Client ID: api://07c030f6-5743-41b7-ba00-0a6e85f37c17
  • User: laurie@phnxdevelopment.com
lagitane · 2 months ago

Resolved — posting the fix in case anyone else hits this.

The app I was staring at in Entra ("Claude for Office") was a red herring — its Application ID didn't match the client ID in the error at all. The actual apps are documented at https://support.claude.com/en/articles/12542951-set-up-the-microsoft-365-connector:

  • M365 MCP Client for Claude — 08ad6f98-a4f8-4635-bb8d-f1a3044760f0
  • M365 MCP Server for Claude — 07c030f6-5743-41b7-ba00-0a6e85f37c17

Reconnecting the MS365 connector through Claude's own Customize > Connectors UI did NOT surface an org-wide admin-consent checkbox for us, even though the docs describe one.

What actually worked: visiting the admin-consent URL directly for each app, signed in as tenant admin:
https://login.microsoftonline.com/{tenantId}/adminconsent?client_id={appId}

Confirmed both Mail.ReadWrite and Calendars.ReadWrite work now — tested moving messages to Deleted Items and creating a calendar event, both succeeded. Might be worth the Claude connector UI surfacing that admin-consent URL directly (or the "grant org-wide access" checkbox actually appearing) for tenants where the in-app flow doesn't do it automatically, so the next person doesn't have to go spelunking in Entra to find it.

github-actions[bot] · 25 days ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.