Announcing CIMD support for MCP Client registration
Learn more

SharePoint MCP vs SharePoint API for AI Agents (2026)

TL;DR

  • Microsoft's official SharePoint MCP server is Work IQ SharePoint (mcp_SharePointRemoteServer), and it ships 35 tools covering sites, lists, columns, list items, document libraries, files, sharing, and sensitivity labels. File operations are capped at 5 MB, search and folder enumeration return the top 20 results, and there are no webhook, delta query, versioning, or check-out tools.
  • Work IQ SharePoint is a preview feature that requires a Microsoft 365 Copilot license plus a Microsoft Entra app registration with the matching Work IQ permission consented. There is no personal-account path and no static credential path. A background agent with no user session cannot complete that flow.
  • The Graph API accepts delegated OAuth and app-only client credentials, supports change notification subscriptions, delta cursors, resumable upload sessions, file versioning, and OData filtering with real pagination. That is the surface headless and high-volume SharePoint agents need.
  • Both paths enforce the authorizing user's SharePoint permissions, which is architecturally correct and also means N OAuth tokens per tenant. Neither path stores, refreshes, or revokes those tokens for you.
  • Scalekit's SharePoint connector ships 39 prebuilt Graph-backed tools with per-user token vaulting and automatic refresh, and Virtual MCP servers let you expose a scoped subset of them over a single MCP endpoint, so the MCP vs API decision does not change your auth infrastructure.

Your agent needs to read and write SharePoint: pull the SOW from a project site, update a list item when a deal closes, drop a generated report into a document library. Microsoft now ships both a first-party MCP server and the Microsoft Graph API surface that has backed SharePoint integrations for years. They are not two views of the same thing. One is a preview feature gated behind a Copilot license with a 5 MB file ceiling; the other is a versioned REST surface with webhooks, delta queries, and resumable uploads. Here's how to pick.

What SharePoint MCP and the SharePoint API actually are

These are two Microsoft-built surfaces over the same underlying data, released roughly a decade apart, with very different design intents. The MCP server is built for LLM clients inside a governed tenant. The API is built for applications. Establishing what each one actually is up front removes most of the confusion in the comparison that follows.

Work IQ SharePoint, the official MCP server

Microsoft's first-party SharePoint MCP server ships under Agent 365 as part of the Work IQ tool family. The server ID is mcp_SharePointRemoteServer and the tenant-scoped endpoint is https://agent365.svc.cloud.microsoft/agents/tenants/{tenantId}/servers/mcp_SharePointRemoteServer. It is built directly on Graph and exposes 35 tools spanning site discovery, document libraries, files and folders, lists, columns, list items, sharing invitations, and sensitivity labels.

It is a preview feature. Microsoft states plainly that it might change preview tool names and parameters, and advises against hard-coded dependencies. Access requires a Microsoft 365 Copilot license, and clients reach it through Copilot Studio, Microsoft Foundry, or a coding agent configured against an Entra app registration holding the matching Work IQ SharePoint permission.

Official docs: Work IQ SharePoint reference on Microsoft Learn and the Work IQ MCP overview.

The SharePoint API surface on Microsoft Graph

Graph models SharePoint as site, list, listItem, drive, and driveItem resources under https://graph.microsoft.com/v1.0/sites/.... Every capability the MCP server exposes is reachable here, plus change notification subscriptions, delta cursors for incremental sync, file version history, check-in and check-out, content types, recycle bin restore, Microsoft Search with KQL, and resumable upload sessions.

Auth is standard Microsoft Entra OAuth 2.0. Delegated flows let the agent act as a specific user with that user's site and library permissions intact. Client credentials give you app-only access for background work with no user in the loop. One honest limitation worth naming: Graph v1.0 provides read-only support for site resources, so creating new site collections still needs the beta endpoint or a different API.

Official docs: SharePoint API in Microsoft Graph and the SharePoint sites and content overview.

Comparing them where it matters for agents

Four dimensions decide this: what the agent can call, what auth model each path forces, what you still own once it is running, and which scenarios each one actually fits. Capability first, because for SharePoint the gap is unusually concrete.

What your agent can actually do

Work IQ SharePoint covers the interactive document and list surface well. It handles the tasks that make up most of what a knowledge worker asks an agent to do inside SharePoint: find a site, browse a library, read a file, update a list item, share a document. The gaps show up the moment an agent needs to watch for changes, move real files, or page through more than a screenful of results.

