# https://github.com/okapi-ca/ms-365-admin-mcp-server 项目说明书

生成时间：2026-05-13 14:28:40 UTC

## 目录

- [项目介绍](#page-introduction)
- [核心功能特性](#page-features)
- [系统架构](#page-architecture)
- [通信传输层](#page-transports)
- [认证系统](#page-authentication)
- [授权机制](#page-authorization)
- [工具分类系统](#page-tool-categories)
- [风险模型](#page-risk-model)
- [部署指南](#page-deployment)
- [配置参考](#page-configuration)

<a id='page-introduction'></a>

## 项目介绍

### 相关页面

相关主题：[核心功能特性](#page-features), [系统架构](#page-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/README.md)
- [package.json](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/package.json)
- [CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)
- [CHANGELOG.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CHANGELOG.md)
- [SECURITY.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/SECURITY.md)
- [src/tool-categories.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)
- [src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)
</details>

# 项目介绍

## 项目概述

`ms-365-admin-mcp-server` 是一个基于 Microsoft Model Context Protocol (MCP) 的服务器项目，专门为 Microsoft 365 管理任务提供标准化的工具接口。该项目将 Microsoft Graph API 中的管理员操作封装为离散的、类型安全的工具（tools），使 AI 代理能够以受控和安全的方式执行 Microsoft 365 租户管理操作。 资料来源：[README.md]()

项目支持发布到 npm 作为 `@okapi-ca/ms-365-admin-mcp-server`，同时容器镜像发布到 GHCR (`ghcr.io/okapi-ca/ms-365-admin-mcp-server`)。 资料来源：[CHANGELOG.md]()

## 核心架构

### 技术栈

| 组件 | 技术选型 | 说明 |
|------|---------|------|
| 运行时 | Node.js / TypeScript | 严格模式，ESLint + Prettier 规范 |
| API 层 | Microsoft Graph API | OpenAPI 规范自动生成客户端 |
| 认证 | MSAL (Microsoft Authentication Library) | 客户端凭据流 |
| 类型安全 | Zod | Graph 响应的运行时验证 |
| 构建 | npm | 包管理和脚本执行 |

### 模块结构

```
src/
  auth.ts             # MSAL 客户端凭据流实现
  auth-bootstrap.ts   # RFC 8628 设备代码引导认证
  cli.ts              # Commander 参数解析
  cloud-config.ts     # 全球版与中国世纪互联版端点配置
  endpoints.json      # 工具定义的权威数据源
  generated/          # 自动生成的 Zod 客户端代码
  tool-categories.ts  # 工具分类正则模式
  risk-level.ts       # 风险等级计算模块
  user-token-authorization.ts  # 用户令牌授权验证
  untrusted-envelope.ts       # 不受信任响应包装器
```

资料来源：[CONTRIBUTING.md]()

## 核心功能

### 工具生态

项目当前包含 **444 个管理员工具**，覆盖以下主要类别：

| 类别 | 功能范围 | 参考文档 |
|------|---------|---------|
| `identity` | 用户、组、角色、设备、PIM、来宾、外部身份 | usecase-identity.md |
| `exchange` | 消息追踪、邮箱管理 | usecase-exchange.md |
| `intune` | 设备、合规、配置、Autopilot、应用、RBAC | usecase-intune.md |
| `governance` | 访问评审、权利管理、生命周期工作流、条款使用 | usecase-governance.md |
| `compliance` | 许可证、安全评分、身份保护、风险检测、CA策略 | usecase-compliance.md |
| `response` | 事件响应写入（禁用、撤销、确认、忽略） | usecase-response.md |
| `ediscovery` | 电子发现案例（Microsoft Purview） | usecase-ediscovery.md |
| `cloudpc` | 云 PC / Windows 365 | usecase-cloudpc.md |
| `callrecords` | Teams 通话记录 | usecase-callrecords.md |
| `print` | 通用打印 | usecase-print.md |
| `infoprotection` | BitLocker、威胁评估、敏感度标签 | usecase-infoprotection.md |
| `sharepointadmin` | SharePoint 租户管理 | usecase-sharepointadmin.md |
| `retention` | 记录管理 | usecase-retention.md |

资料来源：[tools-catalog.md]()

### 工具分类模式

工具类别通过正则表达式自动匹配工具名称：

```typescript
export const TOOL_CATEGORIES: Record<string, ToolCategory> = {
  identity: {
    name: 'identity',
    pattern: /user|group|role|device|administrative|directory/i,
    description: '用户、组、角色、设备、PIM...',
  },
  response: {
    name: 'response',
    pattern:
      /disable-user|revoke|block|reset|isolate|update-security|.../i,
    description: '事件响应操作...',
  },
  // ...
};
```

资料来源：[src/tool-categories.ts]()

## 安全模型

项目实现了多层安全防护机制。

### 风险等级体系

所有非 GET 操作必须标注风险等级，作为 MCP 工具注册的依据：

| 风险等级 | 判定标准 | 示例工具 |
|---------|---------|---------|
| `low` | 只读或微小影响 | `run-hunting-query`, `add-security-alert-comment` |
| `medium` | 单个实体的可逆变更 | `update-user`, `add-group-member`, `create-invitation` |
| `high` | 广泛影响、凭据变更或破坏性操作 | `revoke-user-sessions`, `update-conditional-access-policy` |
| `critical` | 不可逆或租户范围影响 | `delete-user`, `wipe-managed-device`, `delete-conditional-access-policy` |

资料来源：[CONTRIBUTING.md]()

### 安全机制

| 机制 | 描述 |
|------|------|
| `--max-risk-level` | CLI 参数限制注册工具的最大风险等级 |
| `--allow-writes` | 显式授权写入操作 |
| 响应包装器 | Graph 响应使用 nonce 包装防提示注入 |
| 最小权限 | 仅请求必需的 Graph API 权限 |

项目包含 51 个单元测试覆盖所有五个安全关键模块。 资料来源：[CHANGELOG.md]()

## 认证机制

### 客户端凭据流

```mermaid
graph TD
    A[启动服务器] --> B[读取 .env 配置]
    B --> C{环境变量检查}
    C -->|缺失 MSAL 配置| D[触发设备代码引导]
    C -->|有 MSAL 配置| E[初始化 MSAL 客户端]
    D --> F[RFC 8628 设备代码流程]
    F --> G[获取访问令牌]
    E --> G
    G --> H[缓存令牌到 mcp-remote]
    H --> I[服务器就绪]
```

### 云配置

项目支持 Microsoft 365 全球版和中国世纪互联版（21Vianet）的不同端点，通过 `cloud-config.ts` 模块统一管理。 资料来源：[src/auth.ts]()

## 开发工作流

### 环境配置

```bash
git clone https://github.com/okapi-ca/ms-365-admin-mcp-server.git
cd ms-365-admin-mcp-server
npm install
npm run generate    # 下载 Graph OpenAPI 规范并生成客户端
npm run build
npm test
```

本地 `.env` 文件配置：

```
MS365_ADMIN_MCP_CLIENT_ID=...
MS365_ADMIN_MCP_CLIENT_SECRET=...
MS365_ADMIN_MCP_TENANT_ID=...
```

资料来源：[CONTRIBUTING.md]()

### 添加工具流程

```mermaid
graph LR
    A[编辑 endpoints.json] --> B[添加工具定义]
    B --> C[npm run generate]
    C --> D[生成 Zod 客户端代码]
    D --> E[node dist/index.js --list-tools]
    E --> F[验证工具注册]
    F --> G[添加单元测试]
    G --> H[更新 README.md 工具表]
```

资料来源：[CONTRIBUTING.md]()

## 工具定义规范

`endpoints.json` 中每个工具定义包含：

```json
{
  "toolName": {
    "method": "GET|POST|PATCH|DELETE",
    "appPermissions": ["Permission.Read.All"],
    "llmTip": "可选的 LLM 提示信息",
    "riskLevel": "low|medium|high|critical"
  }
}
```

## 版本历史

| 版本 | 工具数 | 主要变更 |
|------|-------|---------|
| 当前 | 444 | 安全修复、BitLocker 恢复密钥等敏感读取标注 |
| 之前 | 369 | 新增云 PC、Teams 通话记录、通用打印等5个类别 |
| 更早 | 306 | 107 个高价值管理员端点 |
| 更早 | 199 | 安全修复、权限范围缩减 |

资料来源：[CHANGELOG.md]()

## 使用场景

### 管理员操作自动化

项目主要用于以下场景：

- **身份管理**：用户生命周期管理、组分配、角色权限
- **设备管理**：Intune 设备合规性监控、丢失设备远程操作
- **安全响应**：风险用户确认、 compromised 用户隔离
- **合规审计**：电子发现、访问评审、审计日志查询
- **租户配置**：SharePoint、Teams、Exchange 设置管理

### MCP 客户端集成

项目作为 MCP 服务器运行，Claude Desktop/Code 等客户端可通过 MCP Inspector 进行交互式调试：

```bash
npm run inspector
```

资料来源：[CONTRIBUTING.md]()

## 质量保证

| 检查项 | 命令 |
|-------|------|
| 代码格式检查 | `npm run format:check` |
| ESLint 检查 | `npm run lint` |
| 完整验证 | `npm run verify` |
| 列出所有工具 | `node dist/index.js --list-tools` |
| 列出所有权限 | `node dist/index.js --list-permissions` |

## 许可证

本项目采用 MIT 许可证。 资料来源：[CHANGELOG.md]()

---

<a id='page-features'></a>

## 核心功能特性

### 相关页面

相关主题：[项目介绍](#page-introduction), [工具分类系统](#page-tool-categories)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/tool-categories.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)
- [src/endpoints.json](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/endpoints.json)
- [src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)
- [src/cloud-config.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cloud-config.ts)
- [src/cli.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cli.ts)
- [src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)
- [CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)
- [CHANGELOG.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CHANGELOG.md)
</details>

# 核心功能特性

ms-365-admin-mcp-server 是一个基于 Model Context Protocol (MCP) 的 Microsoft 365 管理服务器，通过 Microsoft Graph API 为 AI 助手提供对 Microsoft 365 管理功能的标准化访问接口。该项目从 175 个工具起步，经过多次迭代已扩展至 **515 个管理工具**，覆盖安全、审计、合规、设备管理、身份治理等核心领域。

## 1. 系统架构概览

### 1.1 整体架构

ms-365-admin-mcp-server 采用分层架构设计，核心层负责与 Microsoft Graph API 交互，认证层处理 Azure AD 应用注册凭证，配置层支持全球版和中国区（21Vianet）两种部署模式。

```mermaid
graph TD
    subgraph 客户端层
        A[MCP 客户端 / Claude Code]
        B[MCP Inspector]
    end
    
    subgraph 服务端核心
        C[CLI 解析层<br/>src/cli.ts]
        D[工具注册表<br/>src/endpoints.json]
        E[风险评估引擎<br/>src/risk-level.ts]
    end
    
    subgraph 认证与配置
        F[MSAL 认证<br/>src/auth.ts]
        G[云配置<br/>src/cloud-config.ts]
    end
    
    subgraph Microsoft Graph API
        H[全球版<br/>graph.microsoft.com]
        I[中国版<br/>graph.microsoft.cn]
    end
    
    A --> C
    B --> C
    C --> D
    C --> E
    C --> F
    F --> G
    G --> H
    G --> I
    D --> H
    D --> I
```

### 1.2 目录结构

| 目录/文件 | 功能说明 |
|-----------|----------|
| `bin/` | 代码生成脚本（OpenAPI 规范转换为 Zod 客户端） |
| `src/` | 核心源代码 |
| `src/auth.ts` | MSAL 客户端凭证流认证 |
| `src/cli.ts` | Commander 参数解析 |
| `src/cloud-config.ts` | 全球版与中国区端点配置 |
| `src/endpoints.json` | 工具定义的事实来源 |
| `src/generated/` | 自动生成的 Zod 验证代码 |
| `src/risk-level.ts` | 风险等级计算与权限校验 |
| `src/tool-categories.ts` | 工具分类与预设定义 |
| `docs/` | 使用文档、风险模型、剧本 |

## 2. 工具分类与预设体系

### 2.1 预设分类总览

该服务器将 515 个工具组织为 **17 个功能预设（Preset）**，每个预设对应特定的管理场景。预设通过正则表达式匹配工具名称实现自动归类。

| 预设名称 | 功能描述 | 对应用例文件 |
|----------|----------|--------------|
| `security` | 安全警报、事件、攻击模拟、威胁情报 | `usecase-security.md` |
| `audit` | 目录审计、登录日志、预配记录、已删除项 | `usecase-audit.md` |
| `health` | 服务运行状况、消息中心公告 | `usecase-health.md` |
| `reports` | 使用报告（Teams、邮件、SharePoint、OneDrive） | `usecase-reports.md` |
| `identity` | 用户、组、角色、设备、PIM、来宾用户、外部身份 | `usecase-identity.md` |
| `exchange` | 邮件跟踪、邮箱管理 | `usecase-exchange.md` |
| `intune` | 设备、合规、配置、Autopilot、应用、RBAC | `usecase-intune.md` |
| `governance` | 访问评审、权利管理生命周期、条款使用 | `usecase-governance.md` |
| `compliance` | 许可证、安全分数、身份保护、风险检测、CA 策略 | `usecase-compliance.md` |
| `response` | 事件响应写入操作（禁用、吊销、确认、驳回） | `usecase-response.md` |
| `ediscovery` | 电子发现案例（Purview） | `usecase-ediscovery.md` |
| `cloudpc` | 云 PC / Windows 365 | `usecase-cloudpc.md` |
| `callrecords` | Teams 通话记录 | `usecase-callrecords.md` |
| `print` | 通用打印 | `usecase-print.md` |
| `infoprotection` | BitLocker、威胁评估、敏感度标签 | `usecase-infoprotection.md` |
| `sharepointadmin` | SharePoint 租户管理 | `usecase-sharepointadmin.md` |
| `retention` | 记录管理 | `usecase-retention.md` |

### 2.2 工具分类定义实现

预设分类在 `src/tool-categories.ts` 中通过 TypeScript 接口和正则表达式定义：

```typescript
export interface ToolCategory {
  name: string;
  pattern: RegExp;
  description: string;
}

export const TOOL_CATEGORIES: Record<string, ToolCategory> = {
  security: {
    name: 'security',
    pattern: /security|alert|incident|attack-simulation|threat-intel/i,
    description: 'Security alerts, incidents, attack simulations...',
  },
  identity: {
    name: 'identity',
    pattern: /user|group|role|conditional|directory|domain|auth-method|.../i,
    description: 'Identity and access management...',
  },
  // ... 其他预设
};
```

资料来源：[src/tool-categories.ts:1-20]()

### 2.3 工具发现与验证

服务器提供命令行工具用于验证工具分类和权限配置：

```bash
# 列出所有工具
node dist/index.js --list-tools

# 按预设列出工具
node dist/index.js --preset security --list-tools

# 列出所需权限
node dist/index.js --list-permissions

# 验证特定预设
node dist/index.js --preset identity --list-tools | grep list-users
```

## 3. 风险等级管理体系

### 3.1 风险等级定义

服务器对所有非 GET 操作工具进行风险分类，确保高风险操作需要明确授权：

| 风险等级 | 判断标准 | 影响范围 | 操作示例 |
|----------|----------|----------|----------|
| `low` | 只读效果或最小影响 | 有限 | 添加安全警报评论、重新处理用户许可证 |
| `medium` | 可逆变更影响单个实体 | 单个实体 | 更新用户、创建组、添加工具成员 |
| `high` | 重大影响、凭证变更或破坏性操作 | 多个实体 | 吊销用户会话、更新条件访问策略 |
| `critical` | 不可逆或租户级影响 | 整个租户 | 删除用户、擦除托管设备、删除条件访问策略 |

### 3.2 风险等级计算逻辑

风险等级的计算遵循以下优先级：

1. **已配置风险等级优先**：如果 `endpoints.json` 中明确指定了 `riskLevel`，则使用该值
2. **GET 请求默认低风险**：GET 请求默认为 `low`（只读操作）
3. **未标注写入操作默认为 critical**：对于没有明确标注风险等级的写入操作，默认设置为 `critical`（故障安全原则）

```typescript
export function effectiveRiskLevel(
  configuredRiskLevel: RiskLevel | undefined,
  method: string
): RiskLevel {
  if (configuredRiskLevel) return configuredRiskLevel;
  return method.toUpperCase() === 'GET' ? 'low' : 'critical';
}
```

资料来源：[src/risk-level.ts:9-17]()

### 3.3 权限校验机制

工具执行前会校验其风险等级是否在允许范围内：

```typescript
export function isToolAllowed(
  configuredRiskLevel: RiskLevel | undefined,
  method: string,
  maxRiskLevel: RiskLevel
): boolean {
  return rank(effectiveRiskLevel(configuredRiskLevel, method)) <= rank(maxRiskLevel);
}
```

写入操作的默认行为需要显式启用：

```bash
# 允许中等风险操作
node dist/index.js --allow-writes medium

# 允许高风险操作（需二次确认）
node dist/index.js --allow-writes high
```

### 3.4 高危工具分类

#### Critical 级别（需带外审批）

以下操作被视为不可逆或具有租户范围影响：

- `delete-user` — 删除用户账户
- `delete-group` — 删除安全组
- `delete-conditional-access-policy` — 删除条件访问策略
- `wipe-managed-device` — 远程擦除托管设备
- `delete-managed-device` — 删除设备注册
- `delete-ediscovery-case` — 删除电子发现案例

#### High 级别（需显式确认 + 预演）

以下操作需要操作员确认并可能需要干运行：

- `revoke-user-sessions` — 吊销用户会话
- `confirm-compromised-users` — 确认受损用户
- `change-user-password` — 更改用户密码
- `update-device` — 更新设备配置
- `create-attack-simulation` — 创建攻击模拟（钓鱼测试）

## 4. 认证与安全机制

### 4.1 MSAL 客户端凭证流

服务器使用 Microsoft Authentication Library (MSAL) 的客户端凭证流进行认证，适用于服务级（无用户交互）的管理操作：

```mermaid
sequenceDiagram
    participant MCP as MCP Server
    participant MSAL as MSAL 库
    participant AAD as Azure AD
    
    MCP->>AAD: 请求访问令牌<br/>(client_id, client_secret, tenant_id)
    AAD-->>MSAL: 返回 access_token
    MSAL-->>MCP: access_token
    MCP->>Graph: Graph API 请求<br/>(Bearer token)
    Graph-->>MCP: API 响应
```

### 4.2 环境变量配置

需要在 `.env` 文件中配置以下凭证：

```bash
MS365_ADMIN_MCP_CLIENT_ID=...    # Azure AD 应用注册的应用 ID
MS365_ADMIN_MCP_CLIENT_SECRET=... # 应用密钥
MS365_ADMIN_MCP_TENANT_ID=...    # 租户 ID
```

资料来源：[CONTRIBUTING.md:45-49]()

### 4.3 查询字符串与错误信息防护

服务器对以下内容进行脱敏处理以防止凭证泄露：

- 查询字符串参数
- `testLogin` 错误消息中的敏感信息

> `sec: sanitize query strings and testLogin error leaks` — CHANGELOG.md

## 5. 云配置与多租户支持

### 5.1 全球版与中国区切换

服务器支持两种 Microsoft Graph 端点配置，适用于不同的主权云环境：

```mermaid
graph LR
    A[请求] --> B{cloud-config}
    B -->|全球版| C[graph.microsoft.com]
    B -->|中国版| D[graph.microsoft.cn<br/>21Vianet]
    
    style C fill:#4CAF50
    style D fill:#FF9800
```

| 云类型 | Graph 端点 | 适用场景 |
|--------|------------|----------|
| Global | `graph.microsoft.com` | 全球 Microsoft 365 商业版 |
| China | `graph.microsoft.cn` | 世纪互联运营的 Azure 中国区 |

配置详情见 `src/cloud-config.ts`。

## 6. 工具定义与代码生成

### 6.1 端点定义格式

工具定义以 JSON 格式存储在 `endpoints.json` 中，作为所有工具定义的事实来源：

```json
{
  "toolName": "list-users",
  "endpoint": "/v1.0/users",
  "method": "GET",
  "appPermissions": ["User.Read.All"],
  "llmTip": "列出租户中的所有用户",
  "riskLevel": "low"
}
```

### 6.2 代码生成流程

服务器采用 OpenAPI 规范驱动的工作流：

```mermaid
graph LR
    A[Graph OpenAPI 规范] --> B[bin/ 脚本]
    B --> C[生成 Zod 验证代码]
    B --> D[更新 endpoints.json]
    C --> E[src/generated/]
    D --> F[src/endpoints.json]
    
    style A fill:#2196F3,color:#fff
    style E fill:#E3F2FD
    style F fill:#E3F2FD
```

生成命令：

```bash
npm run generate  # 下载 Graph OpenAPI 规范并生成客户端
```

**重要提示**：`src/generated/` 目录下的文件由代码生成脚本自动维护，请勿手动编辑。如需修改工具定义，应编辑 `endpoints.json` 后重新生成。

资料来源：[CONTRIBUTING.md:88-94]()

## 7. 命令行接口

### 7.1 可用命令

服务器通过 `src/cli.ts` 提供以下命令行选项：

| 命令 | 功能 |
|------|------|
| `--list-tools` | 列出所有可用工具 |
| `--list-permissions` | 列出所需 Graph API 权限 |
| `--list-tools --preset <name>` | 按预设筛选工具 |
| `--list-tools --category <name>` | 按类别筛选工具 |
| `--allow-writes <level>` | 允许指定风险等级的写入操作 |
| `--preset <name> --list-tools` | 验证预设分类 |
| `--inspector` | 启动 MCP Inspector |

### 7.2 交互式调试

使用 MCP Inspector 进行本地调试：

```bash
npm run inspector
```

## 8. 开发与贡献指南

### 8.1 开发环境搭建

```bash
git clone https://github.com/okapi-ca/ms-365-admin-mcp-server.git
cd ms-365-admin-mcp-server
npm install
npm run generate    # 生成客户端代码
npm run build       # 编译 TypeScript
npm test            # 运行测试
npm run verify      # 完整验证（lint + 测试）
```

### 8.2 添加新工具的工作流

添加新工具的标准流程：

1. **编辑端点定义**：在 `endpoints.json` 中添加工具定义

   ```json
   {
     "toolName": "list-something",
     "endpoint": "/v1.0/something",
     "method": "GET",
     "appPermissions": ["Something.Read.All"],
     "llmTip": "可选的 LLM 提示",
     "riskLevel": "low"
   }
   ```

2. **重新生成客户端**：

   ```bash
   npm run generate
   ```

3. **验证工具注册**：

   ```bash
   node dist/index.js --list-tools | grep list-something
   node dist/index.js --list-permissions | grep Something
   ```

4. **添加测试**：为非平凡参数处理或 skipEncoding 规则添加测试

5. **更新 README.md**：更新工具计数和类别表格

### 8.3 提交规范

| 前缀 | 使用场景 |
|------|----------|
| `feat:` | 新工具、预设或功能 |
| `fix:` | 错误修复 |
| `sec:` | 安全修复 |
| `docs:` | 仅文档更改 |
| `chore:` | 工具、依赖、非功能性变更 |
| `refactor:` | 无行为变更的重构 |
| `test:` | 仅测试 |
| `build(deps):` | 依赖升级 |

## 9. 权限模型

### 9.1 最小权限原则

所有新工具必须声明最小必需的 Graph API 权限：

| 操作类型 | 推荐权限 | 避免 |
|----------|----------|------|
| 只读 | `*.Read.All` | `*.ReadWrite.All` |
| 写入 | `*.ReadWrite.All` | 仅在必要时使用 |

### 9.2 应用权限 vs 委托权限

服务器使用 **应用权限**（application permissions），因为它是无用户交互的服务级操作：

```typescript
// endpoints.json 中的权限声明
{
  "appPermissions": ["User.Read.All", "Group.Read.All"]
}
```

## 10. 快速参考表

### 10.1 关键文件速查

| 文件路径 | 用途 |
|----------|------|
| `src/endpoints.json` | 工具定义的源文件 |
| `src/tool-categories.ts` | 预设分类配置 |
| `src/risk-level.ts` | 风险计算逻辑 |
| `src/auth.ts` | MSAL 认证 |
| `src/cloud-config.ts` | 云端点配置 |
| `src/cli.ts` | 命令行接口 |
| `docs/RISK_MODEL.md` | 风险模型文档 |
| `docs/USE_CASES.md` | 用例文档 |

### 10.2 风险等级快速对照

```
权限等级: low < medium < high < critical
允许写入: --allow-writes medium 允许 low + medium
```

### 10.3 版本历史要点

| 版本 | 工具数量 | 关键变更 |
|------|----------|----------|
| 当前 | 515 | 71 个管理写入端点 |
| v1.0 | 444 | 75 个管理写入操作 |
| - | 369 | Cloud PC、Teams 通话记录、通用打印、信息保护 |
| - | 306 | eDiscovery、Intune、身份治理 |
| - | 199 | 权限范围缩减至最小权限 |
| 早期 | 175 | 基础安全、设备、PIM、风险检测 |

资料来源：[CHANGELOG.md:1-50]()

---

<a id='page-architecture'></a>

## 系统架构

### 相关页面

相关主题：[项目介绍](#page-introduction), [通信传输层](#page-transports), [认证系统](#page-authentication)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)
- [src/graph-client.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/graph-client.ts)
- [src/server.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/server.ts)
- [src/graph-tools.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/graph-tools.ts)
- [src/tool-categories.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)
- [src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)
- [src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)
- [src/cloud-config.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cloud-config.ts)
</details>

# 系统架构

## 概述

`ms-365-admin-mcp-server` 是一个基于 Model Context Protocol (MCP) 的 Microsoft 365 管理服务器，通过 Microsoft Graph API 为 AI 代理提供 515+ 管理工具的访问能力。服务器采用 TypeScript 开发，运行于 Node.js 环境，支持标准输入输出（STDIO）和 HTTP 两种传输模式，可部署在 Azure Container Apps 等云环境中。

核心设计原则：
- **安全优先**：所有写操作必须按风险等级分类，需要显式授权方可执行
- **最小权限**：仅请求必要的 Graph API 权限
- **零破坏变更**：工具名称、参数结构预设分类不可随意变更
- **代码生成**：工具定义基于 OpenAPI 规范自动生成，确保与 Graph API 同步

资料来源：[CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

---

## 整体架构

```mermaid
graph TD
    subgraph 客户端层
        A1[Claude Desktop]
        A2[Claude Code]
        A3[其他 MCP 客户端]
    end

    subgraph 服务器传输层
        B1[STDIO 服务器<br/>server.ts]
        B2[HTTP 服务器<br/>http-server.ts<br/>StreamableHTTP]
    end

    subgraph 核心服务层
        C1[认证模块<br/>auth.ts]
        C2[工具注册<br/>graph-tools.ts]
        C3[风险评估<br/>risk-level.ts]
        C4[工具分类<br/>tool-categories.ts]
        C5[云配置<br/>cloud-config.ts]
    end

    subgraph Graph API 层
        D1[Graph 客户端<br/>graph-client.ts]
        D2[端点配置<br/>endpoints.json]
        D3[生成工具<br/>generated/]
    end

    subgraph Microsoft 365
        E1[Microsoft Graph API]
        E2[Azure AD<br/>令牌颁发]
    end

    A1 --> B1
    A2 --> B1
    A3 --> B2
    B1 --> C1
    B2 --> C1
    C1 --> D1
    D1 --> E1
    D1 --> E2
    C2 --> D2
    C2 --> D3
```

资料来源：[src/server.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/server.ts)

---

## 核心组件

### 组件职责矩阵

| 组件文件 | 职责 | 关键类型/函数 |
|---------|------|--------------|
| `src/index.ts` | 应用入口点，CLI 参数解析 | Commander.js |
| `src/auth.ts` | MSAL 客户端凭据流认证 | `getConfidentialClientApplication` |
| `src/cloud-config.ts` | 全球版与世纪互联版端点切换 | `CloudConfig`, `getCloudConfig` |
| `src/graph-client.ts` | Graph API HTTP 封装 | `GraphClient`, `fetchWithAuth` |
| `src/graph-tools.ts` | MCP 工具注册与执行 | `registerTools`, `executeGraphTool` |
| `src/risk-level.ts` | 风险等级计算与权限校验 | `effectiveRiskLevel`, `isToolAllowed` |
| `src/tool-categories.ts` | 预设分类定义 | `TOOL_CATEGORIES`, `getCombinedPresetPattern` |
| `src/server.ts` | STDIO 传输模式服务器 | `StdioServer`, `runStdioServer` |
| `src/http-server.ts` | HTTP 传输模式服务器 | `StreamableHTTPTransport` |
| `src/token-validator.ts` | HTTP 模式 JWT 验证 | `validateJwtToken` |

资料来源：[CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

---

## 工具注册流程

### 工具定义来源

所有工具定义存储在 `src/endpoints.json` 中，作为工具注册的唯一数据源。每个条目包含：

```jsonc
{
  "toolName": "list-users",
  "pathPattern": "/users",
  "method": "GET",
  "appPermissions": ["User.Read.All"],
  "llmTip": "获取所有用户列表，支持 $select, $filter",
  "riskLevel": "low"  // 仅非 GET 操作需要
}
```

资料来源：[CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

### 工具注册时序

```mermaid
sequenceDiagram
    participant CLI as 命令行解析
    participant Server as StdioServer
    participant Registry as 工具注册器
    participant Config as endpoints.json
    participant Generator as 代码生成器
    participant Graph as GraphClient

    CLI->>Server: 初始化服务器
    Server->>Registry: 加载 endpoints.json
    Registry->>Generator: 读取工具定义
    Generator->>Config: 解析工具元数据
    Config-->>Registry: 返回工具配置列表
    Registry->>Registry: 遍历每个工具
    Registry->>Registry: 计算 effectiveRiskLevel
    Registry->>Registry: 检查 maxRiskLevel 限制
    alt 工具被风险等级过滤
        Registry->>Registry: 跳过注册
    else 工具允许注册
        Registry->>Graph: 注册 MCP 工具
        Graph-->>Registry: 注册成功
    end
    Registry->>Server: 返回注册统计
```

资料来源：[src/graph-tools.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/graph-tools.ts)

---

## 认证机制

### MSAL 客户端凭据流

服务器使用 MSAL (Microsoft Authentication Library) 的客户端凭据流进行无用户认证：

```mermaid
graph LR
    A[服务器启动] --> B[初始化 MSAL 客户端]
    B --> C[从环境变量读取<br/>CLIENT_ID, CLIENT_SECRET, TENANT_ID]
    C --> D{云类型}
    D -->|全球版| E[login.microsoftonline.com]
    D -->|世纪互联| F[login.partner.microsoftonline.cn]
    E --> G[获取访问令牌]
    F --> G
    G --> H[Graph API 请求]
    H -->|令牌过期| G
```

资料来源：[src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)

### 云配置支持

| 云类型 | 标识 | Graph 根端点 |
|--------|------|-------------|
| 全球版 (Commercial) | `global` | `graph.microsoft.com` |
| 世纪互联版 (China 21Vianet) | `china` | `graph.microsoft.cn` |

资料来源：[src/cloud-config.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cloud-config.ts)

---

## 风险等级系统

### 风险等级定义

| 等级 | 描述 | 判定条件 |
|------|------|---------|
| `low` | 只读操作或无害写操作 | GET 请求默认；POST 查询报表 |
| `medium` | 单个实体的可逆变更 | `update-user`, `add-group-member` |
| `high` | 广泛影响、凭据变更或破坏性操作 | `revoke-user-sessions`, `update-conditional-access-policy` |
| `critical` | 不可逆或租户级影响 | `delete-user`, `wipe-managed-device`, `delete-conditional-access-policy` |

资料来源：[src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)

### 风险等级计算逻辑

```typescript
function effectiveRiskLevel(
  configuredRiskLevel: RiskLevel | undefined,
  method: string
): RiskLevel {
  // 1. 如果配置了显式风险等级，使用配置值
  if (configuredRiskLevel) return configuredRiskLevel;
  
  // 2. GET 请求默认 low
  if (method.toUpperCase() === 'GET') return 'low';
  
  // 3. 未标注的非 GET 请求默认为 critical（fail-safe）
  return 'critical';
}

function isToolAllowed(
  configuredRiskLevel: RiskLevel | undefined,
  method: string,
  maxRiskLevel: RiskLevel
): boolean {
  return rank(effectiveRiskLevel(configuredRiskLevel, method)) <= rank(maxRiskLevel);
}
```

**重要**：未在 `endpoints.json` 中显式标注风险等级的非 GET 操作会被视为 `critical`，确保敏感操作不会被意外暴露。

资料来源：[src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)

---

## 工具分类预设

### 预设分类列表

| 预设名称 | 功能范围 | 正则匹配模式 |
|---------|---------|-------------|
| `security` | 安全警报、事件、攻击模拟、威胁情报 | `/security\|alert\|incident\|attack/i` |
| `audit` | 目录审计、登录日志、预配日志 | `/audit\|sign-in\|provision\|deleted/i` |
| `health` | 服务健康、消息中心 | `/serviceHealth\|serviceStatus\|messageCenter/i` |
| `reports` | 使用报告（Teams、邮件、SharePoint 等） | `/report\|usage/i` |
| `identity` | 用户、组、角色、设备、PIM、来宾 | `/user\|group\|role\|device\|pim\|guest/i` |
| `exchange` | 消息跟踪、邮箱 | `/mail\|messageTrace\|mailbox/i` |
| `intune` | 设备、合规、配置、Autopilot、应用、RBAC | `/intune\|managedDevice\|compliance/i` |
| `governance` | 访问评审、权利管理、生命周期、PIM | `/accessReview\|entitlement\|lifecycle\|pim/i` |
| `compliance` | 许可证、安全分数、身份保护、条件访问 | `/license\|secureScore\|conditionalAccess/i` |
| `response` | 事件响应写操作（禁用、撤销、确认） | `/disable\|revoke\|block\|reset\|wipe/i` |
| `ediscovery` | 电子发现案件（Purview） | `/ediscovery/i` |
| `cloudpc` | 云 PC / Windows 365 | `/cloud-pc\|provisioning/i` |
| `callrecords` | Teams 通话记录 | `/call-record\|call-session\|pstn/i` |
| `print` | 通用打印 | `/print/i` |
| `infoprotection` | BitLocker、威胁评估、敏感标签 | `/bitlocker\|sensitivity\|threatAssessment/i` |
| `sharepointadmin` | SharePoint 租户管理 | `/sharepoint\|spo/i` |
| `retention` | 记录管理 | `/retention/i` |
| `teamsadmin` | Teams 管理 | `/team\|channel\|teams-app/i` |
| `all` | 所有可用工具 | `/.*/` |

资料来源：[src/tool-categories.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)

---

## 传输模式

### STDIO 模式

适用于本地运行和 Claude Desktop/Code 集成：

```mermaid
graph LR
    A[Claude Desktop] <-->|STDIO| B[ms-365-admin-mcp-server]
    B --> C[MSAL 认证]
    C --> D[Graph API]
```

启动命令：
```bash
node dist/index.js
```

### HTTP 模式

适用于 Azure Container Apps 等云部署：

```mermaid
graph LR
    A[MCP 客户端] -->|HTTPS + JWT| B[HTTP 服务器]
    B --> C[Token 验证<br/>token-validator.ts]
    C --> D[MSAL 认证]
    D --> E[Graph API]
```

启动命令：
```bash
node dist/index.js --http --port 3000 --jwt-secret <secret>
```

资料来源：[src/server.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/server.ts)

---

## 代码生成流程

### OpenAPI 规范生成工具

```mermaid
graph TD
    A[Microsoft Graph<br/>OpenAPI Spec] --> B[bin/generate-mcp-tools.mjs]
    B --> C[解析端点元数据]
    C --> D[生成 Zod 验证模式]
    D --> E[输出到 src/generated/]
    E --> F[类型安全的工具定义]
```

生成命令：
```bash
npm run generate
```

生成的代码位于 `src/generated/` 目录，**请勿手动编辑**，所有修改应在 `src/endpoints.json` 中进行后重新生成。

资料来源：[CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

---

## Graph 客户端架构

### 请求执行流程

```mermaid
sequenceDiagram
    participant Tool as MCP 工具调用
    participant GC as GraphClient
    participant Auth as MSAL Auth
    participant Graph as Graph API

    Tool->>GC: executeGraphTool(tool, params)
    GC->>GC: 构建请求 URL
    GC->>Auth: 获取访问令牌
    Auth-->>GC: accessToken
    GC->>Graph: HTTP 请求 (Bearer token)
    Graph-->>GC: JSON 响应
    GC->>GC: Zod 验证响应
    GC-->>Tool: 结构化结果
    
    Note over GC: 错误处理：<br/>401 → 刷新令牌重试<br/>429 → 指数退避重试<br/>5xx → 返回错误
```

### 请求参数处理

| 参数类型 | 处理方式 | 说明 |
|---------|---------|------|
| 路径参数 | URL 模板替换 | `/{user-id}/...` → `/{实际ID}/...` |
| 查询参数 | $filter, $select 等 | 自动编码，支持 OData |
| 请求体 | POST/PATCH | Zod 验证后 JSON 序列化 |

资料来源：[src/graph-client.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/graph-client.ts)

---

## 项目结构总览

```
ms-365-admin-mcp-server/
├── bin/                           # 代码生成脚本
│   └── modules/
│       └── generate-mcp-tools.mjs # OpenAPI → Zod 生成器
├── src/                           # 核心源代码
│   ├── auth.ts                    # MSAL 认证模块
│   ├── auth-bootstrap.ts          # RFC 8628 设备码引导
│   ├── cli.ts                     # Commander CLI 参数解析
│   ├── cloud-config.ts            # 云配置（全球/世纪互联）
│   ├── endpoints.json             # 工具定义唯一数据源
│   ├── generated/                 # 自动生成的 Zod 客户端
│   ├── graph-client.ts            # Graph API HTTP 封装
│   ├── graph-tools.ts             # MCP 工具注册
│   ├── http-server.ts             # HTTP 传输服务器
│   ├── index.ts                   # 应用入口
│   ├── logger.ts                  # Winston 日志
│   ├── risk-level.ts              # 风险等级系统
│   ├── secrets.ts                 # 密钥提供器（env/Key Vault）
│   ├── server.ts                  # STDIO 服务器
│   ├── token-validator.ts         # JWT 验证
│   └── tool-categories.ts         # 预设分类定义
├── infra/                         # 基础设施代码
│   └── main.bicep                 # Azure Container Apps 部署
├── test/                          # Vitest 测试
├── docs/                          # 文档
│   ├── ARCHITECTURE.md
│   ├── RISK_MODEL.md
│   └── USE_CASES.md
├── CONTRIBUTING.md
├── SECURITY.md
└── package.json
```

资料来源：[CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

---

## 安全考量

### 权限最小化原则

新工具必须声明最小 Graph API 权限：

| 场景 | 推荐权限 | 禁止权限 |
|------|---------|---------|
| 仅读取用户 | `User.Read.All` | `User.ReadWrite.All` |
| 仅读取组 | `Group.Read.All` | `Group.ReadWrite.All` |
| 目录读取 | `Directory.Read.All` | `Directory.ReadWrite.All` |

### 关键风险操作

以下操作被分类为 `critical`，需要 MCP 客户端显式授权（`--allow-writes`）：

- `delete-user` - 删除用户（不可逆）
- `delete-group` - 删除组
- `delete-application` - 删除应用注册
- `delete-conditional-access-policy` - 删除条件访问策略
- `wipe-managed-device` - 远程擦除设备

资料来源：[agent-skills/ms365-admin-mcp/references/tools-catalog.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/tools-catalog.md)

---

## 部署架构

### Azure Container Apps 部署

```mermaid
graph TD
    subgraph Azure
        A[客户端] -->|HTTPS| B[Azure Container Apps]
        B --> C[ms-365-admin-mcp-server<br/>容器实例]
        C --> D[Azure Key Vault<br/>密钥存储]
        D --> E[Microsoft Graph API]
    end

    subgraph 认证流程
        F[Azure AD App Registration] -->|CLIENT_ID/SECRET| C
    end
```

环境变量配置：

```bash
MS365_ADMIN_MCP_CLIENT_ID=<Azure AD 应用 ID>
MS365_ADMIN_MCP_CLIENT_SECRET=<客户端密钥>
MS365_ADMIN_MCP_TENANT_ID=<租户 ID>
```

部署模板：`infra/main.bicep`

资料来源：[CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

---

<a id='page-transports'></a>

## 通信传输层

### 相关页面

相关主题：[系统架构](#page-architecture), [部署指南](#page-deployment)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/http-server.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/http-server.ts)
- [src/index.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/index.ts)
- [src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)
- [src/auth-bootstrap.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth-bootstrap.ts)
- [src/cli.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cli.ts)
- [src/upstream-error.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/upstream-error.ts)
- [docs/HTTP_DEPLOYMENT.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/HTTP_DEPLOYMENT.md)
- [docs/TROUBLESHOOTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/TROUBLESHOOTING.md)
- [CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)
</details>

# 通信传输层

本文档详细介绍 ms-365-admin-mcp-server 项目中的通信传输层架构，涵盖客户端认证、HTTP 服务器部署、令牌管理以及远程调用的完整流程。

## 概述

ms-365-admin-mcp-server 的通信传输层是连接 MCP 客户端（如 Claude Desktop/Code）与 Microsoft Graph API 的核心组件。该层负责处理 OAuth 2.0 身份认证、HTTP 服务器托管、MCP 协议通信以及令牌缓存等关键功能。

项目的通信架构支持两种主要运行模式：

| 运行模式 | 描述 | 适用场景 |
|---------|------|---------|
| **本地模式** | 直接在本地运行 MCP 服务器，通过标准输入/输出与客户端通信 | 开发调试、本地使用 |
| **远程 HTTP 模式** | 通过 HTTP 服务器托管，支持远程客户端访问 | 生产部署、多用户环境 |

资料来源：[CONTRIBUTING.md:35-45]()

## 架构组件

### 核心模块职责

```
┌─────────────────────────────────────────────────────────────────┐
│                      MCP 客户端 (Claude)                         │
└─────────────────────────────┬───────────────────────────────────┘
                              │ HTTP / stdio
┌─────────────────────────────▼───────────────────────────────────┐
│                      通信传输层                                   │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────────────┐  │
│  │ http-server │  │ auth-bootstrap│  │ auth (MSAL)            │  │
│  └─────────────┘  └──────────────┘  └─────────────────────────┘  │
└─────────────────────────────┬───────────────────────────────────┘
                              │ HTTPS
┌─────────────────────────────▼───────────────────────────────────┐
│                    Microsoft Graph API                           │
└─────────────────────────────────────────────────────────────────┘
```

| 模块 | 文件 | 主要职责 |
|------|------|---------|
| HTTP 服务器 | `src/http-server.ts` | 托管 MCP 端点、处理请求路由 |
| 认证引导 | `src/auth-bootstrap.ts` | RFC 8628 device_code 流程初始化 |
| MSAL 认证 | `src/auth.ts` | Microsoft 身份平台客户端凭证流 |
| CLI 入口 | `src/cli.ts` | 命令行参数解析、模式切换 |
| 错误处理 | `src/upstream-error.ts` | 上游 API 错误规范化 |

资料来源：[src/http-server.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/http-server.ts)、[src/auth-bootstrap.ts:45-60]()

## HTTP 服务器部署

### 部署方式

项目支持多种 HTTP 服务器部署配置，主要通过环境变量和命令行参数进行控制。

#### 环境变量配置

| 环境变量 | 描述 | 默认值 |
|---------|------|--------|
| `MS365_ADMIN_MCP_CLIENT_ID` | Azure AD 应用注册客户端 ID | 必需 |
| `MS365_ADMIN_MCP_CLIENT_SECRET` | Azure AD 应用注册客户端密钥 | 必需 |
| `MS365_ADMIN_MCP_TENANT_ID` | Azure AD 租户 ID | 必需 |
| `MCP_REMOTE_CONFIG_DIR` | 远程配置目录路径 | `~/.mcp-auth/mcp-remote-<version>/` |
| `CI` | 是否在 CI 环境运行 | `false` |

资料来源：[CONTRIBUTING.md:30-40]()

#### 命令行参数

```bash
node dist/index.js --preset <preset-name> --list-tools
node dist/index.js --preset <preset-name> --list-permissions
npm run inspector
```

| 参数 | 描述 |
|------|------|
| `--preset <name>` | 指定工具预设类别 |
| `--list-tools` | 列出所有可用工具 |
| `--list-permissions` | 列出所需 Graph API 权限 |
| `--inspector` | 使用 MCP Inspector 交互式运行 |

资料来源：[src/cli.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cli.ts)

### MCP Inspector 交互模式

开发调试阶段可以使用 MCP Inspector 进行交互式测试：

```bash
npm run inspector
```

该命令启动交互式调试服务器，便于验证工具注册、权限配置以及请求路由是否正常工作。

资料来源：[CONTRIBUTING.md:43]()

## 认证机制

### MSAL 客户端凭证流

`src/auth.ts` 模块实现了 Microsoft 身份库 (MSAL) 的客户端凭证流，用于服务器到服务器的认证场景。

```typescript
// 核心认证流程伪代码
const clientCredentialFlow = new ClientCredentialFlow({
  clientId: process.env.MS365_ADMIN_MCP_CLIENT_ID,
  clientSecret: process.env.MS365_ADMIN_MCP_CLIENT_SECRET,
  tenantId: process.env.MS365_ADMIN_MCP_TENANT_ID,
});
```

此认证方式适用于后台服务场景，不需要用户交互即可获取访问令牌。

资料来源：[src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)

### RFC 8628 Device Code 引导流程

`src/auth-bootstrap.ts` 实现了 RFC 8628 定义的 device_code 认证流程，专门用于为远程 MCP 客户端预先填充令牌缓存。

#### 核心流程

```
┌──────────────┐     ┌───────────────┐     ┌──────────────────┐
│ CLI 工具     │────▶│ OAuth 服务器  │────▶│ 用户设备/浏览器  │
│ (auth-bootstrap)│   │ (/authorize) │     │ (验证页面)       │
└──────┬───────┘     └───────────────┘     └──────────────────┘
       │                                           │
       │ 轮询 /token                               │
       │◀──────────────────────────────────────────┤
       │                                           │
       ▼                                           │
┌──────────────┐                                   │
│ 缓存令牌     │                                   │
│ _tokens.json│                                   │
│ _client_info│                                   │
└──────────────┘                                   │
```

#### 功能特性

- **缓存键计算**：`md5(serverUrl)`，与 `mcp-remote` 的 `getServerUrlHash` 完全匹配，确保缓存正确关联
- **缓存路径**：`~/.mcp-auth/mcp-remote-<version>/`
- **文件权限**：0600（仅所有者读写），保护敏感凭证
- **剪贴板支持**：自动复制设备代码到剪贴板（`pbcopy`/`clip`/`wl-copy`/`xclip`），CI 或非 TTY 环境自动禁用

资料来源：[src/auth-bootstrap.ts:60-75]()

#### 命令行用法

```bash
ms-365-admin-mcp-auth -s <MCP服务器URL> [--scope <范围>] [--cache-dir <路径>]
```

| 选项 | 描述 |
|------|------|
| `-s, --server <url>` | MCP 服务器 URL（必需），支持带或不带 `/mcp` 后缀 |
| `--scope <scope>` | 覆盖默认 OAuth 范围（默认使用服务器元数据） |
| `--cache-dir <path>` | 覆盖缓存目录路径 |

#### 退出码

| 退出码 | 含义 |
|-------|------|
| 0 | 认证成功 |
| 1 | 用法错误 |
| 2 | 网络错误 |
| 3 | 认证被拒绝 |
| 4 | 超时 |

资料来源：[src/auth-bootstrap.ts:20-35]()

### 令牌缓存机制

认证引导工具生成的缓存文件包含两个关键文件：

| 文件 | 用途 |
|------|------|
| `<hash>_client_info.json` | OAuth 客户端信息 |
| `<hash>_tokens.json` | 访问令牌和刷新令牌 |

缓存键采用 MD5 哈希算法，直接对应服务器 URL，确保多服务器部署场景下缓存隔离。

资料来源：[src/auth-bootstrap.ts:68-70]()

## 远程 HTTP 服务器架构

### 请求处理流程

```
                    ┌─────────────────────────────────┐
                    │        HTTP 请求入口             │
                    │  (Azure Container Apps / VPS)   │
                    └───────────────┬─────────────────┘
                                    │
                    ┌───────────────▼─────────────────┐
                    │      请求路由与中间件            │
                    │  - 认证验证                      │
                    │  - 协议解析                      │
                    └───────────────┬─────────────────┘
                                    │
          ┌─────────────────────────┼─────────────────────────┐
          │                         │                         │
┌─────────▼─────────┐   ┌──────────▼──────────┐   ┌────────▼────────┐
│   MCP 协议处理器   │   │   工具注册表        │   │   Graph API    │
│  (method routing) │──▶│  (endpoints.json)   │──▶│    客户端       │
└───────────────────┘   └─────────────────────┘   └─────────────────┘
```

### 云端部署注意事项

根据 `docs/TROUBLESHOOTING.md` 文档，远程 HTTP 部署需要考虑以下因素：

| 注意事项 | 说明 |
|---------|------|
| **平台 SSO** | Azure AD 条件访问可能触发平台 SSO，导致 device_code 流程复杂化 |
| **条件访问策略** | 需要确保部署的 MCP 服务器被条件访问策略允许 |
| **Docker 挂载** | 使用 `--cache-dir` 和 `MCP_REMOTE_CONFIG_DIR` 环境变量支持 Docker 卷挂载 |
| **多用户场景** | 不同用户需配置独立的缓存目录 |

资料来源：[docs/TROUBLESHOOTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/TROUBLESHOOTING.md)

### 认证流程对比

#### 本地模式（标准输入/输出）

```
Claude Desktop ──▶ stdio ──▶ MCP Server ──▶ Graph API
```

- 直接进程间通信
- 无需网络配置
- 适用于单用户场景

#### 远程模式（HTTP 服务器）

```
Claude Desktop/Code ──▶ HTTPS ──▶ MCP Remote Proxy ──▶ MCP Server ──▶ Graph API
                                    │
                              device_code 认证
                              (预填充令牌缓存)
```

- 基于 HTTP 的远程调用
- 支持分布式部署
- 需要令牌缓存配置

资料来源：[docs/HTTP_DEPLOYMENT.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/HTTP_DEPLOYMENT.md)

## 错误处理

### 上游错误规范化

`src/upstream-error.ts` 模块负责解析和规范化来自 Microsoft Graph API 的错误响应。

#### 错误代码提取

```typescript
// 从 OAuth 错误响应中提取 error_codes
if (parsed.error_codes && Array.isArray(parsed.error_codes)) {
  const codes = parsed.error_codes
    .filter((c) => typeof c === 'number')
    .slice(0, 5);
  if (codes.length > 0) {
    parts.push(`error_codes=[${codes.join(',')}]`);
  }
}
```

#### 错误格式化

| 场景 | 输出格式 |
|------|---------|
| 可解析的错误 | `error=X error_description=Y error_codes=[...]` |
| 不可解析响应 | `<unparseable N bytes>` |
| 无可识别字段 | `<no recognise oauth error fields>` |

资料来源：[src/upstream-error.ts:10-25]()

### 认证错误分类

| 错误类型 | 处理方式 |
|---------|---------|
| 网络错误 | 退出码 2，可重试 |
| 认证拒绝 | 退出码 3，检查权限配置 |
| 超时 | 退出码 4，增加超时配置 |

## 安全性考虑

### 令牌存储安全

| 安全措施 | 实现 |
|---------|------|
| 文件权限 | 0600，仅进程所有者可访问 |
| 缓存隔离 | MD5 URL 哈希确保不同服务器缓存分离 |
| 环境变量 | 敏感信息通过环境变量注入，避免硬编码 |

资料来源：[src/auth-bootstrap.ts:70]()

### 最小权限原则

新增工具必须声明最小 Graph API 权限，禁止请求 `.ReadWrite.All` 当 `.Read.All` 即可满足需求。

资料来源：[CONTRIBUTING.md:18-20]()

## 配置示例

### 本地开发配置

```bash
# .env 文件
MS365_ADMIN_MCP_CLIENT_ID=your-client-id
MS365_ADMIN_MCP_CLIENT_SECRET=your-client-secret
MS365_ADMIN_MCP_TENANT_ID=your-tenant-id
```

### Docker 部署配置

```bash
docker run -e MS365_ADMIN_MCP_CLIENT_ID=xxx \
           -e MS365_ADMIN_MCP_CLIENT_SECRET=xxx \
           -e MS365_ADMIN_MCP_TENANT_ID=xxx \
           -e MCP_REMOTE_CONFIG_DIR=/data/mcp-cache \
           -v /path/to/cache:/data/mcp-cache \
           ghcr.io/okapi-ca/ms-365-admin-mcp-server
```

### Device Code 认证

```bash
ms-365-admin-mcp-auth -s https://your-host.azurecontainerapps.io/mcp \
                      --cache-dir /data/mcp-cache
```

## 故障排查

| 问题 | 可能原因 | 解决方案 |
|------|---------|---------|
| `Server disconnected` | 网络连接问题或服务器未运行 | 检查服务器状态和网络连通性 |
| 设备代码流程超时 | 用户未在规定时间内完成认证 | 使用较长的超时时间或重新发起流程 |
| 条件访问阻止 | 平台 SSO 或 CA 策略限制 | 检查并配置条件访问策略 |
| 缓存权限错误 | Docker 卷挂载权限问题 | 确保挂载目录权限正确 |

资料来源：[docs/TROUBLESHOOTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/TROUBLESHOOTING.md)

## 相关文档

| 文档 | 位置 | 内容 |
|------|------|------|
| HTTP 部署指南 | `docs/HTTP_DEPLOYMENT.md` | 远程服务器部署详细说明 |
| 故障排查指南 | `docs/TROUBLESHOOTING.md` | 常见问题与解决方案 |
| 贡献指南 | `CONTRIBUTING.md` | 开发设置与代码规范 |
| 安全模型 | `docs/RISK_MODEL.md` | 风险分级与安全要求 |

---

<a id='page-authentication'></a>

## 认证系统

### 相关页面

相关主题：[授权机制](#page-authorization), [系统架构](#page-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)
- [src/oauth-proxy.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/oauth-proxy.ts)
- [src/token-validator.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/token-validator.ts)
- [src/jwks-stale-cache.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/jwks-stale-cache.ts)
- [src/secrets.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/secrets.ts)
- [src/http-server.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/http-server.ts)
- [src/auth-bootstrap.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth-bootstrap.ts)
</details>

# 认证系统

## 概述

ms-365-admin-mcp-server 的认证系统负责保护 MCP 服务器的访问安全，支持两种主要的认证模式：

1. **服务令牌模式（Service Token Mode）**：使用客户端 ID 和客户端密钥进行身份验证，适用于服务到服务的通信
2. **OAuth 2.0 代理模式（OAuth Mode）**：通过 Microsoft Entra ID 实现用户身份验证，支持 Claude Desktop、Claude Code 和 Claude.ai Web 等客户端的 OAuth 授权流程

该认证系统的核心目标是确保只有经过授权的用户和服务才能调用 Microsoft Graph API 执行租户管理操作。

## 架构概览

```mermaid
graph TD
    subgraph "客户端层"
        A[Claude Desktop]
        B[Claude Code]
        C[Claude.ai Web]
        D[第三方 MCP 客户端]
    end
    
    subgraph "认证层"
        E[MCP 认证中间件]
        F[OAuth 代理]
        G[令牌验证器]
        H[JWKS 缓存]
    end
    
    subgraph "Microsoft Entra ID"
        I[令牌颁发]
        J[JWKS 端点]
    end
    
    subgraph "资源层"
        K[Graph API]
        L[MCP 工具]
    end
    
    A --> E
    B --> E
    C --> F
    D --> E
    D --> F
    
    E --> G
    F --> I
    G --> H
    H --> J
    
    E --> L
    G --> K
    F --> K
```

## 核心组件

### 1. 认证模块（src/auth.ts）

认证模块实现了 MSAL（Microsoft Authentication Library）的客户端凭据流，用于获取访问 Microsoft Graph API 的应用程序级令牌。

| 功能 | 说明 |
|------|------|
| 客户端凭据流 | 使用应用 ID 和证书/密钥获取应用级访问令牌 |
| 云配置支持 | 支持全球云和世纪互联（21Vianet）中国区云端点 |
| 令牌缓存 | 内置令牌缓存机制，避免频繁请求新令牌 |

### 2. OAuth 代理（src/oauth-proxy.ts）

OAuth 代理实现了完整的 OAuth 2.0 + PKCE 授权代码流程，使 Claude 客户端能够通过 Microsoft Entra ID 进行身份验证。

```mermaid
sequenceDiagram
    participant Client as Claude 客户端
    participant Proxy as OAuth 代理
    participant Entra as Microsoft Entra ID
    participant Graph as Graph API

    Client->>Proxy: GET /.well-known/oauth-authorization-server
    Proxy->>Client: 返回元数据
    
    Client->>Proxy: GET /authorize?response_type=code&...
    Proxy->>Entra: 重定向到 Entra 授权端点
    Entra->>User: 显示登录页面
    User->>Entra: 完成身份验证
    Entra->>Proxy: 重定向回 /callback?code=xxx
    
    Client->>Proxy: POST /token (authorization_code)
    Proxy->>Entra: 使用 code 兑换令牌
    Entra->>Proxy: 返回 access_token, refresh_token
    
    Proxy->>Client: 返回令牌
    
    Client->>Proxy: GET /mcp (Bearer token)
    Proxy->>Graph: 使用 access_token 调用 API
    Graph->>Proxy: 返回数据
    Proxy->>Client: 返回结果
```

#### OAuth 代理端点

| 端点 | 方法 | 功能 |
|------|------|------|
| `/.well-known/oauth-authorization-server` | GET | 返回 OAuth 2.0 服务器元数据 |
| `/.well-known/oauth-protected-resource` | GET | 返回受保护资源元数据（用于客户端发现）|
| `/authorize` | GET | 授权端点，启动 PKCE 流程 |
| `/callback` | GET | 授权回调处理 |
| `/token` | POST | 令牌颁发端点 |
| `/client/register` | POST | 动态客户端注册（DCR） |

### 3. 令牌验证器（src/token-validator.ts）

令牌验证器负责验证 HTTP 传输模式下传入的 Bearer 令牌，确保令牌的有效性和合法性。

| 验证项目 | 说明 |
|----------|------|
| JWT 签名验证 | 使用 JWKS 端点获取公钥验证 JWT 签名 |
| 颁发者验证 | 确认令牌由预期的 Entra 租户颁发 |
| 受众验证 | 确认令牌适用于此应用（`aud` 声明）|
| 租户验证 | 确认令牌来自授权的租户（`tid` 声明）|
| 用户范围验证 | 确认令牌包含必需的 `scp` 声明（默认 `access_as_user`）|

验证失败时的日志记录包括违规的 `aud`、`tid` 和 `upn` 信息，便于排查问题。

### 4. JWKS 缓存（src/jwks-stale-cache.ts）

为了提高性能和减少网络请求，令牌验证器使用 JWKS 缓存来存储和重用公钥信息。

| 特性 | 说明 |
|------|------|
| 内存缓存 | 将 JWKS 数据缓存在内存中 |
| 过期策略 | 支持配置缓存过期时间 |
| 后台刷新 | 令牌验证前自动刷新过期缓存 |
| 错误处理 | 缓存过期时优雅降级 |

### 5. 密钥管理（src/secrets.ts）

密钥管理模块负责从多种来源获取敏感配置信息：

| 来源 | 优先级 | 说明 |
|------|--------|------|
| 环境变量 | 最高 | 直接从 `process.env` 读取 |
| Azure Key Vault | 次高 | 从 Key Vault 获取存储的密钥 |
| 默认值 | 最低 | 使用编译时默认值 |

支持的密钥类型：
- `AZURE_CLIENT_ID`：应用（客户端）ID
- `AZURE_CLIENT_SECRET`：客户端密钥
- `AZURE_TENANT_ID`：租户 ID

### 6. HTTP 服务器认证中间件（src/http-server.ts）

HTTP 服务器实现了 `/mcp` 端点的 Bearer 令牌验证中间件，遵循 RFC 6750 标准。

```mermaid
flowchart LR
    A[收到 /mcp 请求] --> B{Authorization Header}
    
    B -->|无或非 Bearer| C[返回 401<br/>WWW-Authenticate Header]
    B -->|有 Bearer| D[提取令牌]
    
    D --> E{令牌类型}
    
    E -->|用户令牌| F[用户令牌验证器]
    E -->|服务令牌| G[服务令牌验证器]
    
    F -->|通过| H[允许访问]
    F -->|失败| I{原因}
    I -->|无授权用户| J[返回 403]
    I -->|其他| K[返回 401]
    
    G -->|通过| H
    G -->|失败| L[返回 403]
    
    H --> M[处理 MCP 请求]
```

#### WWW-Authenticate 响应头

| 场景 | 状态码 | WWW-Authenticate Header |
|------|--------|------------------------|
| 缺少令牌 | 401 | `Bearer resource_metadata="..."` |
| 令牌验证失败 | 403 | `Bearer resource_metadata="...", error="invalid_token"` |

### 7. 认证引导工具（src/auth-bootstrap.ts）

认证引导工具实现了 RFC 8628 设备代码流，用于在 CLI 环境中自动化 OAuth 认证过程。

| 功能 | 说明 |
|------|------|
| 设备代码获取 | 从服务器获取设备代码和用户验证码 |
| PKCE 支持 | 自动生成 code_verifier 和 code_challenge |
| 令牌缓存 | 将客户端信息和令牌保存到本地文件 |
| 缓存目录 | 默认 `$MCP_REMOTE_CONFIG_DIR/mcp-remote-<version>` |

## 认证流程

### 服务令牌模式

```mermaid
graph LR
    A[客户端] -->|携带 Bearer Token| B[MCP 中间件]
    B --> C[令牌验证器]
    C -->|验证 JWT 签名| D[JWKS 缓存]
    D -->|返回公钥| C
    C -->|验证声明| E{验证结果}
    E -->|通过| F[Graph API 调用]
    E -->|失败| G[返回 401/403]
```

### OAuth 模式

```mermaid
graph TD
    A[Claude Desktop 启动] -->|无缓存令牌| B[发起设备代码流]
    B --> C[auth-bootstrap 获取设备代码]
    C --> D[用户完成浏览器认证]
    D --> E[缓存令牌到本地]
    E --> F[MCP 连接携带缓存令牌]
    F --> G[OAuth 代理验证令牌]
    G -->|有效| H[允许 Graph API 调用]
    G -->|无效/过期| I[使用 refresh_token 刷新]
    I -->|刷新成功| H
    I -->|刷新失败| J[提示重新认证]
```

## 安全配置

### 启动参数

| 参数 | 说明 | 默认值 | 安全性 |
|------|------|--------|--------|
| `--allowed-clients` | 允许的服务客户端 ID 列表 | 必需（无默认）| P1 |
| `--oauth-mode` | 启用 OAuth 2.0 代理模式 | false | P1 |
| `--authorized-users` | OAuth 模式下允许的用户 OID 列表 | 必需（无默认值）| P1 |
| `--allow-any-tenant-user` | 允许任意租户用户（需明确启用）| false | P1 |
| `--public-url` | OAuth 模式的公共 URL | 必需（behind proxy 时）| P1 |
| `--required-user-scopes` | 用户令牌必需的 scope | `access_as_user` | P1 |
| `--client-secret` | 服务客户端密钥 | 从环境变量获取 | P2 |
| `--trusted-ip-headers` | 信任的 IP 来源头 | 无 | P2 |

### 安全修复记录

| 标识 | 描述 | 版本 | 严重性 |
|------|------|------|--------|
| SEC-F01 | OAuth 模式在空用户白名单时失败关闭 | 0.2.0 | P1 |
| SEC-F02 | `--public-url` 对 OAuth 模式为必需项 | 0.2.0 | P1 |
| SEC-F03 | 新增 `--required-user-scopes` 强制验证 scope 声明 | 0.2.3 | P1 |
| SEC-F04 | `/token` 端点速率限制：10 req/min/IP | 0.2.3 | P1 |
| SEC-F05 | PKCE 桥接内存化，降低多副本部署风险 | 0.2.3 | P1 |

## 部署注意事项

### OAuth 模式部署

OAuth 模式部署需要满足以下条件：

1. **Entra 应用注册配置**：
   - 公开暴露 `access_as_user` 委托 scope（`api://<client-id>/access_as_user`）
   - 配置 `requestedAccessTokenVersion: 2`
   - 授予管理员同意

2. **网络配置**：
   - 必须设置 `--public-url`（反向代理后必需）
   - 配置 `trust proxy` 设置（如适用）

3. **多副本部署**：
   - 由于 PKCE 桥接内存化特性，默认单副本部署
   - 多副本部署需显式设置 `maxReplicas` 并考虑外部化 PKCE 桥接

### 从旧版本迁移

| 场景 | 操作 |
|------|------|
| 使用 OAuth 模式且依赖"任意认证用户"行为 | 添加 `--allow-any-tenant-user` |
| OAuth 模式部署在反向代理后 | 添加 `--public-url https://<fqdn>` |
| Entra 应用未暴露 `access_as_user` scope | 添加 `--required-user-scopes ""` |
| Bicep 部署依赖默认 `maxReplicas = 3` | 显式设置 `maxReplicas` |

## 相关文件

| 文件 | 职责 |
|------|------|
| `src/auth.ts` | MSAL 客户端凭据流实现 |
| `src/oauth-proxy.ts` | OAuth 2.0 授权代码流代理 |
| `src/token-validator.ts` | JWT 令牌验证 |
| `src/jwks-stale-cache.ts` | JWKS 密钥缓存管理 |
| `src/secrets.ts` | 密钥和环境变量管理 |
| `src/http-server.ts` | HTTP 传输和认证中间件 |
| `src/auth-bootstrap.ts` | RFC 8628 设备代码引导 |
| `infra/main.bicep` | Azure Container Apps 部署配置 |

---

<a id='page-authorization'></a>

## 授权机制

### 相关页面

相关主题：[认证系统](#page-authentication), [风险模型](#page-risk-model)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/user-token-authorization.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/user-token-authorization.ts)
- [src/user-token-validator.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/user-token-validator.ts)
- [src/auth-bootstrap.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth-bootstrap.ts)
- [src/oauth-proxy.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/oauth-proxy.ts)
- [src/oauth-rate-limiters.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/oauth-rate-limiters.ts)
- [src/cli.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cli.ts)
</details>

# 授权机制

## 概述

ms-365-admin-mcp-server 的授权机制采用分层设计，支持两种主要的认证模式：**OAuth 2.0 代理模式**和**服务令牌模式**。系统通过用户令牌授权模块验证调用者身份，并结合速率限制和范围检查确保安全性。

授权机制的核心职责包括：
- 验证用户令牌的签名、颁发者和范围
- 实施基于允许列表的访问控制
- 提供细粒度的范围（scope）验证
- 支持 Entra ID（Azure AD）集成的 OAuth 2.0 流程

## 架构总览

```mermaid
graph TD
    A[HTTP 请求] --> B[/mcp 认证中间件]
    B --> C{OAuth 模式启用?}
    C -->|是| D[用户令牌验证]
    C -->|否| E{允许客户端模式?}
    E -->|是| F[服务令牌验证]
    E -->|否| G[返回 403]
    
    D --> H{令牌有效?}
    D --> I{在授权用户列表?}
    D --> J{范围满足?}
    
    H -->|否| K[返回 invalid_token / 401]
    I -->|否| L[返回 unauthorized / 403]
    J -->|否| M[返回 insufficient_scope / 403]
    
    H -->|是| I
    I -->|是| J
    J -->|是| N[提取 claims<br/>oid, upn, name, appid]
    
    F --> O[验证服务令牌签名]
    O -->|成功| P[允许访问]
    
    N --> P
```

## 用户令牌授权

### 核心验证流程

用户令牌授权模块（`src/user-token-authorization.ts`）负责验证通过 OAuth 2.0 流程获取的用户令牌。验证过程遵循以下步骤：

1. **签名验证** — 验证 JWT 签名来自可信的 JWKS 端点
2. **声明验证** — 检查 `aud`（受众）、`tid`（租户 ID）等关键声明
3. **用户白名单检查** — 验证 `upn` 是否在授权用户列表中
4. **范围验证** — 确认令牌包含所需的 OAuth 范围

### 关键函数

```typescript
export function authorizeUserClaims(
  payload: UserTokenPayload,
  options: UserTokenValidatorOptions
): UserTokenAuthorizationResult
```

**参数说明：**

| 参数 | 类型 | 说明 |
|------|------|------|
| `payload` | `UserTokenPayload` | 解码后的 JWT 载荷 |
| `options.requiredScopes` | `string[]` | 必需的 OAuth 范围列表 |
| `options.authorizedUsers` | `string[]` | 授权用户 UPN 列表 |
| `options.requiredAudiences` | `string[]` | 必需的受众声明 |
| `options.requiredTenantId` | `string` | 必需的租户 ID |

**返回值：**

| 字段 | 说明 |
|------|------|
| `ok: true` | 授权成功，返回包含 `claims` 的对象 |
| `ok: false` | 授权失败，`reason` 指示失败原因 |

### 失败原因与 HTTP 状态码

| 失败原因 | HTTP 状态 | 说明 |
|----------|-----------|------|
| `invalid_token` | 401 | 令牌格式错误或签名验证失败 |
| `insufficient_scope` | 403 | 令牌缺少必需的范围 |
| `unauthorized_user` | 403 | 用户不在授权列表中 |

```typescript
// 资料来源：src/user-token-authorization.ts:46-52
if (missing.length > 0) {
  logger.warn(
    `User token missing required scope(s): ${missing.join(', ')}; token scp=${payload.scp ?? '<none>'}`
  );
  return { ok: false, reason: 'insufficient_scope' };
}
```

### 范围解析逻辑

系统通过 `parseTokenScopes` 函数解析令牌中的 `scp` 声明，并与必需范围进行比对：

```mermaid
graph LR
    A[scp 声明] --> B{解析范围列表}
    B --> C[requiredScopes]
    C --> D[过滤出不匹配项]
    D --> E{missing.length > 0?}
    E -->|是| F[返回 insufficient_scope]
    E -->|否| G[授权通过]
```

## OAuth 2.0 代理模式

### 概述

当服务器以 `--oauth-mode` 运行时，启用 OAuth 2.0 代理功能。用户通过 Entra ID 进行身份验证后，服务器代理令牌交换和验证流程。

### 端点列表

| 端点 | 方法 | 说明 |
|------|------|------|
| `/.well-known/oauth-authorization-server` | GET | OAuth 发现文档 |
| `/.well-known/oauth-protected-resource` | GET | 受保护资源元数据 |
| `/authorize` | GET | 授权请求入口 |
| `/token` | POST | 令牌交换 |
| `/devicecode` | POST | 设备代码流 |

### 授权流程

```mermaid
sequenceDiagram
    participant U as 用户
    participant S as MCP Server
    participant E as Entra ID
    
    U->>S: 访问 MCP 端点 (无令牌)
    S->>U: 返回 401 + WWW-Authenticate
    U->>S: GET /authorize
    S->>E: 重定向到 Entra ID<br/>client_id, redirect_uri, scope
    E->>U: 登录页面
    U->>E: 完成身份验证 + MFA
    E->>S: redirect_uri + auth_code
    S->>E: POST /token<br/>client_id, client_secret, code
    E->>S: access_token, refresh_token
    S->>U: 返回令牌给客户端
```

### 客户端认证

OAuth 代理在 `/token` 端点强制要求客户端凭证：

```typescript
// 资料来源：src/oauth-proxy.ts:85-100
const { clientId: reqClientId, clientSecret: reqClientSecret } = extractClientCredentials(req);
if (!reqClientId || !reqClientSecret) {
  res.status(401).json({
    error: 'invalid_client',
    error_description: 'Missing client_id or client_secret',
  });
  return;
}
```

| 字段 | 说明 |
|------|------|
| `client_id` | 注册的 OAuth 应用客户端 ID |
| `client_secret` | 对应的客户端密钥 |

### 设备代码引导

对于无浏览器环境，服务器提供 RFC 8628 设备代码流程：

```bash
ms-365-admin-mcp-auth -s https://your-host.azurecontainerapps.io/mcp
```

**工作流程：**

1. 客户端向 `/devicecode` 请求设备代码
2. 服务器返回 `device_code` 和 `user_code`
3. 用户在另一设备访问 `verification_uri` 并输入 `user_code`
4. 轮询 `/token` 直到授权完成

```typescript
// 资料来源：src/auth-bootstrap.ts:60-80
const { verification_uri, user_code, device_code, interval, expires_in } = await getDeviceCode(
  serverUrl,
  clientId,
  scope
);
```

## 服务令牌模式

### 概述

当部署使用 `--allowed-clients` 参数时，系统接受预注册的服务令牌（如 MCP Remote 客户端令牌）。

### 认证中间件顺序

```mermaid
graph TD
    A[请求到达 /mcp] --> B{oauth-mode 启用?}
    B -->|是| C[尝试用户令牌验证]
    B -->|否| D{allowed-clients 启用?}
    
    C --> E{用户令牌验证成功?}
    E -->|是| F[允许访问]
    E -->|否| G{allowed-clients 启用?}
    
    D -->|是| H[尝试服务令牌验证]
    D -->|否| I[返回 403]
    
    H --> J{服务令牌验证成功?}
    J -->|是| F
    J -->|否| I
    G -->|是| H
    G -->|否| I
```

### 令牌缓存

用户令牌和客户端信息缓存到本地目录：

```bash
$MCP_REMOTE_CONFIG_DIR/mcp-remote-<version>/
├── client-info.json
└── tokens.json
```

缓存文件权限设置为 `0700`（目录）和 `0600`（文件），确保令牌安全存储。

## 速率限制

### 限制器配置

系统通过 `src/oauth-rate-limiters.ts` 为 OAuth 端点配置多层速率限制：

| 端点 | 限制器 | 窗口 | 最大请求 |
|------|--------|------|----------|
| `/token` (device_code) | `tokenDevicePollLimiter` | 1 分钟 | 10 次 |
| `/token` (其他) | `tokenTightLimiter` | 1 分钟 | 5 次 |
| `/register` | `tokenTightLimiter` | 1 分钟 | 5 次 |
| `/devicecode` | `tokenTightLimiter` | 1 分钟 | 5 次 |

### 设备代码轮询限制

设备代码轮询（polling）有特殊的速率限制，防止客户端过度请求：

```typescript
// 资料来源：src/oauth-rate-limiters.ts:25-35
const tokenDevicePollLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 10,
  standardHeaders: true,
  legacyHeaders: false,
  message: {
    error: 'invalid_request',
    error_description: 'Too many device_code poll requests',
  },
});
```

## CLI 配置选项

通过 `src/cli.ts` 暴露的启动参数控制授权行为：

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `--oauth-mode` | 启用 OAuth 2.0 代理模式 | `false` |
| `--allowed-clients` | 允许的服务客户端 ID 列表（逗号分隔） | 无 |
| `--public-url` | OAuth 模式下的公共 URL | 必需（OAuth 模式下） |
| `--required-user-scopes` | 必需的 OAuth 用户范围 | 必需（OAuth 模式下） |
| `--allow-any-tenant-user` | 允许任何已验证租户的用户 | `false` |

### 必需参数组合

```mermaid
graph TD
    A[启动参数检查] --> B{OAuth 模式?}
    B -->|是| C{提供 --public-url?}
    C -->|否| D[错误：需要 public-url]
    C -->|是| E{提供 --required-user-scopes?}
    E -->|否| F[使用默认值]
    E -->|是| G[使用指定范围]
    
    B -->|否| H{提供 --allowed-clients?}
    H -->|否| I[错误：需要 allowed-clients 或 oauth-mode]
    H -->|是| J[启动成功]
```

### 示例启动命令

```bash
# OAuth 模式（Claude Desktop 集成）
ms-365-admin-mcp-server --transport streamable-http \
  --oauth-mode \
  --public-url https://mcp.contoso.com \
  --required-user-scopes "access_as_user"

# 服务客户端模式
ms-365-admin-mcp-server --transport streamable-http \
  --allowed-clients "client-id-1,client-id-2"

# 混合模式
ms-365-admin-mcp-server --transport streamable-http \
  --oauth-mode \
  --allowed-clients "legacy-client-id" \
  --public-url https://mcp.contoso.com
```

## 安全考量

### 令牌验证原则

1. **签名验证优先** — 所有 JWT 必须通过 JWKS 验证签名
2. **范围最小化** — 仅接受明确声明的范围
3. **租户隔离** — 除非明确允许，否则仅接受同一租户的用户
4. **客户端认证** — OAuth 端点强制要求客户端凭证

### 日志记录

授权失败时，系统记录详细诊断信息：

```typescript
// 资料来源：src/user-token-authorization.ts:40-45
logger.warn(
  `User (${upnForLog}) not in authorized-users allowlist`
);
return { ok: false, reason: 'invalid_token' };
```

日志包含的信息：
- 用户主体名称（UPN）
- 缺失的范围列表
- 令牌受众（aud）和租户 ID（tid）

### 速率限制保护

- 防止设备代码轮询滥用
- 限制令牌注册请求频率
- 防止暴力破解客户端凭证

## 迁移指南

### 从旧版本升级

| 版本 | 变更 |
|------|------|
| 0.2.0+ | 新增 `--oauth-mode` 支持 |
| 0.2.4+ | 允许客户端参数变为可选（需要 `--oauth-mode` 或 `--allowed-clients`） |

### 常见配置错误

| 错误 | 解决方案 |
|------|----------|
| `ERR_MISSING_PUBLIC_URL` | 添加 `--public-url` 参数 |
| `ERR_MISSING_REQUIRED_SCOPES` | 添加 `--required-user-scopes` 参数 |
| `ERR_RATE_LIMIT_EXCEEDED` | 减少设备代码轮询频率 |

## 参考资料

- 授权核心实现：[src/user-token-authorization.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/user-token-authorization.ts)
- OAuth 代理：[src/oauth-proxy.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/oauth-proxy.ts)
- 设备代码引导：[src/auth-bootstrap.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth-bootstrap.ts)
- 速率限制：[src/oauth-rate-limiters.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/oauth-rate-limiters.ts)
- CLI 配置：[src/cli.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cli.ts)
- 安全审查文档：[docs/SECURITY_REVIEW_2026-04-20.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/SECURITY_REVIEW_2026-04-20.md)

---

<a id='page-tool-categories'></a>

## 工具分类系统

### 相关页面

相关主题：[核心功能特性](#page-features), [风险模型](#page-risk-model)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/tool-categories.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)
- [agent-skills/ms365-admin-mcp/SKILL.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/SKILL.md)
- [agent-skills/ms365-admin-mcp/references/tools-catalog.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/tools-catalog.md)
- [CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)
- [src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)
</details>

# 工具分类系统

## 概述

工具分类系统（Tool Categories System）是 ms-365-admin-mcp-server 项目中用于组织和管理 515 个 Microsoft Graph API 工具的核心组件。该系统通过正则表达式模式匹配将工具自动归类到不同的功能域，使管理员和 AI 代理能够根据业务场景快速定位所需工具。 资料来源：[agent-skills/ms365-admin-mcp/references/tools-catalog.md:1]()

### 核心设计目标

| 目标 | 说明 |
|------|------|
| **按领域组织** | 将 515 个工具按功能域（安全、身份、合规等）分组 |
| **模式匹配** | 使用正则表达式自动识别工具所属分类 |
| **预设管理** | 支持通过 `--preset` 参数动态加载相关工具集 |
| **风险分层** | 每个分类关联特定的风险级别，便于权限管控 |

## 架构设计

### 系统架构图

```mermaid
graph TD
    A[endpoints.json] --> B[工具注册表]
    B --> C{工具分类器}
    C --> D[TOOL_CATEGORIES]
    C --> E[CLI preset 参数]
    
    D --> F[security<br/>audit<br/>health<br/>reports]
    D --> G[identity<br/>governance<br/>response]
    D --> H[exchange<br/>intune<br/>ediscovery]
    D --> I[cloudpc<br/>callrecords<br/>print<br/>infoprotection<br/>sharepointadmin<br/>retention]
    
    E --> J[list-tools<br/>filter by pattern]
    
    F --> K[MCP Inspector<br/>动态加载]
    G --> K
    H --> K
    I --> K
```

### 核心接口定义

工具分类系统定义了一个简洁的接口，包含三个必需属性： 资料来源：[src/tool-categories.ts:1-5]()

```typescript
export interface ToolCategory {
  name: string;           // 分类唯一标识符
  pattern: RegExp;        // 匹配工具名称的正则表达式
  description: string;    // 人类可读的分类描述
}
```

## 分类清单

### 完整分类对照表

| 分类名称 | 模式关键词 | 描述 | 文档参考 |
|----------|------------|------|----------|
| `security` | security, alert, incident, attack-simulation, threat-intel | Microsoft 365 Defender 安全告警、事件、攻击模拟和威胁情报 | usecase-security.md |
| `audit` | audit, sign-in, provisioning, directory, deleted-user, deleted-group | 审计日志、目录审计、登录记录和已删除项目 | usecase-audit.md |
| `health` | service, health, issue, message | 服务健康状态和消息中心公告 | usecase-health.md |
| `reports` | report, activity, usage | Teams、邮箱、SharePoint、OneDrive、M365 应用使用报告 | usecase-reports.md |
| `identity` | user, group, role, conditional, directory, domain, auth-method, credential, application, service-principal, sp-password, sp-key, sp-token, sp-owner, oauth2, organization, named-location, device, administrative-unit, cross-tenant, pim, app-role, invitation, identity-provider, b2x, api-connector, custom-auth | Entra ID 用户、组、角色、设备、PIM、来宾用户、外部身份的身份和访问管理 | usecase-identity.md |
| `governance` | role-resource-namespace | 访问评审、权利管理、生命周期工作流、角色/组 PIM、使用条款、应用同意的身份治理 | usecase-governance.md |
| `response` | disable-user, revoke, block, reset, isolate, update-security, delete-user-auth, delete-user-phone, update-device, update-user-auth, confirm-compromised, dismiss-risky, confirm-safe, hunting-query, wipe-managed, retire-managed, remote-lock, locate-managed, bypass-activation, apply-hold, remove-hold | 事件响应操作（禁用用户、撤销会话、确认泄露/安全、 dismissal 风险、威胁狩猎查询） | usecase-response.md |
| `ediscovery` | ediscovery | Microsoft Purview 电子发现案例 | usecase-ediscovery.md |
| `cloudpc` | cloud-pc, provisioning-polic | Cloud PC / Windows 365（云电脑、配置策略、设备镜像） | usecase-cloudpc.md |
| `callrecords` | call-record, call-session, pstn-call, direct-routing | Teams 通话记录（会话、分段、参与方、PSTN 通话、直接路由） | usecase-callrecords.md |
| `print` | print | 通用打印（打印机、共享、连接器、服务、任务定义） | usecase-print.md |
| `infoprotection` | sensitivity, bitlocker, threat-assessment, mip | BitLocker、威胁评估、敏感度标签 | usecase-infoprotection.md |
| `sharepointadmin` | spo, sharepoint | SharePoint 租户管理 | usecase-sharepointadmin.md |
| `retention` | retention, records | 记录管理 | usecase-retention.md |
| `exchange` | exchange, mailbox, message-trace | 消息追踪、邮箱管理 | usecase-exchange.md |
| `intune` | intune, mdm, mam, compliance, autopilot | 设备管理、合规配置、Autopilot、应用保护策略 | usecase-intune.md |
| `teamsadmin` | teams, channel, meeting | Teams 团队、频道、会议、应用设置 | usecase-teamsadmin.md |

资料来源：[src/tool-categories.ts:7-85]()

## 使用方式

### 命令行预设加载

通过 `--preset` 参数加载特定分类的工具集：

```bash
# 列出所有安全相关工具
node dist/index.js --preset security --list-tools

# 列出所有身份管理工具
node dist/index.js --preset identity --list-tools

# 列出所有合规相关工具
node dist/index.js --preset compliance --list-tools
```

### 验证工具分类

检查特定工具是否被正确分类：

```bash
node dist/index.js --preset mypreset --list-tools
```

资料来源：[CONTRIBUTING.md:27-30]()

## 扩展机制

### 添加新分类

在 `src/tool-categories.ts` 文件中扩展 `TOOL_CATEGORIES` 对象：

```typescript
export const TOOL_CATEGORIES: Record<string, ToolCategory> = {
  // ... 现有分类 ...
  mypreset: {
    name: 'mypreset',
    pattern: /pattern-matching-tool-names/i,
    description: 'Short human-readable description',
  },
};
```

### 分类匹配规则

正则表达式必须能够匹配 `endpoints.json` 中定义的 `toolName`。验证方法：

```bash
node dist/index.js --preset mypreset --list-tools | grep list-something
```

资料来源：[CONTRIBUTING.md:20-32]()

## 与风险级别系统的集成

工具分类系统与风险级别系统（risk-level.ts）协同工作，为每个操作提供安全保障：

```typescript
export function effectiveRiskLevel(
  configuredRiskLevel: RiskLevel | undefined,
  method: string
): RiskLevel {
  if (configuredRiskLevel) return configuredRiskLevel;
  // GET 请求默认为 low，危险操作默认为 critical
  return method.toUpperCase() === 'GET' ? 'low' : 'critical';
}
```

### 风险级别分类

| 级别 | 描述 | 包含的操作类型 |
|------|------|----------------|
| `low` | 仅读取或无害操作 | GET 请求、报表生成 |
| `medium` | 可逆的单实体变更 | update-user, add-group-member |
| `high` | 影响范围大或凭证变更 | revoke-user-sessions, update-conditional-access-policy |
| `critical` | 不可逆或租户级影响 | delete-user, wipe-managed-device, delete-conditional-access-policy |

资料来源：[src/risk-level.ts:1-25]()

## 技术实现细节

### 模式匹配优先级

当一个工具名称同时匹配多个分类的正则表达式时，系统按以下原则处理：

1. **最长匹配优先** — 选择模式最具体的分类
2. **精确分类优先** — 明确命名的分类（如 `ediscovery`）优先于宽泛匹配
3. **配置覆盖** — `endpoints.json` 中的显式分类配置优先于自动匹配

### 分类与文档映射

工具目录（tools-catalog.md）建立了分类与用例文档的完整映射：

```mermaid
graph LR
    A[security preset] --> B[usecase-security.md]
    A --> C[usecase-threatintel.md]
    D[identity preset] --> E[usecase-identity.md]
    F[compliance preset] --> G[usecase-compliance.md]
    F --> H[usecase-response.md]
```

每个用例文档包含：

- 工具清单表格（操作、用途、风险级别）
- 常见操作模式（Pattern）
- 安全护栏（Guardrails）

资料来源：[agent-skills/ms365-admin-mcp/references/tools-catalog.md:1-50]()

## 开发工作流

### 添加新工具到现有分类

1. 在 `src/endpoints.json` 中添加工具定义
2. 运行 `npm run generate` 重新生成客户端代码
3. 验证工具是否被正确分类：`node dist/index.js --list-tools | grep <tool-name>`
4. 检查所需 Graph API 权限：`node dist/index.js --list-permissions | grep <permission>`

### 创建新分类

1. 编辑 `src/tool-categories.ts` 添加新的 `ToolCategory` 条目
2. 编写对应的 `usecase-<category>.md` 参考文档
3. 在 `agent-skills/ms365-admin-mcp/references/tools-catalog.md` 中添加索引
4. 运行测试验证：`npm run verify`

资料来源：[CONTRIBUTING.md:33-75]()

## 总结

工具分类系统是 ms-365-admin-mcp-server 的核心组织机制，通过 16 个预设分类覆盖了 Microsoft 365 管理的全部功能域。系统利用正则表达式模式实现自动化分类，结合风险级别系统提供了完整的安全保障。该设计遵循了最小权限原则，所有新工具必须声明最小必需的 Graph API 权限，且非 GET 操作必须明确标注风险级别。

---

<a id='page-risk-model'></a>

## 风险模型

### 相关页面

相关主题：[授权机制](#page-authorization), [工具分类系统](#page-tool-categories)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/RISK_MODEL.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/RISK_MODEL.md)
- [src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)
- [CONTRIBUTING.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)
- [agent-skills/ms365-admin-mcp/references/tools-catalog.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/tools-catalog.md)
- [agent-skills/ms365-admin-mcp/references/usecase-compliance.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/usecase-compliance.md)
</details>

# 风险模型

## 概述

风险模型是 ms-365-admin-mcp-server 安全架构的核心组件，为所有管理工具提供风险级别的分类和访问控制机制。该模型确保高风险操作得到适当的审查和确认，防止意外或恶意的租户级别更改。

风险模型的主要职责包括：

- 为每个管理工具分配明确的风险等级（`low`、`medium`、`high`、`critical`）
- 提供运行时风险级别检查机制
- 支持通过 CLI 参数 `--max-risk-level` 限制可执行的最高风险级别
- 默认为安全策略：未明确标注的写操作自动归类为 `critical`

资料来源：[src/risk-level.ts:1-30](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)

## 风险等级定义

### 四级风险体系

| 风险等级 | 判定标准 | 示例工具 |
|---------|---------|---------|
| `low` | 只读效果（POST 查询、报告）或trivial注解 | `run-hunting-query`、`add-security-alert-comment`、Intune 报告 |
| `medium` | 可逆的单一实体变更 | `update-user`、`add-group-member`、`create-invitation` |
| `high` | 重大影响：范围广、凭证变更或破坏性操作 | `revoke-user-sessions`、`update-conditional-access-policy` |
| `critical` | 不可逆或租户级别影响 | `delete-user`、`wipe-managed-device`、`delete-conditional-access-policy` |

资料来源：[CONTRIBUTING.md:55-60](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

### 判定规则

风险等级判定遵循以下原则：

1. **已配置风险优先**：如果工具显式配置了 `configuredRiskLevel`，直接使用该值
2. **方法默认策略**：未配置的工具，GET 请求默认为 `low`，写操作默认为 `critical`（fail-safe 机制）
3. **高风险优先原则**：难以判断时，选择更高的风险等级

```typescript
export function effectiveRiskLevel(
  configuredRiskLevel: RiskLevel | undefined,
  method: string
): RiskLevel {
  if (configuredRiskLevel) return configuredRiskLevel;
  return method.toUpperCase() === 'GET' ? 'low' : 'critical';
}
```

资料来源：[src/risk-level.ts:15-22](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)

## 风险级别函数

### 函数列表

```typescript
// 计算有效风险级别
export function effectiveRiskLevel(
  configuredRiskLevel: RiskLevel | undefined,
  method: string
): RiskLevel

// 检查工具是否在允许范围内
export function isToolAllowed(
  configuredRiskLevel: RiskLevel | undefined,
  method: string,
  maxRiskLevel: RiskLevel
): boolean
```

### 级别排序

风险级别按严重程度排序为：`low < medium < high < critical`

```typescript
function rank(level: RiskLevel): number {
  const ranking: Record<RiskLevel, number> = {
    low: 0,
    medium: 1,
    high: 2,
    critical: 3,
  };
  return ranking[level];
}
```

### 允许检查逻辑

工具是否允许执行取决于其有效风险级别是否不超过配置的最大风险级别：

```mermaid
graph TD
    A[工具调用请求] --> B{获取有效风险级别}
    B --> C{获取最大风险级别 cap}
    C --> D{rank有效级别 <= rank最大级别?}
    D -->|是| E[允许执行]
    D -->|否| F[拒绝执行 + 提示]
```

资料来源：[src/risk-level.ts:25-30](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)

## CLI 风险控制

### 命令行参数

| 参数 | 说明 | 隐含效果 |
|-----|------|---------|
| `--allow-writes` | 允许执行写操作 | 启用写入工具注册 |
| `--max-risk-level <level>` | 设置最高可执行风险级别 | 隐含 `--allow-writes`，隐藏更高级别工具 |

### 风险限制示例

```bash
# 只允许只读操作
ms-365-admin-mcp-server --max-risk-level low

# 允许低和中风险操作
ms-365-admin-mcp-server --max-risk-level medium

# 允许所有操作（含高风险）
ms-365-admin-mcp-server --max-risk-level high

# 允许所有操作（含关键风险）
ms-365-admin-mcp-server --max-risk-level critical
```

资料来源：[CHANGELOG.md:1-20](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CHANGELOG.md)

## 关键工具风险映射

### Critical 级别工具（需带外审批）

以下工具具有不可逆或租户级别影响，执行前必须获得正式变更请求审批：

| 工具名称 | 影响描述 |
|---------|---------|
| `delete-user` | 永久删除用户账户 |
| `delete-group` | 永久删除安全组/Microsoft 365 组 |
| `delete-application` | 删除应用注册 |
| `delete-service-principal` | 删除服务主体 |
| `delete-conditional-access-policy` | 删除条件访问策略 |
| `delete-exchange-mailbox` | 删除 Exchange 邮箱 |
| `delete-ediscovery-case` | 删除 eDiscovery 案例 |
| `delete-team` | 删除 Teams 团队 |
| `delete-managed-device` | 删除托管设备记录 |
| `wipe-managed-device` | 完全擦除设备数据 |
| `clean-windows-device` | 清理 Windows 设备 |
| `add-directory-role-member` | 添加特权目录角色成员 |
| `create-pim-role-assignment-request` | 特权角色的 PIM 分配请求 |
| `create-pim-role-eligibility-request` | 特权角色资格请求 |
| `disable-user-account` | 禁用特权或紧急访问账户 |

资料来源：[agent-skills/ms365-admin-mcp/references/tools-catalog.md:30-45](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/tools-catalog.md)

### High 级别工具（需明确确认 + 预演）

| 工具名称 | 风险描述 |
|---------|---------|
| `revoke-user-sessions` | 撤销用户所有会话，影响用户当前工作 |
| `confirm-compromised-users` | 确认用户账户已被泄露 |
| `confirm-safe-users` | 将用户标记为安全（误报处理） |
| `dismiss-risky-users` | 忽略风险用户 |
| `confirm-compromised-service-principals` | 确认服务主体泄露 |
| `dismiss-risky-service-principals` | 忽略风险服务主体 |
| `delete-user-phone-auth-method` | 删除用户手机认证方法 |
| `change-user-password` | 更改用户密码 |
| `update-device` | 更新设备配置 |
| `create-conditional-access-policy` | 创建条件访问策略 |
| `update-conditional-access-policy` | 更新条件访问策略 |

资料来源：[agent-skills/ms365-admin-mcp/references/tools-catalog.md:50-60](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/tools-catalog.md)

### 敏感读取工具

某些 GET 操作因暴露敏感信息也被标注风险级别：

| 风险等级 | 工具类型 | 示例 |
|---------|---------|------|
| `high` | 密钥/恢复信息 | BitLocker 恢复密钥、LAPS 密码 |
| `medium` | 认证信息 | 认证方法、登录记录、风险检测 |
| `high` | 合规数据 | eDiscovery 案例、保管人、搜索、主题权限请求 |

资料来源：[CHANGELOG.md:1-20](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CHANGELOG.md)

## 高危操作安全模式

### 必须遵循的操作流程

对于 `high` 和 `critical` 级别的工具，必须执行以下序列：

```mermaid
graph TD
    A[识别目标对象] --> B[预演 Dry-Run]
    B --> C[读取目标对象详情]
    C --> D[列出预期影响]
    D --> E[请求明确确认]
    E --> F{确认?}
    F -->|是| G[执行操作]
    F -->|否| H[取消操作]
    G --> I[记录审计日志]
```

### 标准确认话术

执行高风险操作前，必须向操作员说明：

> "即将调用 `<工具名称>` 对 `<目标>` 执行 `<影响描述>`。此操作 `<可逆性/不可逆>`。是否确认执行？"

资料来源：[agent-skills/ms365-admin-mcp/SKILL.md:50-70](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/SKILL.md)

## 工具目录中的风险索引

工具目录按预设（preset）和风险级别双重索引，便于快速查找：

```mermaid
graph LR
    A[工具目录] --> B[按预设索引]
    A --> C[按风险级别索引]
    B --> B1[security<br/>audit<br/>health<br/>reports<br/>identity<br/>exchange<br/>intune<br/>governance<br/>compliance<br/>response<br/>ediscovery<br/>cloudpc<br/>callrecords<br/>print<br/>infoprotection<br/>sharepointadmin<br/>retention]
    C --> C1[Critical<br/>需带外审批]
    C --> C2[High<br/>确认+预演]
    C --> C3[Medium<br/>明确确认]
    C --> C4[Low<br/>常规操作]
```

资料来源：[agent-skills/ms365-admin-mcp/references/tools-catalog.md:1-30](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/agent-skills/ms365-admin-mcp/references/tools-catalog.md)

## 安全集成

### 与其他安全机制的关系

| 安全组件 | 集成点 | 说明 |
|---------|-------|------|
| SEC-G01 | `--max-risk-level` | 风险级别 cap 作为安全门控 |
| SEC-G02 | 响应包装器 | Graph 响应被nonce信封包装，防止提示注入 |
| SEC-G03 | 敏感读取标注 | 22个敏感GET工具已标注风险级别 |

### 最小权限原则

新工具必须：

1. 声明最小必需的 Graph API 权限（`appPermissions`）
2. 避免请求 `.ReadWrite.All` 当 `.Read.All` 足够时
3. 所有写操作必须附带风险级别标注

资料来源：[CONTRIBUTING.md:40-50](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/CONTRIBUTING.md)

## 最佳实践

### 开发新工具时的风险标注

在 `endpoints.json` 中添加新工具时，必须包含风险级别：

```json
{
  "toolName": "create-something",
  "method": "POST",
  "appPermissions": ["Something.ReadWrite.All"],
  "riskLevel": "medium"
}
```

### 风险升级场景

以下情况应提升风险等级：

- 操作影响多个实体
- 操作修改凭证或访问权限
- 操作产生不可逆的数据变更
- 操作具有租户范围的影响

### 降低风险的方法

如需降低操作风险，可考虑：

1. 添加预演/确认步骤
2. 限制操作范围（单用户而非批量）
3. 添加延迟执行或审批工作流
4. 提供回滚机制

## 总结

风险模型是 ms-365-admin-mcp-server 安全架构的基础，通过四级风险体系（`low`、`medium`、`high`、`critical`）对所有515个管理工具进行分类。该模型配合 CLI 风险上限参数 `--max-risk-level` 和强制性的确认流程，确保管理员在执行敏感操作时经过充分审查，防止租户级别的意外或恶意更改。

---

<a id='page-deployment'></a>

## 部署指南

### 相关页面

相关主题：[配置参考](#page-configuration), [通信传输层](#page-transports)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [Dockerfile](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/Dockerfile)
- [docs/APP_REGISTRATION.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/APP_REGISTRATION.md)
- [docs/AZURE_DEPLOYMENT_SECURITY.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/docs/AZURE_DEPLOYMENT_SECURITY.md)
- [infra/main.bicep](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/infra/main.bicep)
</details>

# 部署指南

本文档提供 ms-365-admin-mcp-server 的完整部署指南，涵盖从 Azure AD 应用注册到容器化部署的全流程。

## 1. 部署概述

### 1.1 部署模式

ms-365-admin-mcp-server 支持两种主要部署模式：

| 部署模式 | 说明 | 适用场景 |
|---------|------|---------|
| **STDIO 模式** | 标准输入输出通信，适合本地开发和 Claude Code 集成 | 本地开发、单用户 |
| **HTTP 服务器模式** | REST API 服务，支持远程访问和 Docker 部署 | 生产环境、多租户 |

### 1.2 核心部署架构

```mermaid
graph TD
    A[客户端 MCP Client] -->|HTTP/gRPC| B[ms-365-admin-mcp-server]
    B --> C[Azure AD 应用注册]
    B --> D[Microsoft Graph API]
    D --> E[Microsoft 365 管理 API]
    
    F[Docker 容器] --> B
    G[Azure Container Instances] --> F
    H[Azure App Service] --> B
```

### 1.3 部署前提条件

- Node.js 18+ (STDIO 模式)
- Docker 20.10+ (容器模式)
- Azure 订阅
- Microsoft 365 租户管理员权限

## 2. Azure AD 应用注册

### 2.1 创建应用注册

在 Azure Portal 中创建应用注册，配置以下设置：

| 设置项 | 推荐值 | 说明 |
|-------|--------|------|
| 支持的账户类型 | 仅此组织目录中的账户 | 单租户部署 |
| 重定向 URI | `http://localhost:7000` | 本地开发 |
| 重定向 URI (生产) | `https://<your-domain>/mcp` | HTTP 服务器模式 |

### 2.2 配置应用程序权限

ms-365-admin-mcp-server 使用应用程序权限（application permissions），需要以下 Graph API 权限：

```json
{
  "requiredResourceAccess": [
    {
      "resourceAppId": "00000003-0000-0000-c000-000000000000",
      "resourceAccess": [
        {
          "id": "<permission-id>",
          "type": "Role"
        }
      ]
    }
  ]
}
```

资料来源：[docs/APP_REGISTRATION.md:1-50]()

### 2.3 获取凭据

部署需要以下环境变量：

| 环境变量 | 说明 |
|---------|------|
| `MS365_ADMIN_MCP_CLIENT_ID` | Azure AD 应用程序客户端 ID |
| `MS365_ADMIN_MCP_CLIENT_SECRET` | 应用程序客户端密钥 |
| `MS365_ADMIN_MCP_TENANT_ID` | Azure AD 租户 ID |

## 3. Docker 部署

### 3.1 拉取镜像

```bash
# 从 GitHub Container Registry 拉取
docker pull ghcr.io/okapi-ca/ms-365-admin-mcp-server:latest

# 验证镜像
docker run -d \
  --name mcp-server \
  -p 7000:7000 \
  -e MS365_ADMIN_MCP_CLIENT_ID="<your-client-id>" \
  -e MS365_ADMIN_MCP_CLIENT_SECRET="<your-client-secret>" \
  -e MS365_ADMIN_MCP_TENANT_ID="<your-tenant-id>" \
  -e MS365_ADMIN_MCP_ALLOWED_CLIENTS="*" \
  ghcr.io/okapi-ca/ms-365-admin-mcp-server:latest
```

### 3.2 Docker 容器安全配置

Docker 镜像使用非 root 用户运行，确保容器安全性：

```dockerfile
# 基础镜像配置
FROM node:18-alpine

# 创建非 root 用户
RUN addgroup -g 1001 -S mcpuser && \
    adduser -S mcpuser -u 1001

# 切换到非 root 用户
USER mcpuser

# 设置工作目录
WORKDIR /app
```

资料来源：[Dockerfile:1-30]()

### 3.3 卷挂载配置

生产环境建议挂载日志目录：

```bash
docker run -d \
  --name mcp-server \
  -p 7000:7000 \
  -v /path/to/config:/app/config:ro \
  -v /path/to/logs:/var/log/mcp-server \
  -e MS365_ADMIN_MCP_LOG_DIR="/var/log/mcp-server" \
  ghcr.io/okapi-ca/ms-365-admin-mcp-server:latest
```

## 4. Azure 基础设施部署

### 4.1 Bicep 部署架构

```mermaid
graph TD
    A[main.bicep] --> B[Azure Container Instance]
    A --> C[用户托管身份 UAMI]
    A --> D[Azure Key Vault]
    A --> E[虚拟网络]
    
    B --> C
    B --> D
    C --> D
    
    F[Private Container Registry] --> B
```

### 4.2 必需参数

| 参数名 | 类型 | 必需 | 说明 |
|-------|------|-----|------|
| `allowedClients` | string | 是 | 允许访问的客户端 CIDR 列表 |
| `acrLoginServer` | string | 否 | 私有容器注册表服务器 |
| `tags` | object | 否 | 资源标签 |
| `location` | string | 否 | 部署区域 |

资料来源：[infra/main.bicep:1-100]()

### 4.3 部署命令

```bash
# 使用 Azure CLI 部署
az deployment sub create \
  --location eastus \
  --template-file infra/main.bicep \
  --parameters allowedClients="['10.0.0.0/8']" \
  --parameters acrLoginServer="myregistry.azurecr.io"

# 验证部署
az container show --resource-group <rg-name> --name <container-name>
```

### 4.4 用户托管身份配置

Bicep 模板自动配置用户托管身份（UAMI）用于：

- 从 Azure Key Vault 检索客户端密钥
- 访问 Azure 资源
- 容器注册表拉取镜像

```bicep
resource uami 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: 'mcp-server-identity'
  location: location
}
```

资料来源：[infra/main.bicep:100-150]()

## 5. HTTP 服务器模式配置

### 5.1 启动参数

| 参数 | 默认值 | 说明 |
|-----|-------|------|
| `--port` | 7000 | HTTP 服务器监听端口 |
| `--host` | 0.0.0.0 | 绑定地址 |
| `--allowed-clients` | - | 允许的客户端 IP/CIDR |
| `--log-dir` | - | 日志目录 |
| `--allow-writes` | false | 允许写操作 |
| `--max-risk-level` | medium | 最大风险级别 |
| `--preset` | - | 预置工具类别 |
| `--enabled-tools` | - | 启用工具正则表达式 |

### 5.2 安全配置

| 安全功能 | 默认状态 | 说明 |
|---------|---------|------|
| 安全头 | 启用 | X-Content-Type-Options, X-Frame-Options, CSP |
| Body 大小限制 | 100KB | 防止大文件攻击 |
| 路径参数验证 | 启用 | 防止路径遍历 |
| ReDoS 保护 | 启用 | 正则表达式长度限制 500 字符 |
| 敏感数据脱敏 | 启用 | 日志中不泄露密钥 |

资料来源：[docs/AZURE_DEPLOYMENT_SECURITY.md:1-50]()

### 5.3 设备代码认证流程

HTTP 服务器支持设备代码认证（device_code flow），适用于无法使用客户端密钥的场景：

```bash
# 启动服务器并触发设备代码认证
node dist/index.js --http --device-code

# 输出示例
# To sign in, use a web browser to open the page https://microsoft.com/devicelogin
# and enter the code ABC12345 to authenticate.
```

认证流程：

```mermaid
sequenceDiagram
    participant C as 客户端
    participant S as MCP 服务器
    participant A as Azure AD
    
    C->>S: 请求 /token (device_code)
    S->>A: POST /devicecode
    A-->>S: device_code, user_code
    S-->>C: 显示 user_code
    C->>S: 轮询 /token
    Note over C: 用户在浏览器输入 code
    C->>A: 用户在 microsoft.com/devicelogin 认证
    A-->>S: 返回 tokens
    S-->>C: 返回 access_token
```

## 6. 环境变量配置

### 6.1 完整环境变量列表

| 环境变量 | 必需 | 默认值 | 说明 |
|---------|-----|-------|------|
| `MS365_ADMIN_MCP_CLIENT_ID` | 是 | - | Azure AD 客户端 ID |
| `MS365_ADMIN_MCP_CLIENT_SECRET` | 是* | - | 客户端密钥 |
| `MS365_ADMIN_MCP_TENANT_ID` | 是 | - | 租户 ID |
| `MS365_ADMIN_MCP_LOG_DIR` | 否 | - | 日志目录 |
| `MS365_ADMIN_MCP_PORT` | 否 | 7000 | HTTP 端口 |
| `MS365_ADMIN_MCP_HOST` | 否 | 0.0.0.0 | 绑定主机 |
| `MS365_ADMIN_MCP_ALLOWED_CLIENTS` | 否 | - | 允许的客户端 |
| `MS365_ADMIN_MCP_ALLOW_WRITES` | 否 | false | 允许写操作 |
| `MS365_ADMIN_MCP_MAX_RISK_LEVEL` | 否 | medium | 最大风险级别 |
| `MCP_REMOTE_CONFIG_DIR` | 否 | ~/.mcp-auth | OAuth 缓存目录 |

*设备代码模式下不需要

### 6.2 日志配置

Winston 日志默认使用以下路径：

```bash
# 容器环境默认日志路径
MS365_ADMIN_MCP_LOG_DIR=/tmp/.ms365-admin-mcp/logs
```

注意：在 Bicep 模板中已配置为 `/tmp/...`，避免 rootless 用户在 `/nonexistent/.ms365-admin-mcp/logs` 出现权限错误。

## 7. 生产环境检查清单

### 7.1 部署前检查

- [ ] Azure AD 应用注册已完成
- [ ] 所需 Graph API 权限已获批准
- [ ] 客户端 ID 和租户 ID 已获取
- [ ] 客户端密钥已生成并安全存储
- [ ] 网络策略已配置（允许来自 MCP 客户端的访问）
- [ ] 日志存储已配置

### 7.2 安全检查清单

- [ ] 使用 HTTPS（生产环境）
- [ ] 配置 `allowedClients` 限制访问
- [ ] `ALLOW_WRITES` 默认关闭
- [ ] 监控日志中的敏感信息泄露
- [ ] 定期轮换客户端密钥
- [ ] 配置 Key Vault 存储密钥

资料来源：[docs/AZURE_DEPLOYMENT_SECURITY.md:50-100]()

### 7.3 高可用性配置

```bash
# 使用 Azure Container Apps 实现高可用
az containerapp create \
  --name mcp-server \
  --resource-group <rg-name> \
  --environment <env-name> \
  --image ghcr.io/okapi-ca/ms-365-admin-mcp-server:latest \
  --min-replicas 2 \
  --max-replicas 10
```

## 8. 故障排除

### 8.1 常见部署错误

| 错误 | 原因 | 解决方案 |
|-----|------|---------|
| `EACCES` 日志写入失败 | 权限问题 | 设置 `MS365_ADMIN_MCP_LOG_DIR=/tmp/...` |
| `tenant_rejected` | 使用了 `common` 端点 | 改用单租户 `organizations` 端点 |
| `Server disconnected` | 设备代码认证超时 | 重新启动认证流程 |
| 401 Unauthorized | 客户端密钥过期 | 更新密钥或使用设备代码流 |

### 8.2 容器日志查看

```bash
# 查看容器日志
docker logs mcp-server

# 实时跟踪日志
docker logs -f mcp-server

# 进入容器调试
docker exec -it mcp-server sh
```

### 8.3 网络连通性测试

```bash
# 测试 Graph API 连通性
curl -v https://graph.microsoft.com/v1.0/$select

# 测试 Token 端点
curl -v -X POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
```

## 9. 相关文档

- [应用注册指南](docs/APP_REGISTRATION.md)
- [Azure 部署安全](docs/AZURE_DEPLOYMENT_SECURITY.md)
- [架构文档](docs/ARCHITECTURE.md)
- [使用案例](docs/USE_CASES.md)
- [故障排除](docs/TROUBLESHOOTING.md)

---

<a id='page-configuration'></a>

## 配置参考

### 相关页面

相关主题：[部署指南](#page-deployment), [认证系统](#page-authentication)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/cloud-config.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cloud-config.ts)
- [src/endpoints.json](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/endpoints.json)
- [src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)
- [src/secrets.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/secrets.ts)
- [README.md](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/README.md)
- [src/tool-categories.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)
- [src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)
</details>

# 配置参考

本页面详细说明 ms-365-admin-mcp-server 的所有配置选项，包括环境变量、云端配置、认证方式、预设分组以及风险级别策略。

## 1. 环境变量配置

服务器通过环境变量读取 Azure AD 应用注册凭据。支持两种模式：标准环境和 Azure 中国区（21Vianet）。

### 1.1 必需的环境变量

| 环境变量 | 描述 | 示例 |
|---------|------|------|
| `MS365_ADMIN_MCP_CLIENT_ID` | Azure AD 应用程序（客户端）ID | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
| `MS365_ADMIN_MCP_CLIENT_SECRET` | 客户端密钥 | `~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
| `MS365_ADMIN_MCP_TENANT_ID` | Azure AD 租户 ID | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |

### 1.2 云端环境配置

| 环境变量 | 默认值 | 描述 |
|---------|--------|------|
| `MS365_ADMIN_MCP_CLOUD` | `global` | 云环境：`global`（全球版）或 `cn`（中国区 21Vianet） |

资料来源：[src/cloud-config.ts:1-50](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cloud-config.ts)

### 1.3 服务器运行配置

| 环境变量 | 默认值 | 描述 |
|---------|--------|------|
| `MS365_ADMIN_MCP_PORT` | `3000` | HTTP 服务器监听端口 |
| `MS365_ADMIN_MCP_HOST` | `0.0.0.0` | HTTP 服务器绑定地址 |
| `MS365_ADMIN_MCP_ALLOW_WRITES` | `false` | 允许执行写入操作 |
| `MS365_ADMIN_MCP_MAX_RISK_LEVEL` | `medium` | 最大允许风险级别 |
| `MS365_ADMIN_MCP_PRESET` | `all` | 初始工具预设分组 |

### 1.4 认证缓存配置

| 环境变量 | 默认值 | 描述 |
|---------|--------|------|
| `MCP_REMOTE_CONFIG_DIR` | `~/.mcp-auth/mcp-remote-<version>/` | 设备码认证缓存目录 |
| `AZURE_CLIENT_SECRET` | - | Key Vault 密钥保管库模式下的客户端密钥 |

资料来源：[src/secrets.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/secrets.ts)

## 2. 云端配置详解

### 2.1 云环境端点

服务器支持两种 Microsoft 365 云环境：

```mermaid
graph TD
    A[启动服务器] --> B{MS365_ADMIN_MCP_CLOUD?}
    B -->|global| C[全球版端点]
    B -->|cn| D[中国区端点 21Vianet]
    C --> E[login.microsoftonline.com]
    D --> F[login.partner.microsoftonline.cn]
```

**全球版端点：**

| 用途 | 端点 URL |
|------|----------|
| Microsoft Graph | `https://graph.microsoft.com` |
| Azure AD 令牌 | `https://login.microsoftonline.com` |
| Azure Key Vault | `https://vault.azure.net` |

**中国区（21Vianet）端点：**

| 用途 | 端点 URL |
|------|----------|
| Microsoft Graph | `https://microsoftgraph.chinacloudapi.cn` |
| Azure AD 令牌 | `https://login.partner.microsoftonline.cn` |
| Azure Key Vault | `https://vault.azure.cn` |

资料来源：[src/cloud-config.ts:10-45](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/cloud-config.ts)

## 3. 认证配置

### 3.1 认证流程

服务器使用 MSAL（Microsoft Authentication Library）的客户端凭据流（Client Credentials Flow）进行身份验证：

```mermaid
sequenceDiagram
    participant Client
    participant Server
    participant Azure AD
    
    Client->>Server: 请求调用工具
    Server->>Azure AD: 获取访问令牌 (client_credentials)
    Azure AD-->>Server: access_token
    Server->>Microsoft Graph: API 请求 + access_token
    Microsoft Graph-->>Server: 响应数据
    Server-->>Client: 工具执行结果
```

### 3.2 认证模式

| 模式 | 配置方式 | 说明 |
|------|----------|------|
| 环境变量 | `MS365_ADMIN_MCP_CLIENT_SECRET` | 最简方式，直接明文存储密钥 |
| Key Vault | `AZURE_CLIENT_SECRET` + Key Vault URI | 生产环境推荐，密钥由 Azure Key Vault 管理 |

资料来源：[src/auth.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/auth.ts)

### 3.3 设备码认证（远程 HTTP 服务器）

对于远程 HTTP 服务器部署，服务器支持 RFC 8628 设备码流：

```bash
# 预填充认证缓存
ms-365-admin-mcp-auth --server https://your-host.azurecontainerapps.io/mcp

# 退出码说明
# 0 - 成功
# 1 - 用法错误
# 2 - 网络错误
# 3 - 认证被拒绝
# 4 - 超时
```

认证缓存位置：`~/.mcp-auth/mcp-remote-<version>/`，包含：
- `<hash>_client_info.json`
- `<hash>_tokens.json`

缓存密钥使用 `md5(serverUrl)` 计算，与 `mcp-remote` 的 `getServerUrlHash` 完全匹配。

## 4. 工具预设分组

工具预设（Presets）用于按功能域分组暴露管理工具，减少 MCP 客户端需要处理的工具数量。

### 4.1 可用预设列表

| 预设名称 | 说明 | 包含工具类型 |
|---------|------|-------------|
| `security` | 安全警报、事件、攻击模拟、威胁情报 | Microsoft 365 Defender 相关 |
| `audit` | 审计日志、登录日志、已删除项目 | 目录审计、登录、预配 |
| `health` | 服务健康状况、消息中心公告 | 服务状态、问题、消息 |
| `reports` | 使用报告 | Teams、邮件、SharePoint、OneDrive、M365 应用 |
| `identity` | 身份和访问管理 | 用户、组、角色、设备、PIM、访客用户、外部身份 |
| `exchange` | Exchange 管理 | 邮件追踪、邮箱、收件人 |
| `intune` | Intune 设备管理 | 设备、合规、配置、Autopilot、应用、RBAC |
| `governance` | 标识治理 | 访问评审、权利管理、生命周期工作流、TOU、应用同意 |
| `compliance` | 合规性管理 | 许可证、安全分数、身份保护、风险检测、条件访问 |
| `response` | 事件响应操作 | 禁用用户、撤销会话、确认泄露、 dismissing 风险 |
| `ediscovery` | 电子发现案例 | Microsoft Purview |
| `cloudpc` | Cloud PC / Windows 365 | 云电脑、预配策略、设备镜像 |
| `callrecords` | Teams 通话记录 | 会话、段、参与者、PSTN 通话、Direct Routing |
| `print` | 通用打印 | 打印机、共享、连接器、服务 |
| `infoprotection` | 信息保护 | BitLocker、威胁评估、敏感度标签 |
| `sharepointadmin` | SharePoint 管理 | SharePoint 租户管理 |
| `retention` | 记录管理 | 保留策略、处置工作流 |
| `teamsadmin` | Teams 管理 | 团队、频道、成员、应用、策略 |
| `all` | 所有可用工具 | 全部 515 个工具 |

资料来源：[src/tool-categories.ts:1-80](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/tool-categories.ts)

### 4.2 预设模式匹配规则

每个预设通过正则表达式模式匹配工具名称：

```typescript
// 示例：identity 预设的匹配模式
/role|directory|domain|auth-method|credential|application|service-principal|sp-password|sp-key|sp-token|sp-owner|oauth2|organization|named-location|device|administrative-unit|cross-tenant|pim|app-role|invitation|identity-provider|b2x|api-connector|custom-auth/i
```

### 4.3 组合预设

支持同时启用多个预设：

```typescript
import { getCombinedPresetPattern } from './tool-categories';

const combined = getCombinedPresetPattern(['security', 'audit']);
// 返回组合后的正则表达式
```

## 5. 风险级别策略

### 5.1 风险级别定义

| 级别 | 含义 | 示例工具 |
|------|------|----------|
| `low` | 只读操作，查询类操作 | `list-users`、`get-team` |
| `medium` | 有限影响，局部修改 | `create-team`、`update-user` |
| `high` | 重大影响，范围广泛或凭证变更 | `revoke-user-sessions`、`update-conditional-access-policy` |
| `critical` | 不可逆或租户范围影响 | `delete-user`、`wipe-managed-device`、`delete-conditional-access-policy` |

资料来源：[src/risk-level.ts](https://github.com/okapi-ca/ms-365-admin-mcp-server/blob/main/src/risk-level.ts)

### 5.2 风险级别判定逻辑

```mermaid
graph TD
    A[工具执行请求] --> B{配置了 riskLevel?}
    B -->|是| C[使用配置的 riskLevel]
    B -->|否| D{HTTP 方法是 GET?}
    D -->|是| E[默认为 low]
    D -->|否| F[默认为 critical]
    C --> G[与 maxRiskLevel 比较]
    E --> G
    F --> G
    G --> H{rank ≤ maxRiskLevel?}
    H -->|是| I[允许执行]
    H -->|否| J[拒绝执行]
```

风险等级排序（从小到大）：`low` < `medium` < `high` < `critical`

### 5.3 关键工具列表

**Critical 级别（需要带外审批）：**

| 工具 | 风险 |
|------|------|
| `delete-user` | critical |
| `delete-group` | critical |
| `delete-application` | critical |
| `delete-service-principal` | critical |
| `delete-conditional-access-policy` | critical |
| `delete-exchange-mailbox` | critical |
| `delete-ediscovery-case` | critical |
| `delete-team` | critical |
| `delete-managed-device` | critical |
| `wipe-managed-device` | critical |
| `clean-windows-device` | critical |
| `add-directory-role-member` | critical |
| `create-pim-role-assignment-request` | critical |
| `disable-user-account` | critical |

**High 级别（需要明确确认）：**

| 工具 | 风险 |
|------|------|
| `revoke-user-sessions` | high |
| `confirm-compromised-users` | high |
| `dismiss-risky-users` | high |
| `change-user-password` | high |
| `create-conditional-access-policy` | high |
| `delete-named-location` | high |
| `create-auth-strength-policy` | high |

## 6. 端点配置

### 6.1 端点定义格式

`endpoints.json` 是工具定义的信任源，每个端点包含：

```jsonc
{
  "toolName": "list-users",
  "pathPattern": "/users",
  "method": "GET",
  "appPermissions": ["User.Read.All"],
  "llmTip": "可选的提示信息，显示在工具描述中"
}
```

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `toolName` | string | 是 | 工具唯一标识符 |
| `pathPattern` | string | 是 | Microsoft Graph API 路径 |
| `method` | string | 是 | HTTP 方法（GET/POST/PATCH/DELETE） |
| `appPermissions` | string[] | 是 | 所需的应用权限 |
| `llmTip` | string | 否 | 展示给 LLM 的提示信息 |
| `riskLevel` | string | 否 | 风险级别（仅非 GET 方法需要） |

### 6.2 必需权限示例

| 工具域 | 所需权限 |
|--------|----------|
| 用户管理 | `User.Read.All`, `User.ReadWrite.All` |
| 组管理 | `Group.Read.All`, `Group.ReadWrite.All` |
| 设备管理 | `Device.Read.All`, `Device.ReadWrite.All` |
| 安全 | `SecurityEvents.Read.All`, `SecurityEvents.ReadWrite.All` |
| Intune | `DeviceManagementManagedDevices.Read.All` |

## 7. CLI 命令行参数

### 7.1 本地模式（Stdio）

```bash
ms-365-admin-mcp-server [options]

选项：
  --preset <name>         工具预设分组
  --allow-writes          允许写入操作
  --max-risk-level <level> 最大风险级别 (low/medium/high/critical)
  --list-tools            列出指定预设的工具
  --list-permissions      列出所需 Graph 权限
  --version, -v           显示版本
  --help, -h              显示帮助
```

### 7.2 HTTP 服务器模式

```bash
ms-365-admin-mcp-server --http [options]

HTTP 专用选项：
  --port <number>         监听端口 (默认: 3000)
  --host <address>        绑定地址 (默认: 0.0.0.0)
```

### 7.3 认证引导

```bash
ms-365-admin-mcp-auth --server <url> [options]

选项：
  -s, --server <url>      MCP 服务器 URL（必需）
  --scope <scope>         覆盖 OAuth scope
  --cache-dir <path>      缓存目录覆盖
```

## 8. 本地开发配置

### 8.1 本地 .env 文件格式

```bash
# Azure AD 应用注册
MS365_ADMIN_MCP_CLIENT_ID=your-client-id
MS365_ADMIN_MCP_CLIENT_SECRET=your-client-secret
MS365_ADMIN_MCP_TENANT_ID=your-tenant-id

# 可选：云环境 (默认 global)
MS365_ADMIN_MCP_CLOUD=global
```

### 8.2 开发验证命令

```bash
# 验证工具列表
node dist/index.js --preset security --list-tools

# 验证所需权限
node dist/index.js --preset identity --list-permissions

# 运行 MCP 检查器
npm run inspector
```

## 9. Docker 部署配置

### 9.1 环境变量配置

```bash
docker run -e MS365_ADMIN_MCP_CLIENT_ID=xxx \
           -e MS365_ADMIN_MCP_CLIENT_SECRET=xxx \
           -e MS365_ADMIN_MCP_TENANT_ID=xxx \
           -e MS365_ADMIN_MCP_PORT=3000 \
           ghcr.io/okapi-ca/ms-365-admin-mcp-server:latest
```

### 9.2 Docker Compose 示例

```yaml
services:
  mcp-server:
    image: ghcr.io/okapi-ca/ms-365-admin-mcp-server:latest
    environment:
      MS365_ADMIN_MCP_CLIENT_ID: "${CLIENT_ID}"
      MS365_ADMIN_MCP_CLIENT_SECRET: "${CLIENT_SECRET}"
      MS365_ADMIN_MCP_TENANT_ID: "${TENANT_ID}"
      MS365_ADMIN_MCP_CLOUD: "global"
      MS365_ADMIN_MCP_PORT: "3000"
    ports:
      - "3000:3000"
```

## 10. Azure Container Apps 部署

通过 Bicep 模板部署时，可在 `infra/main.bicep` 中配置：

```bicep
// 环境变量通过 Key Vault 引用
MS365_ADMIN_MCP_CLIENT_ID: keyVaultSecret('client-id')
MS365_ADMIN_MCP_CLIENT_SECRET: keyVaultSecret('client-secret')
MS365_ADMIN_MCP_TENANT_ID: keyVaultSecret('tenant-id')
MS365_ADMIN_MCP_CLOUD: 'global'
```

## 11. 故障排除配置

### 11.1 常见配置问题

| 问题 | 可能原因 | 解决方案 |
|------|----------|----------|
| 认证失败 | 客户端密钥过期 | 续订 Azure AD 应用密钥 |
| 权限不足 | 缺少 Graph API 权限 | 在 Azure AD 中添加所需权限 |
| 工具不可用 | 预设配置错误 | 使用 `--list-tools` 验证工具列表 |
| 写入被拒绝 | `--allow-writes` 未启用 | 添加 `--allow-writes` 参数 |

### 11.2 调试日志

服务器使用 Winston 日志记录器，通过设置日志级别环境变量可获取详细调试信息：

```bash
# 启用调试日志
DEBUG=ms-365-admin-mcp-server:* ms-365-admin-mcp-server
```

## 12. 配置验证清单

部署前请确认以下配置项：

- [ ] Azure AD 应用已注册且 `CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID` 已获取
- [ ] 应用已授权所需 Graph API 权限（使用最小权限原则）
- [ ] 根据部署区域选择正确的 `MS365_ADMIN_MCP_CLOUD` 值
- [ ] 生产环境建议使用 Azure Key Vault 管理密钥
- [ ] `max-risk-level` 已根据组织安全策略配置
- [ ] 对于远程 HTTP 部署，已运行设备码引导流程
- [ ] 已通过 `--list-permissions` 验证所需权限

---

---

## Doramagic 踩坑日志

项目：okapi-ca/ms-365-admin-mcp-server

摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。

## 1. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | README/documentation is current enough for a first validation pass.

## 2. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | last_activity_observed missing

## 3. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作：下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | no_demo; severity=medium

## 4. 安全/权限坑 · 存在安全注意事项

- 严重度：medium
- 证据强度：source_linked
- 发现：No sandbox install has been executed yet; downstream must verify before user use.
- 对用户的影响：用户安装前需要知道权限边界和敏感操作。
- 建议检查：转成明确权限清单和安全审查提示。
- 防护动作：安全注意事项必须面向用户前置展示。
- 证据：risks.safety_notes | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | No sandbox install has been executed yet; downstream must verify before user use.

## 5. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | no_demo; severity=medium

## 6. 安全/权限坑 · 来源证据：SEC-004: UPN persisted in logs without redaction option (PII / GDPR exposure)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：SEC-004: UPN persisted in logs without redaction option (PII / GDPR exposure)
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_6ede43fd3f7247e0981524934656dbeb | https://github.com/okapi-ca/ms-365-admin-mcp-server/issues/71 | 来源类型 github_issue 暴露的待验证使用条件。

## 7. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作：issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | issue_or_pr_quality=unknown

## 8. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | github_repo:1210842314 | https://github.com/okapi-ca/ms-365-admin-mcp-server | release_recency=unknown

<!-- canonical_name: okapi-ca/ms-365-admin-mcp-server; human_manual_source: deepwiki_human_wiki -->
