Skip to main content
ClaudeWave

MCP server for CIPP (CyberDrain Improved Partner Portal) — M365 multi-tenant management, users, security, and standards for MSPs

MCP ServersOfficial Registry11 stars12 forks● TypeScriptNOASSERTIONUpdated today
ClaudeWave Trust Score
80/100
✓ Trusted
Passed
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Flags
  • !Licence file present but not machine-readable
Last scanned: 10/21/2026
Install in Claude Code / Claude Desktop
Method: NPX · cipp-mcp
Claude Code CLI
claude mcp add cipp-mcp -- npx -y cipp-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "cipp-mcp": {
      "command": "npx",
      "args": ["-y", "cipp-mcp"],
      "env": {
        "CIPP_BASE_URL": "<cipp_base_url>",
        "CIPP_CLIENT_SECRET": "<cipp_client_secret>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
CIPP_BASE_URLCIPP_CLIENT_SECRET
Use cases

MCP Servers overview

# CIPP MCP Server

MCP (Model Context Protocol) server for [CIPP](https://github.com/CyberDrain/CIPP) — the CyberDrain Improved Partner Portal. Provides AI assistants with structured access to CIPP's M365 multi-tenant management capabilities.

## Features

- **49 tools** across 12 categories
- Tenant, user, group, and mailbox management
- Mailbox and online-archive size reporting, per tenant or per user
- Per-user Entra ID sign-in logs (status, location, Conditional Access, MFA)
- Security: Conditional Access policies, named locations, Microsoft Secure Score
- Standards & compliance: BPA, domain health, drift detection
- License reporting (per-tenant and CSP-wide)
- Alerts, audit logs, and scheduled tasks
- GDAP role and invite management
- Stdio and HTTP transport modes
- MCP Gateway compatible

## Prerequisites

- Node.js 18+
- A running CIPP deployment
- CIPP API Key (generated from CIPP Settings → API Client Management)

## Installation

### Via npm (once published)

```sh
npx cipp-mcp
```

### From source

```sh
git clone https://github.com/WYRE-AI/cipp-mcp
cd cipp-mcp
npm install
npm run build
```

## Configuration

Set these environment variables (or copy `.env.example` to `.env`):

| Variable | Required | Description |
|---|---|---|
| `CIPP_BASE_URL` | Yes | Your CIPP **Azure Function App** URL (e.g. `https://cippXXXXX.azurewebsites.net`). **Do not use the SWA / frontend URL** — see [Finding your Function App URL](#finding-your-function-app-url). |
| `CIPP_API_KEY` | One of | Static Bearer token. Use this **or** the OAuth trio below. |
| `CIPP_TENANT_ID` | One of | Entra tenant ID that owns the CIPP API-client app registration. |
| `CIPP_CLIENT_ID` | One of | OAuth client ID issued by CIPP's API Client Management page. |
| `CIPP_CLIENT_SECRET` | One of | OAuth client secret paired with `CIPP_CLIENT_ID`. |
| `CIPP_TOKEN_SCOPE` | No | Override OAuth scope. Default: `api://<clientId>/.default`. An explicit value disables the legacy-scope fallback below. |
| `CIPP_TOKEN_SCOPE_FALLBACK` | No | When no explicit scope is set, retry a CIPP HTTP 401 once with the legacy `<clientId>/.default` scope and reuse whichever audience this client accepts. Default: `true`. `TOKEN_SCOPE_FALLBACK` is an alias. Gateway requests can send `x-token-scope-fallback`. |
| `CIPP_TOKEN_URL` | No | Override OAuth token endpoint (sovereign clouds only). |
| `MCP_TRANSPORT` | No | `stdio` (default) or `http` |
| `AUTH_MODE` | No | `env` (stdio and single-tenant HTTP) or `gateway`. Gateway mode requires CIPP credential headers on each `/mcp` request and does not fall back to `CIPP_*`. The container image and the Compose gateway service set `gateway`. |
| `CONDUIT_S2S_SECRET` | Yes for HTTP | Service-to-service secret shared with the gateway. HTTP logs an error and exits non-zero when this is empty, whitespace, or a known placeholder (`changeme`, `change-me`, `your-s2s-secret`, `your-secret`, `placeholder`, `secret`, `example`, `replace-me`, `replace-with-a-real-secret`, `s2s-secret`, or an unresolved `${...}` value). Compose will not start without it. Never commit a real value. |
| `MCP_ALLOW_INSECURE_DEV` | No | Set to exactly `1` only for local development to start HTTP without `CONDUIT_S2S_SECRET`. The process logs a warning, does not enforce `X-Gateway-S2S`, and listens on `127.0.0.1` only. A non-loopback `MCP_HTTP_HOST` is ignored and the override is logged. This flag does not bypass a known placeholder. |
| `MCP_HTTP_HOST` | No | Bind address when `MCP_TRANSPORT=http` and `CONDUIT_S2S_SECRET` is set. Defaults to `127.0.0.1` when unset. The container image sets `0.0.0.0`. |
| `MCP_HTTP_PORT` | No | Port for HTTP mode (default: 8080) |
| `LOG_LEVEL` | No | `error`, `warn`, `info` (default), or `debug` |

> [!IMPORTANT]
> `CIPP_BASE_URL` must be the **Azure Function App** URL — the CIPP-API backend,
> `https://<function-app-name>.azurewebsites.net` — **not** the Static Web App /
> custom-domain UI URL (e.g. `https://cipp.yourdomain.com`). The SWA's built-in
> auth intercepts bearer tokens and redirects them to its interactive login page,
> so every API call fails. Find the Function App (named like `cippXXXXX`) in your
> CIPP resource group in the Azure Portal.

`/health` stays unauthenticated and does not read credentials. The stdio transport does not use `CONDUIT_S2S_SECRET`.

### HTTP authentication

With `MCP_TRANSPORT=http` and `CONDUIT_S2S_SECRET` set, every `/mcp` request must include `X-Gateway-S2S`. The header value is `t=<unix seconds>,v1=<hex>`, where `v1` is the hex-encoded HMAC-SHA256 of the ASCII string `t=<unix seconds>` keyed with `CONDUIT_S2S_SECRET`. The timestamp must be within 300 seconds of the server clock. A missing or invalid header is HTTP 401, before CIPP credentials are read. The secret is never written to logs.

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

In `AUTH_MODE=gateway`, `/mcp` also requires `x-base-url` plus either `x-api-key` or all of `x-tenant-id`, `x-client-id`, and `x-client-secret` (`x-token-scope`, `x-token-url`, and `x-token-scope-fallback` are optional). Those headers are the only CIPP credential source for that request. A request missing them is HTTP 401 and does not use `CIPP_*` from the process environment.

`AUTH_MODE=env` still requires a valid `X-Gateway-S2S` header, then uses `CIPP_*` from the environment.

Local HTTP without a secret is development-only. It binds `127.0.0.1` even when `MCP_HTTP_HOST` is `0.0.0.0` or another non-loopback address:

```bash
MCP_TRANSPORT=http MCP_ALLOW_INSECURE_DEV=1 npm run dev
```

### Docker

The image listens on `0.0.0.0` inside the container (`MCP_HTTP_HOST`) and defaults to `AUTH_MODE=gateway`. Publish the port on loopback and pass the same S2S secret the gateway uses. In gateway mode, CIPP credentials arrive on each request as headers; they are not read from the environment.

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

Compose refuses to start when `CONDUIT_S2S_SECRET` is unset. The `cipp-mcp` service is gateway mode: it sets `AUTH_MODE=gateway`, publishes `127.0.0.1:8080:8080`, and does not set `CIPP_API_KEY`, `CIPP_CLIENT_ID`, `CIPP_CLIENT_SECRET`, `CIPP_TENANT_ID`, `CIPP_BASE_URL`, or `env_file`.

```bash
CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" docker compose up
```

Single-tenant HTTP (`AUTH_MODE=env`) still requires the S2S secret, then uses `CIPP_*`:

```bash
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
```

## Usage with Claude Desktop

Add to your `claude_desktop_config.json`:

```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"
      }
    }
  }
}
```

> **Note:** `CIPP_BASE_URL` must be the Azure **Function App** URL (`.azurewebsites.net`), not
> the frontend SWA URL (`.azurestaticapps.net` or your custom domain). The SWA enforces
> browser-based auth and will redirect all API requests to a Microsoft login page.

## Tools

| Category | Tools |
|---|---|
| Tenants | list_tenants, get_tenant_details |
| Users | 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 |
| Groups | list_groups, create_group |
| Mailboxes | list_mailboxes, list_mailbox_permissions, list_trusted_blocked_senders, list_mailbox_usage, get_mailbox_usage, set_out_of_office, set_email_forwarding |
| Security | list_conditional_access_policies, list_named_locations, get_secure_score, list_secure_score_controls |
| Applications | list_enterprise_apps |
| Standards | 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 |
| Licenses | list_licenses, list_csp_licenses |
| Alerts | list_audit_logs, list_alert_queue |
| GDAP | list_gdap_roles, list_gdap_invites |
| Scheduler | list_scheduled_items, add_scheduled_item |
| Core | ping, get_version, list_logs |

### Editing a user right after creating it

`edit_user` first resolves the account's current UPN, because CIPP's
`Invoke-EditUser` rebuilds the UPN from `username` + `Domain` on every call and
editing without it would rename the account. Graph can lag a few seconds behind
a just-created account, so when that lookup finds nothing, answers HTTP 404, or
fails with a 5xx whose body is Graph's not-found (the `Request_ResourceNotFound`
code, or Graph's "Resource '<id>' does not exist or one of its queried
reference-property objects are not present" message), it is retried up to 4 attempts in total, waiting 1s, 3s and
6s (~10s). The decision uses the HTTP status, not message text; any other 4xx
(400, 401, 403) and other 5xx are not retried. If the user still isn't visible
the error says "Tried N times" and, when the last attempt got an HTTP error,
its status; wait a moment and retry.

### Mailbox and archive sizes

`list_mailbox_usage` reports every mailbox in a tenant — primary size, item
count, quota, percent of quota, and the same four figures for the online
archive — sorted largest first, with tenant-wide totals that cover every
mailbox even when only the top rows are returned.

**It requires CIPP's reporting database to have been synced for that tenant.**
This is not a design choice: `Invoke-ListMailboxes`' live Exchange query selects
no size fields at all, so the cache is the only tenant-wi
cippm365mcpmcp-servermspmsp-mcpwyre-technology

What people ask about cipp-mcp

What is WYRE-AI/cipp-mcp?

+

WYRE-AI/cipp-mcp is mcp servers for the Claude AI ecosystem. MCP server for CIPP (CyberDrain Improved Partner Portal) — M365 multi-tenant management, users, security, and standards for MSPs It has 11 GitHub stars and its last recorded update is dated 2026-10-21.

How do I install cipp-mcp?

+

You can install cipp-mcp by cloning the repository (https://github.com/WYRE-AI/cipp-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is WYRE-AI/cipp-mcp safe to use?

+

Our security agent has analyzed WYRE-AI/cipp-mcp and assigned a Trust Score of 80/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.

Who maintains WYRE-AI/cipp-mcp?

+

WYRE-AI/cipp-mcp is maintained by WYRE-AI. The last recorded GitHub activity is dated 2026-10-21, with 4 open issues.

Are there alternatives to cipp-mcp?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy cipp-mcp to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: WYRE-AI/cipp-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/wyre-ai-cipp-mcp)](https://claudewave.com/repo/wyre-ai-cipp-mcp)
<a href="https://claudewave.com/repo/wyre-ai-cipp-mcp"><img src="https://claudewave.com/api/badge/wyre-ai-cipp-mcp" alt="Featured on ClaudeWave: WYRE-AI/cipp-mcp" width="320" height="64" /></a>

More MCP Servers

cipp-mcp alternatives