Capability
Work IQ SharePoint MCP
Microsoft Graph SharePoint API
Find and resolve sites
Yes (findSite, getSiteByPath)
Yes
List document libraries and folder contents
Yes, top 20 items
Yes, with $top and paging
Read files
Yes, 5 MB ceiling
Yes, no practical read ceiling
Create and upload files
Yes, 5 MB ceiling
Yes, 250 MB single PUT, resumable session above that
List, create, update, delete list items
Yes
Yes
Manage columns and list schema
Yes
Yes
Apply sensitivity labels
Yes (setSensitivityLabelOnFile)
Yes, via Graph directly
Search content
Yes, top 20 by default
Yes, Microsoft Search with KQL, up to 200 per page
OData filter, orderby, skip, pagination
No documented parameters
Yes
Change notification webhooks
No
Yes
Delta query for incremental sync
No
Yes
File version history
No
Yes
Check-out and check-in
No
Yes
Content types
No
Yes
Recycle bin restore
No
Yes
Create site collections
No
Beta endpoint only

The three gaps that decide most builds

The 5 MB ceiling. Microsoft caps Work IQ SharePoint file operations at 5 MB for both upload and download. That is not a soft guideline; it is stated in the server description and repeated on every file tool. A contract PDF with embedded scans, a quarterly deck, a CAD export, or most video assets are simply out of reach. Graph handles 250 MB in a single PUT and anything larger through createUploadSession, uploading in sequential byte ranges under 60 MiB each.

No event surface. Nothing in the 35-tool list subscribes to change notifications or returns a delta cursor. If your agent needs to react when a document lands in a library or a list item flips status, the MCP path cannot express that. Graph gives you both mechanisms: subscriptions for push, delta for a resumable incremental sweep that catches whatever push dropped.

The top-20 wall. getFolderChildren returns the top 20 items. findSite returns the top 20 sites. Search returns the top 20 by default. The Learn reference documents no pagination parameters on these tools. An agent auditing a 4,000-document library cannot get there from here. Graph exposes $top, $skip, $filter, $orderby, and cursor paging on the same resources.

The auth path each one puts you on

Work IQ SharePoint runs on Microsoft Entra OAuth against a registered client application. An administrator or an authorized user registers an app in Entra, adds the Work IQ SharePoint permission, consents to it, and configures a redirect URI. Each MCP server corresponds to a permission on the Agent 365 application, and admins can allow or block servers tenant-wide from the Microsoft 365 admin center.

There is no API key path and no static credential path. Every connecting user completes a browser-based consent flow, and access is subject to workspace governance by default. For enterprise deployments that governance is a feature. For an agent that needs to spin up without an admin in the loop, it is a dependency you plan around.

The Graph API supports the same delegated Authorization Code flow plus Client Credentials for app-only access. Delegated tokens are the right model when the agent must act as a specific person and inherit their SharePoint permissions. App-only tokens are the right model for tenant-wide background work. Both are available; the MCP path gives you exactly one of them. To understand the broader tradeoffs between OAuth vs API Keys for AI agents, it's worth reviewing why static credentials break down in production systems.

The Copilot license and the headless gap

Microsoft is explicit: you must have a Microsoft 365 Copilot license to use Work IQ MCP servers. That is a per-seat commercial dependency sitting underneath a technical integration decision, and it does not apply to Graph at all. If you are shipping a B2B product where each customer connects their own tenant, you are now asserting that every customer has bought Copilot.

The headless gap compounds it. A nightly document classifier, a scheduled compliance sweep, an event-driven pipeline that files incoming attachments into the right library: none of these have a browser or a user present at execution time. Graph's client credentials flow was built for exactly this. The MCP path was not. Understanding how tool calling auth changes when you move from single-tenant to multi-tenant is essential context here.

What you own in production

On the MCP path, Microsoft owns hosting, scaling, tool schemas, and permission enforcement. Observability is genuinely strong here: admins can query trace logs of agent tool calls in the Microsoft Defender portal through Advanced Hunting, including which tools ran, what parameters were passed, and what came back. If your buyer is a CISO who already lives in Defender, that is a real advantage.

What you still own on the MCP path: per-user token storage, refresh, revocation on disconnect, tenant isolation, and the Entra app registration lifecycle. On the direct API path you own all of that plus endpoint selection, request construction, retry logic, pagination, subscription renewal, and adapter code per resource type. More surface area, more control.

Rate limits and schema drift

Both paths consume the same budget. SharePoint Online throttling is enforced per client application per tenant on a resource-unit model scaled by tenant license count, and MCP tool calls resolve to Graph calls underneath. Throttled requests return 429 or 503 with a Retry-After header, and SharePoint returns IETF RateLimit headers ahead of the limit in some conditions. Agentic workflows fire several sequential calls per user action, so budget accordingly and honor the headers.

