mcpField
C
CIPP

CIPP

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

关于 CIPP

CIPP 是连接 CIPP 多租户 Microsoft 365 管理能力的 MCP 服务,面向管理多个租户的 MSP 和 AI 助手。它通过分类工具支持用户、邮箱、安全策略、许可证及合规等管理任务,并可使用 stdio 或 HTTP 传输。

主要功能

  1. 01管理租户、用户和组
  2. 02查看邮箱用量与归档容量
  3. 03查询 Entra ID 登录记录
  4. 04管理条件访问与安全评分
  5. 05检查标准、域健康和租户漂移
  6. 06处理许可证、警报和 GDAP

适用场景

  1. 01为多个租户创建或停用用户
  2. 02检查用户登录与 MFA 状况
  3. 03查看租户邮箱容量和许可证
  4. 04审查安全策略及合规偏差

MCP 相关

该 MCP 服务将 CIPP 的 Microsoft 365 多租户管理功能以结构化工具提供给 MCP 客户端,涵盖租户、用户、邮箱、安全和合规等操作。支持 stdio 与 HTTP 传输。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"wyre-ai-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-ai/cipp-mcp:v1.11.1"
],
"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-ai/cipp-mcp:v1.11.1
需要配置的环境变量
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-ai/cipp-mcp:v1.11.1

工具

还没有获取到工具列表

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

详细介绍

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 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。