Appearance
Azure App Registration — M365 MCP Server SOP
為 M365 MCP Server 設定 Azure Entra ID App Registration 的逐步操作指南,確保 OAuth 2.1 + OBO 流程所需的所有項目正確到位。
概述
M365 MCP Server 透過 OAuth 2.1 + On-Behalf-Of (OBO) 流程,讓 Claude Desktop 以使用者身份呼叫 Microsoft Graph API。App Registration 是整個認證鏈的起點——它定義了 Server 的身份(client ID/secret)、使用者授予的 scope、以及 Graph API 的委任權限。
設定錯誤的常見後果:
- Redirect URI 未配置 → OAuth callback 失敗
requestedAccessTokenVersion不是2→ OBO token exchange 回 401- 未 Grant admin consent → OBO 回
AADSTS65001 - Exchange Online 授權缺失 →
send_mail回 403
| 必須設定的項目 | 用途 |
|---|---|
| Client ID / Tenant ID / Client Secret | Server 連線 Azure Entra ID |
| Redirect URI | OAuth callback 回傳位址 |
Application ID URI + mcp-access scope | MCP client 取得 access token |
Graph API 權限(Mail.Send + User.Read) + Admin consent | OBO 呼叫 Graph API |
requestedAccessTokenVersion = 2 | 確保發出 v2.0 access token |
核心內容
整體流程圖
Step 1 記錄 Client ID + Tenant ID
Step 2 建立 / 確認 Client Secret
Step 3 設定 Redirect URI
Step 4 Expose an API(建立 mcp-access scope)
Step 5 新增 Graph API 權限並 Grant admin consent
Step 6 修改 Manifest(requestedAccessTokenVersion = 2)
Step 7 最終確認清單
Step 8 填入 .env 並啟動Step 1:記錄 Client ID 與 Tenant ID
- 前往 Azure Portal → App registrations
- 找到你的 App Registration → 進入 Overview 頁面
- 記下以下欄位:
| 欄位 | 對應環境變數 | 位置 |
|---|---|---|
| Application (client) ID | AZURE_CLIENT_ID | Overview → Application (client) ID |
| Directory (tenant) ID | AZURE_TENANT_ID | Overview → Directory (tenant) ID |
Step 2:確認或建立 Client Secret
- 進入 Certificates & secrets → Client secrets
- 判斷:
- 有未過期 secret 且還記得 Value → 直接使用
- 沒有或已過期 → 點 New client secret
- 若新建:輸入描述(例如
M365 MCP Server)→ 選擇到期時間 → 點 Add - ⚠️ 立刻複製 Value 欄位(離開頁面後就無法再看到)
| 欄位 | 對應環境變數 |
|---|---|
| Client Secret Value | AZURE_CLIENT_SECRET |
Step 3:設定 Redirect URI
- 進入 Authentication
- 確認有 Web platform,並確認以下 Redirect URI 存在(沒有就新增):
| 環境 | Redirect URI |
|---|---|
| 本機開發 | http://localhost:8000/auth/callback |
| 正式環境(K8s 主路徑) | https://你的網域/auth/callback |
正式環境(K8s Subpath,例如 /mcp-o365) | https://你的網域/mcp-o365/auth/callback |
- 類型選 Web → 點 Save
Step 4:Expose an API(建立 mcp-access scope)
MCP client(Claude Desktop)需要一個 custom scope 才能取得 Server 端的 access token。
- 進入 Expose an API
- Application ID URI:
- 未設定 → 點 Set,接受預設
api://<your-client-id> - 已設定 → 確認格式為
api://<your-client-id>
- 未設定 → 點 Set,接受預設
- 點 Add a scope,填入:
| 欄位 | 值 |
|---|---|
| Scope name | mcp-access |
| Who can consent | Admins and users |
| Admin consent display name | Access MCP Server |
| Admin consent description | Allows the MCP client to access the server on your behalf |
- 點 Add scope
- 確認最終 scope 全名:
api://<your-client-id>/mcp-access
Step 5:新增 Graph API 權限並 Grant Admin Consent
OBO 流程要求 App Registration 持有 Graph API 的委任權限。
- 進入 API permissions → Add a permission → Microsoft Graph → Delegated permissions
- 搜尋並勾選:
| 權限 | 用途 |
|---|---|
Mail.Send | 代替使用者寄送電子郵件 |
User.Read | 讀取使用者基本資料(get_my_profile tool) |
- 點 Add permissions
- 回到 API permissions 頁面,點上方的 Grant admin consent for <你的租戶名稱>
- ⚠️ 需要 Global Admin 或 Privileged Role Admin 角色
- 確認每個權限的 Status 顯示綠色勾勾 Granted for <租戶名稱>
Step 6:修改 Manifest — Token Version
OBO 流程要求 v2.0 access token;預設的 null 值會導致 OBO 失敗。
- 進入 Manifest
- 按
Ctrl+F搜尋requestedAccessTokenVersion - 將值從
null改為2:
json
"requestedAccessTokenVersion": 2- 點 Save
Step 7:最終確認清單
| # | 項目 | 確認 |
|---|---|---|
| 1 | 已記下 Application (client) ID | ☐ |
| 2 | 已記下 Directory (tenant) ID | ☐ |
| 3 | 已記下 Client Secret Value(未過期) | ☐ |
| 4 | Redirect URI 已加入(本機 http://localhost:8000/auth/callback) | ☐ |
| 5 | Redirect URI 已加入(正式環境) | ☐ |
| 6 | Application ID URI 已設定(api://<client-id>) | ☐ |
| 7 | 自定義 Scope mcp-access 已建立且啟用 | ☐ |
| 8 | Graph 權限 Mail.Send 已加入 | ☐ |
| 9 | Graph 權限 User.Read 已加入 | ☐ |
| 10 | 已 Grant admin consent(全部顯示綠勾) | ☐ |
| 11 | Manifest 的 requestedAccessTokenVersion 已改為 2 | ☐ |
Step 8:填入 .env 並啟動
env
AZURE_CLIENT_ID=<你的 Application (client) ID>
AZURE_CLIENT_SECRET=<你的 Client Secret Value>
AZURE_TENANT_ID=<你的 Directory (tenant) ID>
MCP_SERVER_BASE_URL=http://localhost:8000
MCP_SCOPE_NAME=mcp-access
MCP_HOST=0.0.0.0
MCP_PORT=8000
REDIS_URL=redis://redis:6379/0
FASTMCP_STATELESS_HTTP=truebash
docker compose up --build關鍵要點
- Client Secret 離開建立頁面後就無法再看到,一定要當下複製
requestedAccessTokenVersion = null(預設值)會讓 OBO 流程回 401,即使其他設定都正確- Grant admin consent 需要 Global Admin 角色;若沒有這個角色,需要聯絡 IT 管理員
- Subpath 部署(如
/mcp-o365)的 Redirect URI 必須包含完整 subpath:https://your-domain/mcp-o365/auth/callback
實際應用
App Registration 設定完成後,將三個環境變數(AZURE_CLIENT_ID、AZURE_CLIENT_SECRET、AZURE_TENANT_ID)填入 Server 的 .env 即可啟動。之後若 Client Secret 過期,只需回到 Step 2 建立新的,並更新 .env 和 K8s Secret。
部署設定參考
常見問題排查
| 症狀 | 原因與解法 |
|---|---|
| OAuth 登入後 redirect 失敗 | Redirect URI 未加入 → 回 Step 3 新增 |
| OBO token exchange 回 401/403 | requestedAccessTokenVersion 不是 2 → 回 Step 6 修改 |
OBO token exchange 回 AADSTS65001 | Graph API permissions 未 Grant admin consent → 回 Step 5 |
send_mail 回 403 Forbidden | 登入帳號沒有 Exchange Online 授權,或 Mail.Send 未 Grant admin consent |
get_my_profile 回 403 | User.Read 未 Grant admin consent → 回 Step 5 |
| Client Secret 無效 | Secret 已過期 → 回 Step 2 建立新的 |
| Scope 找不到 | Application ID URI 未設定,或 scope name 拼錯 → 回 Step 4 確認 |
相關概念
- M365 MCP Server(Kubernetes 部署) — Server 的完整部署與操作文件
- MCP OAuth Well-Known Subpath 的 nginx Ingress 架構 — Subpath 部署時 Redirect URI 的設定考量
- Azure Graph API 驗證與呼叫 — 直接以 ROPC 流程取 Token 呼叫 Graph API,適合排查權限問題
- AAD / LDAP 查詢工具指南 — 使用 ldapsearch 驗證 App Registration 對應帳號的 AD 屬性