mcpField
C
CIPP

CIPP

本地服务
github.com云与基础设施121 周前更新

关于 CIPP

CIPP 是面向 MSP 的 MCP 服务,可通过运行中的 CIPP 部署管理多个 Microsoft 365 租户,涵盖管理、安全、合规、许可和报告。

主要功能

  1. 01管理租户、用户、群组和邮箱
  2. 02查看登录记录、条件访问和安全评分
  3. 03检查标准、合规性和域健康
  4. 04报告邮箱用量和许可证状态
  5. 05管理警报、GDAP 和计划任务
  6. 06支持 stdio 和 HTTP 传输

适用场景

  1. 01跨客户租户管理用户账户
  2. 02审查登录活动和安全策略
  3. 03检查租户标准及配置偏差
  4. 04报告邮箱大小和许可证分配

MCP 相关

向 MCP 客户端提供 CIPP 的 Microsoft 365 多租户管理能力,作为可调用工具。支持 stdio 和 HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"wyre-technology-cipp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"CIPP_API_URL",
"-e",
"CIPP_CLIENT_ID",
"-e",
"CIPP_CLIENT_SECRET",
"-e",
"CIPP_TENANT_ID",
"-e",
"MCP_TRANSPORT",
"-e",
"AUTH_MODE",
"-e",
"LOG_LEVEL",
"ghcr.io/wyre-technology/cipp-mcp:v1.7.3"
],
"env": {
"CIPP_API_URL": "<CIPP_API_URL>",
"CIPP_CLIENT_ID": "<CIPP_CLIENT_ID>",
"CIPP_CLIENT_SECRET": "<CIPP_CLIENT_SECRET>",
"CIPP_TENANT_ID": "<CIPP_TENANT_ID>",
"MCP_TRANSPORT": "<MCP_TRANSPORT>",
"AUTH_MODE": "<AUTH_MODE>",
"LOG_LEVEL": "<LOG_LEVEL>"
}
}
}
}
启动命令docker run -i --rm -e CIPP_API_URL -e CIPP_CLIENT_ID -e CIPP_CLIENT_SECRET -e CIPP_TENANT_ID -e MCP_TRANSPORT -e AUTH_MODE -e LOG_LEVEL ghcr.io/wyre-technology/cipp-mcp:v1.7.3
需要配置的环境变量
CIPP_API_URLBase URL of your CIPP API instance (e.g. https://cipp-api.example.com)
CIPP_CLIENT_IDEntra ID application (client) ID used to authenticate to CIPP
CIPP_CLIENT_SECRET密钥Entra ID client secret for the CIPP application
CIPP_TENANT_IDEntra ID tenant ID hosting the CIPP application registration
MCP_TRANSPORTTransport mode for the server. Set to 'stdio' for local CLI use; the image defaults to 'http' for gateway hosting.
AUTH_MODE密钥Credential source: 'env' reads vars locally, 'gateway' expects header injection from the WYRE MCP Gateway.
LOG_LEVELLog verbosity: debug, info, warn, error

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/wyre-technology/cipp-mcp:v1.7.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

CIPP MCP 服务器

适用于 CIPP(CyberDrain Improved Partner Portal)的 MCP(Model Context Protocol)服务器。为 AI 助手提供对 CIPP M365 多租户管理功能的结构化访问。

功能

  • 49 个工具,涵盖 12 个类别
  • 租户、用户、组和邮箱管理
  • 邮箱和在线存档大小报告,可按租户或用户查看
  • 每位用户的 Entra ID 登录日志(状态、位置、条件访问、MFA)
  • 安全性:条件访问策略、命名位置、Microsoft Secure Score
  • 标准与合规:BPA、域健康状况、偏差检测
  • 许可证报告(按租户及 CSP 全范围)
  • 警报、审核日志和计划任务
  • GDAP 角色和邀请管理
  • Stdio 和 HTTP 传输模式
  • 兼容 MCP Gateway

先决条件

  • Node.js 18+
  • 正在运行的 CIPP 部署
  • CIPP API Key(在 CIPP Settings → API Client Management 中生成)

安装

通过 npm(发布后)
npx cipp-mcp
从源代码安装
git clone https://github.com/WYRE-AI/cipp-mcp
cd cipp-mcp
npm install
npm run build

配置

设置以下环境变量(或将 .env.example 复制到 .env):

变量必需说明
CIPP_BASE_URL是你的 CIPP Azure Function App URL(例如 https://cippXXXXX.azurewebsites.net)。请勿使用 SWA / 前端 URL——参见查找 Function App URL。
CIPP_API_KEY二选一静态 Bearer 令牌。使用此项或下方的 OAuth 三项配置。
CIPP_TENANT_ID二选一拥有 CIPP API 客户端应用注册的 Entra 租户 ID。
CIPP_CLIENT_ID二选一由 CIPP 的 API Client Management 页面签发的 OAuth 客户端 ID。
CIPP_CLIENT_SECRET二选一与 CIPP_CLIENT_ID 配对的 OAuth 客户端密钥。
CIPP_TOKEN_SCOPE否覆盖 OAuth 作用域。默认值:api://<clientId>/.default。显式设置此值会禁用下方的旧版作用域回退。
CIPP_TOKEN_SCOPE_FALLBACK否未显式设置作用域时,遇到 CIPP HTTP 401 响应后,使用旧版 <clientId>/.default 作用域重试一次,并复用此客户端接受的受众。默认值:true。TOKEN_SCOPE_FALLBACK 是别名。网关请求可发送 x-token-scope-fallback。
CIPP_TOKEN_URL否覆盖 OAuth 令牌端点(仅限主权云)。
MCP_TRANSPORT否stdio(默认)或 http
AUTH_MODE否env(stdio 和单租户 HTTP)或 gateway。网关模式要求每个 /mcp 请求都携带 CIPP 凭据标头,且不会回退到 CIPP_*。容器映像和 Compose 网关服务会设置为 gateway。
CONDUIT_S2S_SECRETHTTP 必需与网关共享的服务间密钥。若该值为空、仅含空白字符或为已知占位值(changeme、change-me、your-s2s-secret、your-secret、placeholder、secret、example、replace-me、replace-with-a-real-secret、s2s-secret 或未解析的 ${...} 值),HTTP 会记录错误并以非零状态退出。未设置该值时,Compose 不会启动。切勿提交真实值。
MCP_ALLOW_INSECURE_DEV否仅限本地开发时,将其精确设置为 1,即可在未设置 CONDUIT_S2S_SECRET 的情况下启动 HTTP。进程会记录警告,不会强制检查 X-Gateway-S2S,且只监听 127.0.0.1。非环回地址的 MCP_HTTP_HOST 将被忽略,并记录此覆盖操作。此标志不会绕过已知占位值检查。
MCP_HTTP_HOST否当 MCP_TRANSPORT=http 且已设置 CONDUIT_S2S_SECRET 时使用的绑定地址。未设置时默认为 127.0.0.1。容器映像会设置为 0.0.0.0。
MCP_HTTP_PORT否HTTP 模式的端口(默认值:8080)
LOG_LEVEL否error、warn、info(默认)或 debug

重要

CIPP_BASE_URL 必须是 Azure Function App URL,即 CIPP-API 后端的 https://<function-app-name>.azurewebsites.net,不能是 Static Web App / 自定义域名 UI URL(例如 https://cipp.yourdomain.com)。SWA 内置的 身份验证会拦截 Bearer 令牌,并将其重定向到交互式登录页面, 因此所有 API 调用都会失败。请在 Azure Portal 的 CIPP 资源组中查找 Function App(名称类似 cippXXXXX)。

/health 无需身份验证,也不会读取凭据。stdio 传输不使用 CONDUIT_S2S_SECRET。

HTTP 身份验证

设置 MCP_TRANSPORT=http 和 CONDUIT_S2S_SECRET 后,每个 /mcp 请求都必须包含 X-Gateway-S2S。标头值的格式为 t=<unix seconds>,v1=<hex>,其中 v1 是使用 CONDUIT_S2S_SECRET 作为密钥,对 ASCII 字符串 t=<unix seconds> 计算得到的 HMAC-SHA256 的十六进制编码。时间戳与服务端时钟的偏差必须在 300 秒以内。缺少标头或标头无效时,会返回 HTTP 401,且不会读取 CIPP 凭据。密钥绝不会写入日志。

X-Gateway-S2S: t=1710000000,v1=<64 lowercase hex chars>

在 AUTH_MODE=gateway 下,/mcp 还需要 x-base-url,以及 x-api-key 或全部三个标头:x-tenant-id、x-client-id 和 x-client-secret(x-token-scope、x-token-url 和 x-token-scope-fallback 为可选项)。这些标头是该请求唯一的 CIPP 凭据来源。缺少这些标头的请求会返回 HTTP 401,且不会使用进程环境中的 CIPP_*。

AUTH_MODE=env 仍要求提供有效的 X-Gateway-S2S 标头,然后使用环境中的 CIPP_*。

不设置密钥的本地 HTTP 仅限开发使用。即使 MCP_HTTP_HOST 为 0.0.0.0 或其他非环回地址,它也会绑定到 127.0.0.1:

MCP_TRANSPORT=http MCP_ALLOW_INSECURE_DEV=1 npm run dev
Docker

镜像会在容器内监听 0.0.0.0(MCP_HTTP_HOST),并默认使用 AUTH_MODE=gateway。请将端口发布到环回地址,并传入网关使用的同一个 S2S 密钥。在网关模式下,每个请求都会通过标头传入 CIPP 凭据;不会从环境中读取这些凭据。

docker build -t cipp-mcp .
docker run --rm \
  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
  -p 127.0.0.1:8080:8080 \
  cipp-mcp

未设置 CONDUIT_S2S_SECRET 时,Compose 会拒绝启动。cipp-mcp 服务使用网关模式:它设置 AUTH_MODE=gateway,发布 127.0.0.1:8080:8080,并且不会设置 CIPP_API_KEY、CIPP_CLIENT_ID、CIPP_CLIENT_SECRET、CIPP_TENANT_ID、CIPP_BASE_URL 或 env_file。

CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" docker compose up

单租户 HTTP(AUTH_MODE=env)仍需要 S2S 密钥,然后使用 CIPP_*:

docker run --rm \
  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
  -e AUTH_MODE=env \
  -e CIPP_BASE_URL=https://cippXXXXX.azurewebsites.net \
  -e CIPP_TENANT_ID=your-entra-tenant-id \
  -e CIPP_CLIENT_ID=your-client-id \
  -e CIPP_CLIENT_SECRET=your-client-secret \
  -p 127.0.0.1:8080:8080 \
  cipp-mcp

在 Claude Desktop 中使用

添加到你的 claude_desktop_config.json:

{
  "mcpServers": {
    "cipp": {
      "command": "node",
      "args": ["/path/to/cipp-mcp/dist/entry.js"],
      "env": {
        "CIPP_BASE_URL": "https://cippXXXXX.azurewebsites.net",
        "CIPP_TENANT_ID": "your-entra-tenant-id",
        "CIPP_CLIENT_ID": "your-client-id",
        "CIPP_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

注意: CIPP_BASE_URL 必须是 Azure Function App URL(.azurewebsites.net),而不是前端 SWA URL(.azurestaticapps.net 或你的自定义域名)。SWA 会强制执行基于浏览器的身份验证,并将所有 API 请求重定向到 Microsoft 登录页面。

工具

类别工具
租户list_tenants, get_tenant_details
用户list_users, create_user, edit_user, disable_user, reset_password, reset_mfa, revoke_sessions, offboard_user, bec_check, list_mfa_users, list_user_devices, list_user_groups, list_user_signin_logs
组list_groups, create_group
邮箱list_mailboxes, list_mailbox_permissions, list_trusted_blocked_senders, list_mailbox_usage, get_mailbox_usage, set_out_of_office, set_email_forwarding
安全list_conditional_access_policies, list_named_locations, get_secure_score, list_secure_score_controls
应用程序list_enterprise_apps
标准list_standards, run_standards_check, list_standard_templates, get_tenant_drift, get_tenant_alignment, create_standard_template, delete_standard_template, list_bpa, list_domain_health
许可证list_licenses, list_csp_licenses
警报list_audit_logs, list_alert_queue
GDAPlist_gdap_roles, list_gdap_invites
调度器list_scheduled_items, add_scheduled_item
核心ping, get_version, list_logs
创建用户后立即编辑用户

edit_user 会先解析帐户当前的 UPN,因为 CIPP 的 Invoke-EditUser 每次调用时都会根据 username + Domain 重新生成 UPN, 不带 UPN 进行编辑会重命名帐户。Graph 可能需要几秒钟才能同步刚创建的帐户,因此如果查找不到帐户、返回 HTTP 404,或返回正文为 Graph 未找到错误的 5xx(Request_ResourceNotFound 代码,或 Graph 的“Resource '' does not exist or one of its queried reference-property objects are not present”消息),最多会重试 4 次,每次间隔 1 秒、3 秒和 6 秒(约 10 秒)。重试判断依据是 HTTP 状态码,而非消息文本;其他任何 4xx (400、401、403)和其他 5xx 都不会重试。如果用户仍不可见,错误会显示“Tried N times”,并在最后一次尝试收到 HTTP 错误时显示其状态码;稍等片刻后重试。

邮箱和存档大小

list_mailbox_usage 会报告租户中的每个邮箱,包括主邮箱大小、项目数、 配额、配额百分比,以及联机存档对应的相同四项数据;按大小从大到小排序, 并提供覆盖所有邮箱的租户总计,即使返回的只有排名靠前的几行。

此工具要求 CIPP 的报告数据库已针对该租户完成同步。 这并非设计选择:Invoke-ListMailboxes 的 Exchange 实时查询 完全不会选择大小字段,因此缓存是获取租户范围大小数据的唯一来源。 请在 CIPP 的 Reports → Report Settings 中进行同步。如果尚未同步, 工具会说明这一点并指出解决方法,而不是返回空结果。

get_mailbox_usage 会报告单个邮箱的相同数据,并实时读取,因此无需缓存。 缓存不可用或已过时时,优先使用此工具。

需要注意以下两点:

  • 隐藏报告名称会导致租户范围的大小数据为空。 在 Microsoft 365 管理 中心启用 Reports: conceal user, group, and site names 后,Graph 的使用情况报告会返回 32 个字符的哈希值,而非 UPN,因此 CIPP 与邮箱列表的联接不会匹配到任何内容, 每个邮箱缓存的大小都会变为 0 — 租户看起来像是空的,而不是查询失败。 list_mailbox_usage 会检测到此情况,并在总计旁返回警告。 get_mailbox_usage 不受影响:它直接读取 Exchange 管理 API。
  • 按用户查询路径返回的大小会四舍五入到吉字节。 CIPP 返回前会将吉字节数 四舍五入到小数点后两位,因此 get_mailbox_usage 的字节数 精确度约为 10 MB。配额是精确的 — 它们是从原始 Get-Mailbox 字符串中还原的, 该字符串包含真实的字节数。
用户登录日志

list_user_signin_logs 会返回一位用户最近的交互式登录记录, 按时间从新到旧排列:时间、应用、IP、位置、成功或失败及错误代码和 原因、客户端应用、条件访问状态及评估过的策略、Graph 记录的身份验证方法 (包括第一个因素 — 是否要求 MFA 由 authenticationRequirement 表示)、设备,以及 在标记风险时显示的风险信息;此外还会汇总失败次数、不同 IP 和国家/地区。

  • 接受 UPN 或对象 ID,并始终先进行解析。 CIPP 根据 userId 过滤 Graph,而该字段是 Entra 对象 ID;如果在此处传入 UPN, 则不会匹配到任何内容,并会返回一个空页面,让人误以为“此用户从未登录”。无法解析的用户会报错,而非返回空结果。
  • 单个租户、单个用户、单页。 top 默认为 50,上限为 1000;如果 页面已满,会显示警告,指出可能还有更早的登录记录。allTenants 会被拒绝 — 此端点没有跨租户分支。租户范围的登录记录在 CIPP 的 Sign-Ins 报告 (ListSignIns)中,此服务不提供该报告。
  • 租户需要 Entra ID P1/P2。 否则 Graph 会拒绝访问登录日志 API; 工具会指出许可证缺失,而不是转述笼统的“Failed to retrieve Sign In report”。
Microsoft Secure Score

get_secure_score 会返回一个租户最新的 Secure Score 及其近期每日历史记录。list_secure_score_controls 会返回建议目录,包括标题、排名、最高分、成本、修正方法、威胁,以及将某项控制标记为已由第三方解决或忽略的决定。

CIPP 没有专用的 Secure Score 读取端点。唯一的 Secure Score HTTP 函数是 ExecUpdateSecureScore,它用于更新控制项,且未在此处公开。这两个工具都会调用 ListGraphRequest,CIPP 自己的 Secure Score 页面也使用该函数,并将 Endpoint 设为 security/secureScores 或 security/secureScoreControlProfiles。

  • 仅限一个租户。 不接受 allTenants。CIPP 的全局视图使用每晚更新的分数缓存,而不是实时 Graph 调用;这些工具不会读取该缓存。
  • 只有关闭分页时,top 才会限制历史记录。 ListGraphRequest 会将 $top 视为 Graph 的页面大小,并跟随每个后续链接,除非设置了 NoPagination。get_secure_score 始终同时发送这两个参数,因此 top(默认值为 7,最大值为 90)表示返回的每日读数数量。控制目录会保持分页开启,并将页面大小设为 999,因此会返回完整列表。
  • 空结果不代表分数为零。 尚未评分的租户,或其 CIPP 应用缺少 SecurityEvents.Read.All 权限的租户,会返回无读数并附带警告。如果权限被拒绝,错误会指出该 Graph 权限,而不是返回通用的 CIPP HTTP 400。
  • 比较数据按 basis 匹配。“所有租户”对应 AllTenants,“相似租户”对应 TotalSeats。这些数值已经是百分比。租户自身分数的百分比为 currentScore / maxScore;如果缺少最高分,则会省略该值,而不会报告为 0%。
CIPP 版本兼容性

请求正文根据 CIPP 自身的 Invoke-*.ps1 处理程序构造,并确保兼容当前和较旧的 CIPP 版本;如果两者存在差异,服务器会发送两者都能接受的格式。以下三种行为值得注意:

  • offboard_user 报告的是已排队,而非已完成。 CIPP 的 ExecOffboardUser 会在创建作业时立即返回 HTTP 200;它不会等待卸载结果,也不会报告结果。在将账户视为已卸载之前,请先在 CIPP 的 Offboarding 视图中确认结果。如果未选择任何操作,该工具会拒绝调用,因为否则会排入一个虽成功但不执行任何操作的作业。
  • 某些端点会在 HTTP 200 下报告失败。 EditUser、AddScheduledItem 和 ExecOffboardUser 会在 Results 中返回错误文本,而不是错误状态。这些工具会解析 Results 并返回 status: "failed";不要将 200 视为成功。
  • 两个参数需要较新的 CIPP 版本。 较旧版本会忽略 offboard_user 的 DisableOneDriveSharing 和 set_out_of_office 的 timezone,而不是报错;因此,在较旧的 CIPP 上,如果卸载操作只选择了 DisableOneDriveSharing,就不会执行任何操作。

身份验证设置

CIPP 的 API 客户端管理页面会预配 Entra ID 应用注册,并返回 OAuth 客户端 ID + 客户端密钥(而非长期有效的 Bearer 令牌)。 服务器会在每次请求时使用 OAuth 2.0 客户端凭据流交换这些信息以获取短期访问令牌,并在令牌即将过期前缓存该令牌。

  1. 在 CIPP 中,前往 Settings → CIPP Settings → Integrations → CIPP-API
  2. 创建新的 API 客户端
  3. 复制 Client ID 和 Client Secret——之后将无法再获取该密钥
  4. 使用 Function App URL 配置服务器(见下文):
    CIPP_BASE_URL=https://cippXXXXX.azurewebsites.net
    CIPP_TENANT_ID=<your-entra-tenant-id>
    CIPP_CLIENT_ID=<client-id-from-cipp>
    CIPP_CLIENT_SECRET=<client-secret-from-cipp>
    

如果已有静态 Bearer 令牌(较旧的 CIPP 部署),请改为设置 CIPP_API_KEY,并将 OAuth 变量留空。如果两者都已提供,则优先使用 CIPP_API_KEY。

访问令牌请求的范围为 api://<clientId>/.default。这是 CIPP 的 App Service 身份验证允许的 Application ID URI。若请求的范围为裸 <clientId>/.default,其 aud 会被设为客户端 ID GUID,App Service 身份验证会以 HTTP 401 和空响应体拒绝该令牌。 仍使用旧受众的部署会自动处理:未配置明确范围时,收到 401 后会使用另一个自动受众(api://<clientId>/.default 或 <clientId>/.default)重试一次。成功的受众会用于同一客户端后续的调用。如果该受众之后开始返回 401,则会取消固定该受众,并使用另一个受众重试一次,然后再次记住成功的受众。 对于其他任何状态(403、500 等),都不会重试;单个请求最多只会重试一次。设置 CIPP_TOKEN_SCOPE 可强制指定范围;设置 CIPP_TOKEN_SCOPE_FALLBACK=false(别名 TOKEN_SCOPE_FALLBACK,网关请求头 x-token-scope-fallback)可跳过重试。

查找 Function App URL

CIPP 以 Azure Static Web App(SWA)形式运行,并由 Azure Function App 提供支持。 SWA URL(你的自定义域名或 *.azurestaticapps.net)仅允许浏览器身份验证,不能用作 CIPP_BASE_URL。请改用 Function App URL。

自托管的 CIPP: 在 Azure 门户中查找 Function App(在与你的 SWA 相同的资源组中,查找 Kind: functionapp 的 App Service),或运行:

az staticwebapp show --name <your-swa-name> --resource-group <rg> \
  --query "linkedBackends[0].backendResourceId" -o tsv

由 CIPP 赞助托管: 联系 CIPP 团队,获取你的实例对应的 Function App URL——它与浏览器中显示的 URL 不同。

IP 允许列表

CIPP 会根据存储在 Azure Table Storage 中的 IPRange 字段验证每个 API 客户端。 如果服务器的公网 IP 不在此列表中,你会收到:

Access to this CIPP API endpoint is not allowed, the API Client does not have the required permission

自托管: 通过 CIPP 界面(Settings → API Client Management)添加你的 IP,或直接在 CIPP 存储帐户的 ApiClients 表中添加。

由 CIPP 赞助托管: 请 CIPP 团队将服务器的公网 IP 添加到 API 客户端的允许范围中。

许可证

Apache-2.0 — 参见 LICENSE

贡献

欢迎提交 Issue 和 PR。此服务端的跟踪事项见 wyre-technology/msp-claude-plugins#24。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。