mcp-server-m365
通过Graph API为Microsoft 365提供独立的MCP服务器。适用于Claude Code、Cursor、Windsurf或任何MCP客户端。
26个工具: 待办事项(6)、日历(6),计划阅读(4)、电子邮件(5)、团队聊天阅读(2)、文件搜索(1)、快照(1)
______________________________________________________________________
先决条件
- Node.js 18+ —
- A. Microsoft 365帐户 (工作/学校或个人,订阅M365)
- 一 Entra ID(Azure AD)应用程序注册 --请参阅下面的设置
- 应用程序注册的管理员同意(或可以授予它的全球管理员)
______________________________________________________________________
第一步:Node.js依赖关系
git clone https://github.com/Backline-Strategic/mcp-server-m365.git
cd mcp-server-m365
npm install这将安装两个软件包:
| 包装 | 版本 | 用途 |
|---|---|---|
@azure/msal-node | ^2.16.3 | MSAL客户端凭据流-获取Graph API令牌 |
node-fetch | ^3.3.2 | Graph API调用的HTTP客户端 |
没有其他运行时依赖关系。无构建步骤。
______________________________________________________________________
第二步:Entra应用程序注册
此服务器使用 仅应用程序(客户端凭据)身份验证 --它在没有登录用户的情况下运行。这意味着您需要一个拥有应用程序权限(未委托)和管理员同意的Entra应用程序注册。
选项A:自己创建(门户)
- 首选 portal.azure.com
- 搜索 微软Entra ID (以前是Azure Active Directory)
- 首选 应用程序注册 → 新注册
- 填写:
- 姓名: mcp-server-m365 (或任何你喜欢的东西) - 支持的帐户类型: 仅此组织目录中的帐户(单个租户) - 重定向URI: 留空
- 点击 注册
- 注意 应用程序(客户端)ID 和 目录(租户)ID 从“概述”页面
选项B:询问您的IT管理员
发送给他们:
“我需要一个Entra应用程序注册,以使用仅限应用程序的身份验证读取我的M365数据(日历、电子邮件、待办事项、团队聊天、OneDrive文件)的本地MCP工具。该应用程序需要下面列出的Graph应用程序权限,并授予管理员同意。请共享租户ID、客户端ID和客户端密码。”
______________________________________________________________________
第3步:API权限
在应用程序注册中,转到 API权限 → 添加权限 → 微软图形 → 应用程序权限.
添加以下所有内容:
| 权限 | 类型 | 使用人 | 备注 |
|---|---|---|---|
Calendars.ReadWrite | 应用程序 | 日历工具 | 读取+创建/更新/删除事件 |
Tasks.ReadWrite.All | 应用程序 | 待办事项工具 | 读写待办事项和列表 |
Tasks.Read.All | 应用程序 | 计划工具 | 阅读计划任务、计划、桶 |
Mail.ReadWrite | 应用程序 | 电子邮件工具 | 读取、标记、移动、起草电子邮件 |
Chat.Read.All | 应用程序 | 聊天工具 | 阅读团队聊天和消息 |
Files.Read.All | 应用程序 | 文件搜索 | 搜索OneDrive文件 |
GroupMember.Read.All | 应用程序 | planner_list_plans | 解决用户可以访问哪些planner计划 |
User.Read.All | 应用程序 | 所有工具 | 按UPN/电子邮件地址解析用户 |
添加所有权限后,单击 授予\[您的租户\]管理员同意 并确认。所有权限都应显示绿色复选标记。
为什么是应用程序权限? 此服务器作为后台进程运行,无需浏览器会话。委托权限需要交互式登录流程。应用程序权限+客户端密码使服务器能够进行静默身份验证。
Mail.ReadWrite对比Mail.Read:Mail.Read如果你只需要email_search,email_get,以及email_list_unread你需要Mail.ReadWrite为了email_draft_create和email_update(标记、移动)。
Tasks.ReadWrite.All对比Tasks.Read.All: 这两种权限都包括待办事项和计划读取权限。Tasks.ReadWrite.All对于任何待办事项写入操作(创建、更新、删除)都是必需的。此服务器中当前未实现计划写入。
______________________________________________________________________
第四步:客户机密
- 在应用程序注册中,转到 证书和秘密 → 客户机密 → 新客户机密
- 设置描述(例如。
mcp-server-m365)有效期(建议24个月) - 点击 添加
- 立即复制机密值 --离开此页面后无法再次查看
______________________________________________________________________
步骤5:查找您的用户ID
这 userId 在您的配置中,是您要访问其数据的帐户的UPN(用户主体名称)。这通常是您的工作电子邮件地址: you@yourdomain.com.
确认:转到 portal.azure.com → 微软Entra ID → 用户 → 查找您的帐户→ 复制 用户主体名称.
______________________________________________________________________
步骤6:配置凭据
选项A——配置文件(建议用于多帐户)
mkdir -p ~/.mcp-server-m365
cp m365-accounts.example.json ~/.mcp-server-m365/accounts.json编辑 ~/.mcp-server-m365/accounts.json:
{
"default": {
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"clientSecret": "your-client-secret-value",
"userId": "you@yourdomain.com"
}
}对于多个帐户(例如个人+工作):
{
"personal": {
"tenantId": "...",
"clientId": "...",
"clientSecret": "...",
"userId": "you@personal.com"
},
"work": {
"tenantId": "...",
"clientId": "...",
"clientSecret": "...",
"userId": "you@company.com"
}
}通过 "account": "work" 在工具参数中以特定帐户为目标。
选项B——环境变量(单一账户)
export M365_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export M365_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export M365_CLIENT_SECRET=your-client-secret-value
export M365_USER_ID=you@yourdomain.com______________________________________________________________________
步骤7:注册 .mcp.json
配置文件身份验证
{
"mcp-server-m365": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-m365/src/index.mjs"],
"env": {
"M365_ACCOUNTS_FILE": "/Users/you/.mcp-server-m365/accounts.json"
}
}
}环境变量认证
{
"mcp-server-m365": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-m365/src/index.mjs"],
"env": {
"M365_TENANT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"M365_CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"M365_CLIENT_SECRET": "your-secret",
"M365_USER_ID": "you@yourdomain.com"
}
}
}.mcp.json生活在你的项目的根,或使用~/.claude/mcp.json用于Claude Code全局配置。
______________________________________________________________________
测试
# List all tools (no credentials needed)
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node src/index.mjs 2>/dev/null | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8'); console.log('Tools:', JSON.parse(d).result.tools.length)"
# List To-Do tasks (requires credentials)
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"todo_list_tasks","arguments":{}}}' | node src/index.mjs
# Create a task
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"todo_create_task","arguments":{"title":"Test from MCP"}}}' | node src/index.mjs
# List today's calendar events
echo '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"calendar_list_events","arguments":{}}}' | node src/index.mjs
# Full snapshot (calendar + todo + email + planner + chats)
echo '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"m365_snapshot","arguments":{}}}' | node src/index.mjs
# Targeted snapshot (just calendar and todo)
echo '{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"m365_snapshot","arguments":{"include":["calendar","todo"]}}}' | node src/index.mjs______________________________________________________________________
多账户使用
通过 "account" 使用任何工具从配置文件中定位特定帐户:
{ "name": "todo_list_tasks", "arguments": { "account": "work" } }
{ "name": "calendar_list_events", "arguments": { "account": "personal", "startDate": "2026-03-20" } }省略 account 使用 "default" 条目,或使用env变量时。
______________________________________________________________________
工具参考
大惊小怪
| 工具 | 必需 | 可选 |
|---|---|---|
todo_list_tasks | — | listName, status, limit |
todo_get_task | taskId 或 title | listName |
todo_create_task | title 或 titles | dueDate, importance, listName |
todo_update_task | taskId 或 title | status, newTitle, dueDate, importance, listName |
todo_delete_task | taskId 或 title | listName |
todo_list_lists | — | — |
日历
| 工具 | 必需 | 可选 |
|---|---|---|
calendar_list_events | — | startDate, endDate, timeZone, limit |
calendar_get_event | eventId | — |
calendar_search_events | query | startDate, limit |
calendar_create_event | subject, start, end | timeZone, location, body, isAllDay, isOnlineMeeting, attendees |
calendar_update_event | eventId | subject, start, end, timeZone, location, body, attendees |
calendar_delete_event | eventId | — |
计划器(只读)
| 工具 | 必需 | 可选 |
|---|---|---|
planner_list_tasks | — | planId, bucketId, limit |
planner_get_task | taskId | — |
planner_list_plans | — | limit |
planner_list_buckets | planId | — |
电子邮件
| 工具 | 必需 | 可选 |
|---|---|---|
email_search | query | limit, folder |
email_get | messageId | includeBody |
email_list_unread | — | limit, folder |
email_draft_create | subject, toRecipients | body, ccRecipients, importance |
email_update | messageId | isRead, flag, destinationFolder |
聊天(只读)
| 工具 | 必需 | 可选 |
|---|---|---|
chat_list | — | limit, since |
chat_get_messages | chatId | limit, since |
文件
| 工具 | 必需 | 可选 |
|---|---|---|
files_search | query | limit |
快照
| 工具 | 必需 | 可选 |
|---|---|---|
m365_snapshot | — | include (阵列), calendarHours |
include 值: "calendar", "todo", "planner", "email", "chats"
______________________________________________________________________
故障排除
No Keychain entry found --此服务器不使用macOS钥匙串。确保 M365_ACCOUNTS_FILE 指向一个有效的JSON文件,或设置四个 M365_* env变量。
403 Forbidden 在任何工具上 --未授予管理员同意,或缺少权限。转到应用程序注册→ API权限→ 确认所有权限显示绿色的“授予”复选标记。
401 Unauthorized --检查 tenantId, clientId,以及 clientSecret.客户端机密过期--如果过期,则生成一个新的机密。
404 Not Found 关于规划工具 --用户可能没有任何Planner计划,或 GroupMember.Read.All 不见了。
chat_list 返回空值 — Chat.Read.All 大多数租户都需要管理员同意。请咨询您的IT管理员。
files_search 返回空值 — drive/recent 不支持app-only auth(这是Graph API的限制)。 files_search 用途 drive/root/search 这确实有效,但必须配置用户的OneDrive。
______________________________________________________________________
安全
- 切勿提交凭据。 使用
~/.mcp-server-m365/accounts.json在项目目录之外,或者使用在运行时注入的env-vars。 - 客户机密是敏感的——把它们当作密码对待。每年或更早轮换一次。
- 此服务器使用仅限应用程序的身份验证,这意味着它可以访问配置的
userId的数据没有活动会话。将应用程序注册仅限于它需要的用户/数据。 - 考虑使用 基于证书的身份验证 而不是用于生产或共享环境的客户端机密(尚未在此服务器中实现)。
______________________________________________________________________
微笑。
如果你分叉或扩展这个项目,请确保你的 .gitignore:
# Credentials — never commit these
m365-accounts.json
*.credentials.json
.env
.env.*
!.env.example
# Node
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# macOS
.DS_Store
.AppleDouble
.LSOverride
# Editor
.vscode/
.idea/
*.swp
*.swo
# Runtime
*.log______________________________________________________________________
许可证
麻省理工学院