Schema stability differs sharply. Graph is versioned: you pin v1.0, and breaking changes go through deprecation. Work IQ SharePoint is a preview whose tool names and parameters Microsoft warns may change, with the explicit instruction to avoid hard-coded dependencies. For a deterministic pipeline where an unannounced schema change is an incident, that distinction is the whole decision. This is one reason why understanding the difference between MCP and APIs matters before you commit to a path.

When to use MCP, when to use the API

Use Work IQ SharePoint MCP when:

  • Your users are inside a Copilot-licensed tenant and your agent runs interactively in Copilot Studio, Microsoft Foundry, or a coding agent where OAuth consent is natural
  • The job is find, read, and light write against sites, small documents, and lists, and the 5 MB and top-20 boundaries do not bite
  • You want Microsoft 365 admin center governance and Defender-based tool call tracing without building your own controls
  • Sensitivity label application is a first-class requirement and you want it as a single tool call

Use the Microsoft Graph SharePoint API when:

  • Your agent runs headless: scheduled document classification, overnight library sync, compliance sweeps, or attachment filing pipelines with no user present
  • Files exceed 5 MB, which for most document management workloads is the common case rather than the exception
  • The agent must react to changes through subscriptions, or resync incrementally through delta
  • You need real pagination and OData filtering across libraries and lists larger than 20 items
  • You depend on version history, check-out and check-in, content types, or recycle bin restore
  • Your customers are not uniformly Copilot-licensed, which is the default assumption for a multi-tenant B2B product

The credential problem that exists on both paths

Both paths hand you a credential per user and nothing else. The MCP OAuth flow produces a token per user. The Graph delegated flow produces a token per user. In neither case does the path give you a vault, rotation logic, tenant isolation, or a revocation flow. That infrastructure gets built separately regardless of which path you chose.

The N-credential math

Take a document intelligence agent serving 60 knowledge workers across 9 customer tenants. That is 60 access tokens to store encrypted, 60 refresh tokens to rotate before expiry, and 60 credentials to invalidate when someone leaves. Add subscription renewal on top if you are using webhooks, because Graph change notification subscriptions on SharePoint resources max out at roughly three days and must be renewed before expiry or the event stream goes quiet.

The failure mode is specific and silent. An employee's Entra account is disabled during offboarding, but a refresh token minted eight months ago is still sitting in your database. The agent does not decide to keep using it. It just does, until something returns 401 and nobody is watching for it. This is the exact scenario that secure token management for AI agents at scale is designed to prevent.

Where Scalekit fits

Scalekit's SharePoint connector resolves the per-user credential on every tool call, so every SharePoint action is attributed to the person who authorized it rather than a shared service account. Tokens live in a vault outside the agent runtime, encrypted at rest and namespaced per tenant, and never appear in prompts, logs, or LLM context. The same infrastructure works whether you build against MCP or Graph directly, which is the point: the path decision does not change what you need at the credential layer.

Building a SharePoint agent with Scalekit

Scalekit ships one SharePoint connector, and it is the Graph-backed API path with 39 prebuilt tools. There is no separate SharePoint MCP connector in the catalog, which reflects the licensing and headless constraints described above. What you get instead is the ability to expose any scoped subset of those Graph-backed tools over an MCP endpoint through Virtual MCP servers, covered further down.

Set up the connection

SharePoint is a bring-your-own-credentials connector. Create the connection in the Scalekit dashboard under AgentKit, Connections, Create Connection, then copy the redirect URI it generates. Register a multitenant application in Microsoft Entra, paste that redirect URI as a Web redirect, generate a client secret, and enter the client ID, secret, and Graph scopes back in the Scalekit connection.

Note the connection name you choose. Every connection_name in your code must match the connection name configured in the dashboard exactly. This is the single most common integration error, and it surfaces as a confusing not-found rather than an obvious misconfiguration.

pip install scalekit langchain langchain-openai

Authorize the user

The agent never sees a SharePoint token. It works with an identifier, which is any stable string that identifies the user in your system, and Scalekit resolves the credential server-side at call time.

