
Your agent needs to work with Microsoft 365. It needs to read a user's Outlook mail, put an event on their calendar, pull a figure out of an Excel workbook, or drop a message in Teams. For Slack or Notion, the "MCP vs API" question has a clean answer, because each ships one hosted MCP server. Microsoft 365 does not. The official MCP story is split across two products with different scopes, licenses, and release states, and the API underneath both is a single graph. Here is how to pick.
Before comparing them, it helps to be precise about the two objects, because "Microsoft 365 MCP" is not one thing the way most agent builders expect.
Microsoft exposes two official MCP paths, and they solve different problems. The first is the Microsoft MCP Server for Enterprise at https://mcp.svc.cloud.microsoft/enterprise. It is in public preview, it is read-only, and it targets Microsoft Entra identity and directory scenarios: users, groups, applications, devices, and administrative reporting. It ships three tools that translate natural language into read-only Microsoft Graph calls, honoring the signed-in user's roles and granted scopes. It is available in the global cloud only, and it is rate-limited to 100 calls per minute per user.
The second path is Agent 365, which reached general availability on May 1, 2026. Its tooling servers map to familiar surfaces (Outlook Mail, Outlook Calendar, Copilot Search, SharePoint and OneDrive) and do support create, update, and delete on behalf of the signed-in user. The tradeoff is where they run and what they cost. These servers are exposed per tenant, they operate inside Microsoft's agent hosting under centralized governance, and using them requires Agent 365 licensing plus Microsoft 365 Copilot licensing for the users of the agent. They are not a general-purpose endpoint you point an arbitrary production agent at.
The Microsoft Graph API is the single unified REST interface for Microsoft 365 data. Every request for every service goes to one endpoint, https://graph.microsoft.com, and there are two versions: v1.0, which is generally available and where changes are additive and non-breaking, and beta, which is preview and can break without notice. See the Microsoft Graph overview for the full surface. Auth runs on Microsoft Entra ID with OAuth 2.0, supporting both delegated access (on behalf of a signed-in user) and application access (the app's own identity). This is the mature path, and it is the one every capability the MCP servers lack is reachable through.
The MCP paths cover a real but narrow slice of Microsoft 365. The Graph API covers all of it. The distinction matters most for write-heavy, headless, or event-driven agents.
The table maps the actions most agents actually need against the two paths. The MCP column reflects both official servers together: the Enterprise MCP for identity reads, and Agent 365 for licensed productivity actions.
The missing rows are not tools waiting to ship next month. The Enterprise MCP is read-only by design; write access to identity is deliberately out of scope for a preview identity server. Agent 365's productivity coverage is real, but it is gated behind licensing and Microsoft's hosting model, which is a commercial and architectural boundary rather than a feature gap. Excel cell edits, Teams messaging at scale, OneNote, and change notifications sit in the Graph API because that is where the complete platform surface has always lived. If your agent's job touches any of those, the MCP question is already answered.
Auth is where the two objects separate most sharply, and it is the axis that decides most production Microsoft 365 agents.
Both official MCP paths run delegated, acting on behalf of a signed-in user, and both enforce that user's existing Microsoft 365 permissions. The Enterprise MCP honors the user's roles and the scopes granted to the MCP client, and it stays read-only. Agent 365's tooling servers execute writes as the signed-in user, but only inside Microsoft's agent hosting and only for users carrying the required licenses. There is no application-only option on either MCP path; a background job with no user in the loop cannot use them.
The Graph API supports both models. In delegated access, the app uses the Authorization Code flow and acts on behalf of the signed-in user; the effective permissions are the intersection of the app's scopes and the user's own privileges, which means the application cannot reach anything the user could not reach. In application access, the app uses the Client Credentials flow with its own identity and no user present, which is the right pattern for daemons, scheduled syncs, and background automation; application permissions are tenant-wide and must be consented by a Global Administrator or Privileged Role Administrator. For chained calls, the On-Behalf-Of flow (RFC 8693) exchanges a delegated token for a downstream Graph token. To understand how these on-behalf-of patterns work in agentic contexts, see our deep dive on delegated agent access.
For a multi-tenant B2B agent, correct attribution and least privilege require delegated, per-user identity: what the user cannot do, the agent cannot do. That is true whether you use the MCP paths or the Graph API delegated flow. It also means one token per user, per tenant, each with its own lifecycle. The application-only route trades that for a single tenant-wide credential, which removes the N-token problem but concentrates the blast radius into one over-privileged secret. Neither path stores, rotates, or revokes any of this for you. For a detailed look at how to handle token refresh for AI agents, see our production guide.
The two paths hand you different operational surfaces. The MCP paths trade control for a managed contract; the Graph API trades a larger maintenance footprint for stability and completeness.
Microsoft owns the servers, the tool schemas, and the request normalization. For the Enterprise MCP, remember it is preview: behavior can change before release, and it is capped at 100 calls per minute per user on top of standard Graph throttling. For Agent 365, you inherit Microsoft's governance model and its licensing prerequisites, which is a feature for regulated tenants and a dependency for everyone else. What you still own on either path is the same thing you always own: per-user token storage, refresh, and revocation, plus tenant isolation.
You own the full stack: endpoint selection, request construction, pagination, error handling, retries, throttling backoff, and the complete token lifecycle. You also get the levers that make Graph efficient, including OData shaping with $select, $filter, and $top to cut payloads and reduce throttling. The maintenance surface is larger, and the operational model is more predictable because you decide when to move.
MCP tool schemas are Microsoft's to change, and the Enterprise MCP in particular carries the usual preview caveat. The Graph API is versioned explicitly: v1.0 is generally available with additive, non-breaking changes, while beta is preview and unsafe for production. For a deterministic pipeline where an unexpected schema change is an incident, pinning to v1.0 is the more stable dependency.
The decision comes down to who is present, what you are allowed to license, and how much of the suite you need to touch.
Scalekit's Microsoft 365 connector takes the Graph API path and makes it production-safe for multi-user agents. It exposes 313 prebuilt, LLM-ready tools across Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams, all backed by Microsoft Graph, all with per-user delegated OAuth. You do not write tool schemas, build an Entra OAuth flow, or manage tokens. There is a unified Microsoft 365 connector, and focused per-app connectors for Excel, Teams, Word, OneDrive, OneNote, Outlook, and SharePoint; browse them from the connector catalog.
Setup is a one-time step per environment. In the Scalekit dashboard, create a Microsoft 365 connection and copy its redirect URI. In Microsoft Entra ID, register a multitenant app, paste that redirect URI, and generate a client secret. Back in Scalekit, add the client ID, client secret, and the Graph scopes your agent needs, for example Calendars.ReadWrite, Mail.Send, Files.ReadWrite, and offline_access. Install the SDK and set your credentials.
The important idea comes before any tool executes. The agent does not load a flat catalog of 313 Microsoft 365 tools. It loads only the tools the current user's connected account is authorized to call. That is the difference between a per-user agent and a shared-credential agent, and it is what keeps tool selection accurate. The identifier represents the current person in your own system; resolve it from your authenticated session, never from the client. Understanding how tool calling auth changes from single-tenant to multi-tenant is key to getting this right.
The connection name inside the filter must match the name you created in the dashboard, character for character; a mismatch returns an empty tool list with no error. Scalekit returns protobuf objects, which is why MessageToDict converts them into the native Anthropic tool format.
This is the standard Claude tool-use loop. Claude decides which tool to call, your code runs it through execute_tool with the user's identifier, and Scalekit makes the Graph call using that user's stored token. The credential never enters the agent runtime.
For any Graph endpoint that does not map to a named tool, the same connected account works as a proxy: actions.request(connection_name="microsoft365", identifier=identifier, path="/v1.0/me/messages", method="GET") calls Graph directly as that user. You get the full v1.0 surface without leaving the per-user model. Full details are in the Python SDK reference and the AgentKit examples.
A shared credential is a single-user solution; it does not survive a second user. Handing the model all 313 tools is both an accuracy problem and a cost problem: LLMs pick the wrong tool when the surface is too large, and every tool in context burns tokens before the agent does any work. Scoping to the handful of tools the current user authorized fixes both at once. The fix is not better prompting. It is surface reduction. This is closely related to who holds the token and how credential ownership works across agent tool-calling patterns.
Most real Microsoft 365 agents are not single-tool. A meeting-prep agent reads Outlook, checks the calendar, and pulls a file from OneDrive; a provisioning agent touches the directory and Teams. Two Scalekit capabilities matter once you cross from one user to many.
A standard MCP server exposes every tool it has. A summarizer that only needs to read mail does not need send, delete, and mailbox-settings tools in its context. Scalekit's Virtual MCP Servers enforce least privilege at the tool level: the agent sees only the tools you explicitly allow, not everything the connector exposes. One server definition serves all users; before each run, a short-lived session token is minted scoped to that user's connected accounts. You configure the connection and the tool allowlist once per agent role, and there is no MCP server to deploy, host, or maintain. The endpoint is static; the identity is per-user.
When an agent acts as a user across Outlook, Teams, and OneDrive, "who did what, as whom" becomes a compliance question, not a debugging convenience. Scalekit records every downstream tool call with the resolving identity, so agent tool observability shows the human each Graph action ran on behalf of, not a shared service account. That is the audit trail an enterprise security review asks for, and it is the same trail whether the action was a calendar write or a file share.
The auth divergence between MCP and Graph is real, but it obscures the problem underneath both choices. Every path produces a credential per user, and none of them manages that credential's life.
Storage: delegated tokens have to live somewhere outside the agent runtime, encrypted at rest and isolated per tenant. Rotation: Graph access tokens are short-lived, roughly an hour, and need proactive refresh rather than reactive 401 handling. Revocation: when an employee leaves or a customer churns, you need to surface and invalidate every active token tied to that identity. In a multi-tenant B2B product that is N credentials, one per user per tenant, each with its own lifecycle. The path you chose changes the token type; the infrastructure required does not. Secure token management for AI agents at scale walks through how to build this infrastructure correctly.
Scalekit's Microsoft 365 connector handles the Entra OAuth flow, per-user token storage, and automatic refresh, so the MCP versus API decision does not change your auth infrastructure. Explore the value proposition on the Microsoft 365 connector page, and see it inside working patterns like the email-to-calendar agent, the meeting prep agent, and the new hire provisioning agent.
If your agent is interactive, your users are licensed for Agent 365 and Microsoft 365 Copilot, and the work is conversational reads or the productivity actions those servers expose, the MCP paths are a legitimate route with Microsoft owning the governance. For read-only Entra reporting specifically, the Enterprise MCP is the shortest path.
If your agent is headless, multi-tenant, or needs Excel edits, Teams messaging, OneNote, change notifications, or national-cloud coverage, build against the Microsoft Graph API directly. It is the only path that reaches the full suite without a licensing and hosting dependency. The single question that decides it: does your agent need to act across many customer tenants, some of them unlicensed for Copilot, and touch more than the MCP servers expose? If yes, Graph. Either way, the per-user credential problem is identical, and that is the part that needs production-grade infrastructure.
Browse the Scalekit Microsoft 365 connector in the docs, start free from the AgentKit page, and check pricing when you are ready to scale.
Building a Microsoft 365 agent and want another set of eyes on the auth model? Join the Scalekit Slack community, or use the Talk to us page for immediate help.