Microsoft 365 MCP server for AI agents

Live

OAUTH 2.0

PRODUCTIVITY

Productivity

Microsoft 365 gives your agent each user's Outlook mail, calendar, contacts, and To Do tasks, plus Teams chats and meetings, OneDrive and SharePoint files, and Excel, Word, PowerPoint, and OneNote.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Microsoft 365
agent · Acme Q3
Run
Find a 30-minute slot tomorrow when Priya and I are both free.
S
microsoft365_outlook_find_meeting_times
141ms
Scheduling agent
Three 30-minute slots work for both of you tomorrow: 10:00, 13:30, and 16:00. Want me to send an invite for one of them?
Sources: Outlook calendars, 2 attendees
microsoft365
3 slots
18:29
Message Claude...

Tools your productivity agent reaches for on Microsoft 365, scoped per user.

CALL ANY TOOL
317 tools across Microsoft 365: read, send, and organize Outlook mail, manage calendars, contacts, and To Do tasks, message in Teams, work with OneDrive and SharePoint files, and edit Excel workbooks.
microsoft365_excel_add_table_column
Excel add table column
Add a new column to an existing Excel table in OneDrive. Optionally specify the column name, its zero-based insertion index (null = append at end), and initial cell values as a 2D array (first row is the header). Returns the created column object.
Parameters
Name
Type
Required
Description
item_id
string
Required
OneDrive item ID of the Excel (.xlsx) file. Example: '01BYE5RZ6QN3ZWBTUFOFD3GSPGOHDJD36K'.
table_id
string
Required
Name or ID of the table to add the column to. Example: 'Table1' or the GUID assigned by Excel.
index
integer
Optional
Zero-based index position at which to insert the column. Null or omitted means append the column at the right end of the table. Example: 0 inserts as the first column.
name
string
Optional
Display name for the new column header. If omitted, Excel auto-generates a name (e.g., 'Column1'). Example: 'Revenue'.
session_id
string
Optional
Optional workbook session ID from createSession. When provided, sent as the workbook-session-id header. Example: 'cluster=SN2&session=...'.
values
array
Optional
2D array of initial cell values for the column, including the header row in the first element. Example: [["Header"],["row1val"],["row2val"]]. Each inner array is one row. If omitted, the column is created empty.
microsoft365_excel_calculate_workbook
Excel calculate workbook
microsoft365_excel_create_chart
Excel create chart
microsoft365_excel_delete_chart
Excel delete chart
microsoft365_excel_get_range
Excel get range
microsoft365_excel_list_charts
Excel list charts
microsoft365_excel_update_chart
Excel update chart
microsoft365_onedrive_discard_checkout
Onedrive discard checkout
microsoft365_onedrive_search_drive_items
Onedrive search drive items
microsoft365_onedrive_upload_large_file
Onedrive upload large file
microsoft365_onenote_get_page_content
Onenote get page content
microsoft365_outlook_create_calendar
Outlook create calendar
microsoft365_outlook_create_mail_folder
Outlook create mail folder
microsoft365_outlook_delete_calendar_group
Outlook delete calendar group
microsoft365_outlook_forward_event
Outlook forward event
microsoft365_outlook_get_mail_tips
Outlook get mail tips
microsoft365_outlook_list_contacts
Outlook list contacts
microsoft365_outlook_send_draft_message
Outlook send draft message
microsoft365_outlook_todo_checklist_items_delete
Delete outlook todo checklist items
microsoft365_outlook_todo_tasks_update
Update outlook todo tasks
microsoft365_outlook_update_message
Outlook update message
microsoft365_powerpoint_read_presentation
Powerpoint read presentation
microsoft365_sharepoint_create_site_page
Sharepoint create site page
microsoft365_sharepoint_get_site
Sharepoint get site
microsoft365_sharepoint_list_followed_sites
Sharepoint list followed sites
microsoft365_sharepoint_publish_site_page
Sharepoint publish site page
microsoft365_sharepoint_remove_group_member
Sharepoint remove group member
microsoft365_sharepoint_renew_webhook
Sharepoint renew webhook
microsoft365_teams_archive_channel
Teams archive channel
microsoft365_teams_set_preferred_presence
Teams set preferred presence

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Microsoft 365 tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["microsoft365"], toolNames: [
    "microsoft365_outlook_search_messages",
    "microsoft365_outlook_find_meeting_times",
    "microsoft365_onedrive_search_drive_items"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Find a 30-minute slot tomorrow when Priya and I are both free" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["microsoft365"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Find a 30-minute slot tomorrow when Priya and I are both free" }],
  tools,
});