import os from scalekit import ScalekitClient from dotenv import load_dotenv load_dotenv() scalekit_client = ScalekitClient( env_url=os.getenv("SCALEKIT_ENV_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), ) actions = scalekit_client.actions CONNECTION_NAME = "sharepoint" # must match the connection name in the Scalekit dashboard IDENTIFIER = "priya@acme.com" account = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) if account.connected_account.status != "ACTIVE": magic_link = actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, ) print("Authorize SharePoint:", magic_link.link) input("Press Enter after authorizing...")

Retrieve the tools this user is authorized to call

Before the agent runs, load its tool surface. This is not a connector catalog dump. list_scoped_tools returns the tools the current user's connected account is authorized to call, filtered further by the tool names you allow for this agent role.

tools_response = actions.tools.list_scoped_tools( identifier=IDENTIFIER, filter={ "connection_names": ["sharepoint"], "tool_names": [ "sharepoint_list_sites", "sharepoint_list_drives", "sharepoint_search", "sharepoint_list_list_items", "sharepoint_update_list_item", ], }, page_size=100, ) for tool in tools_response.tools: print(tool.name, "-", tool.description)

Why that surface is the correct one

The SharePoint connector exposes 39 tools. A contract review agent needs five. Handing the model all 39 costs roughly 200 tokens each, so about 7,800 tokens burned before the agent does any work, and it degrades selection accuracy because the model is choosing from a decision space it was never designed to handle at that scale. Scoping to five cuts the overhead by roughly 87% and shrinks the decision space to what is actually relevant.

Permissions come from the same place. sharepoint_search runs against Microsoft Search as the authorizing user, so sites Priya cannot open in a browser are equally unreachable by the agent acting for her. What the user can't do, the agent can't do. Surface reduction is the lever here. Model upgrades help; they are not the lever.

Run the agent loop with LangChain

Scalekit's LangChain adapter returns native StructuredTool objects, so there is no schema reshaping. Pass the same filters you used above. For a deeper look at how LangChain tool calling works and where it stops, that guide covers the full picture.

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage tools = actions.langchain.get_tools( identifier=IDENTIFIER, connection_names=["sharepoint"], tool_names=[ "sharepoint_list_sites", "sharepoint_list_drives", "sharepoint_search", "sharepoint_list_list_items", "sharepoint_update_list_item", ], page_size=100, ) tool_map = {t.name: t for t in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ HumanMessage( "Find every SOW document updated in the last 30 days across the project sites " "and tell me which ones are still pending approval." ) ] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tool_call in response.tool_calls: result = tool_map[tool_call["name"]].invoke(tool_call["args"]) messages.append( ToolMessage(content=str(result), tool_call_id=tool_call["id"]) )

Reach past the tool catalog with a proxied Graph call

Prebuilt tools cover the common surface. When you need something outside it, such as a delta cursor or a version history call, actions.request proxies raw Graph requests with the user's token injected server-side. Your application still never handles the credential.

# Incremental sync: only what changed since the last run response = actions.request( connection_name=CONNECTION_NAME, identifier=IDENTIFIER, path=f"/v1.0/sites/{site_id}/drive/root/delta", method="GET", query_params={"token": last_delta_token} if last_delta_token else {}, ) payload = response.json() changed_items = payload.get("value", []) next_delta_link = payload.get("@odata.deltaLink") print(f"{len(changed_items)} items changed since the last sync")

TypeScript: scoped tools with the Claude SDK

The same discovery, scope, and execution sequence in Node. listScopedTools returns JSON Schema you pass straight to the Anthropic API.

import { ScalekitClient } from '@scalekit-sdk/node'; import Anthropic from '@anthropic-ai/sdk'; import 'dotenv/config'; const scalekit = new ScalekitClient( process.env.SCALEKIT_ENV_URL!, process.env.SCALEKIT_CLIENT_ID!, process.env.SCALEKIT_CLIENT_SECRET!, ); const anthropic = new Anthropic(); const identifier = 'priya@acme.com'; const { tools } = await scalekit.tools.listScopedTools(identifier, { filter: { connectionNames: ['sharepoint'], toolNames: ['sharepoint_search', 'sharepoint_get_list_item', 'sharepoint_update_list_item'], }, pageSize: 100, }); const claudeTools = tools.map((t) => ({ name: t.name, description: t.description, input_schema: t.inputSchema, })); const messages: Anthropic.MessageParam[] = [ { role: 'user', content: 'Mark the Acme Corp SOW list item as approved and confirm the change.' }, ]; while (true) { const response = await anthropic.messages.create({ model: 'claude-sonnet-4-6', max_tokens: 1024, tools: claudeTools, messages, }); messages.push({ role: 'assistant', content: response.content }); if (response.stop_reason !== 'tool_use') { const text = response.content.find((b) => b.type === 'text'); if (text && text.type === 'text') console.log(text.text); break; } const toolResults: Anthropic.ToolResultBlockParam[] = []; for (const block of response.content) { if (block.type !== 'tool_use') continue; const result = await scalekit.actions.executeTool({ toolName: block.name, toolInput: block.input as Record<string, unknown>, identifier, }); toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(result.data), }); } messages.push({ role: 'user', content: toolResults }); }

