CIPP MCP Server
io.github.WYRE-AI/cipp-mcp
AI-powered M365 multi-tenant management for MSPs via CIPP integration
What is the CIPP MCP server?
The CIPP MCP Server is an MCP (Model Context Protocol) server that provides AI assistants with structured access to CIPP (CyberDrain Improved Partner Portal), enabling multi-tenant Microsoft 365 management for managed service providers. It exposes 45 tools across 12 categories for tenant, user, group, mailbox, security, compliance, and license management.
This server bridges AI assistants like Claude with CIPP's M365 management capabilities, allowing MSPs to automate tenant operations, user lifecycle management, security policy configuration, compliance reporting, and license tracking across multiple customer tenants. It supports both OAuth and static API-key authentication, runs in stdio or HTTP mode, and integrates with Claude Desktop and MCP Gateway.
How to install CIPP
Copy-paste configuration for popular MCP clients.
CIPP_API_URLrequiredBase URL of your CIPP API instance (e.g. https://cipp-api.example.com)
CIPP_CLIENT_IDrequiredEntra ID application (client) ID used to authenticate to CIPP
CIPP_CLIENT_SECRETrequiredsecretEntra 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_MODECredential source: 'env' reads vars locally, 'gateway' expects header injection from the WYRE MCP Gateway.
LOG_LEVELLog verbosity: debug, info, warn, error
Tools & capabilities
Tools this server exposes to the agent.
list_tenants— List all managed tenantsget_tenant_details— Get detailed information about a specific tenantlist_users— List users in a tenantcreate_user— Create a new useredit_user— Edit user propertiesdisable_user— Disable a user accountreset_password— Reset a user's passwordreset_mfa— Reset a user's MFArevoke_sessions— Revoke active user sessionsoffboard_user— Offboard a user with configurable actionsbec_check— Check for business email compromise indicatorslist_mfa_users— List users with MFA enabledlist_user_devices— List devices registered to a userlist_user_groups— List groups a user belongs tolist_groups— List groups in a tenantcreate_group— Create a new grouplist_mailboxes— List mailboxes in a tenantlist_mailbox_permissions— List mailbox permissionslist_mailbox_usage— Report mailbox and archive sizes for all mailboxes in a tenantget_mailbox_usage— Get mailbox and archive size for a single mailbox
Use cases
- Automate user provisioning, password resets, and offboarding across multiple M365 tenants
- Monitor mailbox sizes and compliance drift across customer organizations
- Query and manage Conditional Access policies and security configurations
- Generate license usage reports across CSP portfolios
- Investigate security incidents with BEC checks and audit log queries
CIPP MCP server FAQ
It's an MCP server that connects AI assistants to CIPP, a multi-tenant M365 management platform for MSPs. It provides 45 tools for managing tenants, users, mailboxes, security policies, compliance, and licenses across customer organizations.
Yes, the server itself is open-source under Apache-2.0. You need a running CIPP deployment (which is also open-source) and an API client configured in CIPP Settings.
Add the server to your `claude_desktop_config.json` with the Node.js entry point and environment variables for CIPP_BASE_URL, CIPP_TENANT_ID, CIPP_CLIENT_ID, and CIPP_CLIENT_SECRET. The CIPP_BASE_URL must be the Azure Function App URL, not the frontend SWA URL.
It supports OAuth 2.0 client-credentials flow (recommended, using Client ID and Secret from CIPP's API Client Management) or static Bearer tokens for older CIPP deployments.
Yes, CIPP validates API clients against an IP allowlist stored in Azure Table Storage. Your server's public IP must be added via the CIPP UI or by the CIPP team if using sponsored hosting.
Node.js 18+, a running CIPP deployment, and an API client created in CIPP Settings → Integrations → CIPP-API. You also need the correct Function App URL (not the frontend SWA URL).
README (reference)
Source of truth, from the repository.
CIPP MCP Server
MCP (Model Context Protocol) server for CIPP — the CyberDrain Improved Partner Portal. Provides AI assistants with structured access to CIPP's M365 multi-tenant management capabilities.
Features
- 45 tools across 12 categories
- Tenant, user, group, and mailbox management
- Mailbox and online-archive size reporting, per tenant or per user
- Security: Conditional Access policies, named locations
- 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)
npx cipp-mcp
From source
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. |
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: <clientId>/.default). |
CIPP_TOKEN_URL | No | Override OAuth token endpoint (sovereign clouds only). |
MCP_TRANSPORT | No | stdio (default) or http |
MCP_HTTP_PORT | No | Port for HTTP mode (default: 8080) |
LOG_LEVEL | No | error, warn, info (default), or debug |
[!IMPORTANT]
CIPP_BASE_URLmust 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 likecippXXXXX) in your CIPP resource group in the Azure Portal.
Usage with Claude Desktop
Add to your 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"
}
}
}
}
Note:
CIPP_BASE_URLmust be the Azure Function App URL (.azurewebsites.net), not the frontend SWA URL (.azurestaticapps.netor 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 |
| Groups | list_groups, create_group |
| Mailboxes | list_mailboxes, list_mailbox_permissions, list_mailbox_usage, get_mailbox_usage, set_out_of_office, set_email_forwarding |
| Security | list_conditional_access_policies, list_named_locations |
| 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 |
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-wide source of sizes.
Sync it from CIPP under Reports → Report Settings. If it has not been synced the
tool says so and names the remedy rather than returning an empty result.
get_mailbox_usage reports the same figures for a single mailbox and reads
live, so it needs no cache. Prefer it when the cache is unavailable or stale.
Two caveats worth knowing:
- Concealed report names blank the tenant-wide sizes. With Reports:
conceal user, group, and site names enabled in the Microsoft 365 admin
centre, Graph's usage report returns 32-character hashes instead of UPNs, so
CIPP's join against the mailbox list matches nothing and every mailbox caches
a size of
0— a tenant that reads as empty rather than as failed.list_mailbox_usagedetects this and returns a warning alongside the totals.get_mailbox_usageis unaffected: it reads the Exchange admin API directly. - Sizes are gigabyte-rounded on the per-user path. CIPP rounds to two
decimal places of a gigabyte before returning, so
get_mailbox_usagebyte counts are accurate to roughly 10 MB. Quotas are exact — they are recovered from the rawGet-Mailboxstring, which carries the true byte count.
CIPP version compatibility
Request bodies are shaped against CIPP's own Invoke-*.ps1 handlers and are
written to satisfy both current and older CIPP builds — where the two differ,
the server sends the form both accept. Three behaviours are worth knowing:
offboard_userreports queued, not completed. CIPP'sExecOffboardUserreturns HTTP 200 the instant the job is created; it never waits for or reports the offboarding result. Confirm the outcome in CIPP's Offboarding view before treating an account as offboarded. The tool refuses a call with no actions selected, since that would otherwise queue a job that succeeds while doing nothing.- Some endpoints report failure under HTTP 200.
EditUser,AddScheduledItemandExecOffboardUserreturn error text inResultsrather than an error status. These tools parseResultsand returnstatus: "failed"; do not treat a 200 as success. - Two parameters need a recent CIPP.
offboard_user'sDisableOneDriveSharingandset_out_of_office'stimezoneare ignored by older builds rather than erroring — so an offboarding that selects onlyDisableOneDriveSharingwill run no actions on an older CIPP.
Authentication Setup
CIPP's API Client Management page provisions an Entra ID app registration and returns an OAuth client ID + client secret (not a long-lived Bearer token). The server exchanges these for a short-lived access token on each request using the OAuth 2.0 client-credentials flow, and caches the token until just before its expiry.
- In CIPP, go to Settings → CIPP Settings → Integrations → CIPP-API
- Create a new API client
- Copy the Client ID and Client Secret — you will not be able to retrieve the secret later
- Configure the server with the Function App URL (see below):
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>
If you already have a static Bearer token (older CIPP deployments), set
CIPP_API_KEY instead and leave the OAuth variables unset. When both are
provided, CIPP_API_KEY wins.
Finding your Function App URL
CIPP runs as an Azure Static Web App (SWA) backed by an Azure Function App.
The SWA URL (your custom domain or *.azurestaticapps.net) enforces browser-only
auth and cannot be used as CIPP_BASE_URL. Use the Function App URL instead.
Self-hosted CIPP: Find the Function App in the Azure portal (look for an App Service
with Kind: functionapp in the same resource group as your SWA), or run:
az staticwebapp show --name <your-swa-name> --resource-group <rg> \
--query "linkedBackends[0].backendResourceId" -o tsv
CIPP-sponsored hosting: Contact the CIPP team for your instance's Function App URL — it is not the same as the URL shown in your browser.
IP Allowlist
CIPP validates each API client against an IPRange field stored in Azure Table Storage.
If your server's public IP is not in this list, you will receive:
Access to this CIPP API endpoint is not allowed, the API Client does not have the required permission
Self-hosted: Add your IP via the CIPP UI (Settings → API Client Management) or
directly in the ApiClients table of your CIPP storage account.
CIPP-sponsored hosting: Ask the CIPP team to add your server's public IP to your API client's allowed range.
License
Apache-2.0 — see LICENSE
Contributing
Issues and PRs welcome. This server is tracked against wyre-technology/msp-claude-plugins#24.
Related MCP servers

Cisco Umbrella
MCP server for Cisco Umbrella's deployment, admin, policy, reporting, and investigate APIs.

ConnectWise Automate
MCP server for ConnectWise Automate RMM — computers, clients, alerts, and scripts.
MCP server for ConnectWise CPQ (Sell) — quotes, line items, customers, terms, and templates.
View repository →
ConnectWise Manage
AI-powered ConnectWise Manage access—search tickets, log time, manage companies and projects through natural conversation.

Crewhu
MCP server for Crewhu — customer feedback (CSAT/NPS), employee engagement, and gamification.