// Execute the tool call with the user's vaulted Microsoft 365 token
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["microsoft365"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Find a 30-minute slot tomorrow when Priya and I are both free" }],
  tools,
});

// Tool call runs with the user's vaulted Microsoft 365 token
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["microsoft365"] }, pageSize: 100,
});

const agent = new Agent({
  name: "scheduling_agent",
  model: "gemini-2.5-pro",
  instruction: "Microsoft 365 tools scoped to this user",
  tools,
});

await agent.run("Find a 30-minute slot tomorrow when Priya and I are both free");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Microsoft 365 tool. Click to copy, paste into your agent, done.
Mail
Copy the prompt
Copied
Search my inbox for emails about the Q3 budget.
Copy the prompt
Copied
Draft a reply to the latest message from Priya.
Copy the prompt
Copied
Move this week's newsletters into my Reading folder.
Calendar and meetings
Copy the prompt
Copied
Find a 30-minute slot tomorrow when Priya and I are both free.
Copy the prompt
Copied
Show my calendar for the rest of this week.
Copy the prompt
Copied
List the transcripts from yesterday's Teams project sync.
Files and Teams
Copy the prompt
Copied
Find the latest Q3 review deck in my OneDrive.
Copy the prompt
Copied
Read cells A1:F20 from the Budget sheet in this workbook.
Copy the prompt
Copied
Post a launch update to the General channel of the Marketing team.
SEE HOW AUTH WORKS
Each user signs in to Microsoft 365 once; Scalekit stores and refreshes their tokens. Credentials stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Microsoft 365
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Microsoft 365
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Microsoft 365
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Microsoft 365
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other productivity and collaboration connectors.
Support and Ops Teams
Meeting prep
Pulls agenda, participant context, and open action items before every meeting.
People Ops and HR teams
Performance review collector
Collects review feedback from Airtable and Google Forms scoped to each manager's direct reports, writes per-employee summaries to Notion, and DMs the manager a Slack digest.
People Ops and HR teams
Offer letter routing agent
Drafts the offer in PandaDoc, blocks on the hiring manager's approval in Slack, then emails the candidate their e-signature link. Every call runs as the recruiter who triggered it, never a shared HR bot.
GTM and RevOps Teams
Deal room sync
Pulls opportunity context from Salesforce, captures key decisions from Slack, and syncs a running summary to the deal room doc in Google Drive, but only when the deal actually changed.
Test other agents
See the same per-user auth pattern across other productivity and collaboration connectors.
OPS
Meeting prep agent
Assemble the agenda, HubSpot attendee history, and open action items from Gmail before every meeting on the calendar.
PEOPLE OPS
Performance review collector agent
Collect review feedback from Airtable and Google Forms per manager, summarise each report in Notion, and DM the digest in Slack.
PEOPLE OPS
Offer letter routing agent
Draft the offer in PandaDoc, gate it on hiring manager approval in Slack, then email the candidate their signature link.
GTM
Deal room sync agent
Pull opportunity context from Salesforce, capture decisions from Slack, and keep the Google Drive deal room doc current.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Microsoft 365 token looks fine in a demo. In production every sent email and calendar change looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Microsoft 365 today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Microsoft 365 as the user or through a shared service account?
As the user. Each user signs in to Microsoft 365 once, and Scalekit stores and refreshes their tokens. Audit logs attribute every action to that user, not a shared service account.
Where is the Microsoft 365 OAuth token stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. Refresh is automatic. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Microsoft 365?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example only the Outlook calendar tools for a scheduling agent. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Microsoft 365 access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
Which Microsoft 365 apps does the connector cover?
Outlook mail, calendar, contacts, and To Do, Teams chats, channels, meetings, and shifts, OneDrive, SharePoint sites and lists, and Excel, Word, PowerPoint, and OneNote. That is 317 tools: 127 read, 150 write, and 40 destructive. Expose only the apps your agent needs in toolNames.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""microsoft365"": {
""url"": ""https://mcp.scalekit.com/microsoft365"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.microsoft365]
url = ""https://mcp.scalekit.com/microsoft365""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""microsoft365"": {
""url"": ""https://mcp.scalekit.com/microsoft365"",
""type"": ""http""
}
}
}