Virtual MCP servers for multi-tool, multi-tenant SharePoint agents

If you want an MCP endpoint without the Copilot license, the Entra registration per tenant, and the 5 MB ceiling, Virtual MCP servers give you one. You declare which connections and which tools an agent role can see, and Scalekit generates a static endpoint. There is no MCP server to deploy, host, or maintain.

Define the server once per agent role

A document agent rarely touches only SharePoint. It reads the library, checks the Jira ticket, and posts to Slack. One server definition covers all three, and it is created once for the role rather than once per user.

from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping vmcp_response = scalekit_client.actions.mcp.create_config( name="contract-review-agent", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="sharepoint", tools=[ "sharepoint_search", "sharepoint_list_drives", "sharepoint_download_file", "sharepoint_list_file_versions", ], ), McpConfigConnectionToolMapping( connection_name="slack", tools=["slack_send_message"], ), ], ) config_id = vmcp_response.config.id mcp_server_url = vmcp_response.config.mcp_server_url

Note what is absent from that list. No sharepoint_delete_list, no sharepoint_recycle_item, no sharepoint_delete_role_assignment. A review agent that can permanently delete a list is an incident waiting for a bad tool selection. The agent sees only what you explicitly allow, not everything the connector exposes.

Mint a session token before each run

The endpoint is static. The identity is not. Before each run, confirm the user's connections are still live, then mint a short-lived token bound to that specific user's connected accounts.

from datetime import timedelta accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts( config_id=config_id, identifier=IDENTIFIER, include_auth_link=True, ) for account in accounts_response.connected_accounts: if account.connected_account_status != "ACTIVE": print(f"{account.connection_name} needs auth: {account.authentication_link}") token_response = scalekit_client.actions.mcp.create_session_token( mcp_config_id=config_id, identifier=IDENTIFIER, expiry=timedelta(minutes=30), ) mcp_server = { "url": mcp_server_url, "headers": {"Authorization": f"Bearer {token_response.token}"}, }

Why this matters for multi-tenant SharePoint agents

SharePoint is where cross-tenant leakage does real damage, because a document library is not a row in a table; it is contracts, board decks, and HR records. One server definition serving all users with a per-run session token means no credential sharing between users and no per-user server configuration to drift out of sync. Cross-tenant tool calling requires per-tenant authorization, and there is no shortcut.

The check before minting matters as much as the mint itself. OAuth credentials expire or get revoked between runs, and confirming status up front turns a mid-task failure into a re-auth prompt the user can act on. This is why understanding how to handle token refresh for AI agents is a production concern, not an afterthought.

Observability: auth logs for downstream tool calls

The MCP path gives you Defender-based tracing inside the tenant, which is useful to the customer's security team and invisible to you as the vendor. When your agent misbehaves for one customer, you cannot open their Defender portal.

Scalekit logs the downstream side. Every execute_tool call returns an execution_id, and each entry ties the SharePoint action back to the connected account that authorized it: which user, which connection, which tool, what came back. History is retained for 90 days and exports in a SIEM-friendly shape.

That matters because standard application logs record a user ID and a timestamp, while an agent action touches four principals at once: the user who triggered it, the agent process that ran it, the identity whose OAuth token was spent, and the tenant it executed in. When a compliance reviewer asks whether the agent was authorized to open a specific site, the answer has to reference the authorization event, not just the request. Persisting execution_id alongside your own trace ID gives you that link in one hop. For a comprehensive look at this topic, agent tool observability covers what it takes to know your agent is actually working correctly.

Which one to build against

If your users sit in a Copilot-licensed tenant, your agent runs interactively, and the work is finding and lightly editing small documents and list items, Work IQ SharePoint is a legitimate path with governance and Defender tracing included. Account for the preview status and the instruction to avoid hard-coded tool dependencies.

If your agent runs headless, touches files above 5 MB, needs webhooks or delta sync, has to page through libraries larger than 20 items, or serves customers who have not all bought Copilot, build against Microsoft Graph. Those are architectural boundaries in the current MCP server, not configuration options.

Most production SharePoint agents will end up on Graph for the pipeline and reach for MCP-shaped ergonomics through a scoped Virtual MCP endpoint. Either way the credential management problem is identical, and that is the part that needs production-grade infrastructure.

Get help building your SharePoint agent

Browse the Scalekit SharePoint connector docs for the full 39-tool reference and setup steps, or the SharePoint connector page for framework snippets and starter prompts.

Building something and want a second pair of eyes on the auth model? Join the Scalekit Slack community to compare notes with other agent builders, or talk to an engineer if you need help right now.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
zero upfront cost.

Every feature unlocked. No hidden fees.