Skip to main content
Glama
Intune Assignment Checker MCP

Intune Assignment Checker MCP

by ugurkocde

Intune Assignment Checker MCP

A local, read-only Model Context Protocol server for inspecting and explaining Microsoft Intune assignments through Microsoft Graph /beta.

This repository is the TypeScript port and MCP surface. The existing PowerShell product remains separate and is the behavioral reference for assignment resolution.

Intune Assignment Checker MCP overview

Explore the installation guide and security model at intuneassignmentchecker.ugurkoc.de/mcp.

Current implementation

The first delegated vertical slice is implemented:

  • Local MCP transport over stdio.

  • Interactive browser sign-in with delegated Microsoft Graph permissions.

  • OS-protected persistent MSAL cache (Windows DPAPI, macOS Keychain, or Linux libsecret), with memory-only fallback if secure persistence is unavailable.

  • get_connection_status.

  • search_policies.

  • list_all_device_assignments for direct All Devices policy and application targeting.

  • list_all_user_assignments for direct All Users policy and application targeting.

  • list_unassigned_policies for policies and applications with no assignments.

  • get_policy_assignments.

  • Strict Microsoft Graph /beta URL construction and continuation validation.

  • Bounded calls, pages, execution time, response bytes, retries, and result sizes.

  • Opaque, one-time, tenant-bound MCP cursors; raw Graph @odata.nextLink values never enter model context.

  • Complete page records and opaque continuation cursors in both model-visible text and typed structuredContent for client compatibility.

  • Assignment collections reconcile Graph's sometimes-stale isAssigned flag; duplicate policy names require stable ID-based disambiguation.

  • Explicit partial-coverage and delegated-RBAC uncertainty reporting.

The one production app registration has been created, its public-client ID is embedded, and the package is available from npm. The code contains no second development registration. The embedded client ID also makes source builds testable without supplying a separate registration.

Related MCP server: sql-server-mcp

Architecture

AI client
  -> local stdio MCP process
     -> MSAL delegated sign-in in the user's browser
     -> OS-protected local token cache
     -> internally generated, read-only Microsoft Graph /beta requests

There is no hosted MCP endpoint, Auth0 tenant, customer token database, service certificate, or server-side Graph token exchange.

Install from npm

Requirements: Node.js 20 or newer and a supported local stdio MCP client. The client launches the package on demand; users do not install it globally or create an Entra app registration, client secret, or certificate.

Claude Desktop

Open Settings → Developer → Edit Config and add:

{
  "mcpServers": {
    "intune-assignment-checker": {
      "command": "npx",
      "args": ["-y", "intune-assignment-checker-mcp@latest"]
    }
  }
}

Restart Claude Desktop after saving the configuration.

Claude Code

Add the server at user scope so it is available in every project:

claude mcp add --transport stdio --scope user intune-assignment-checker -- npx -y intune-assignment-checker-mcp@latest

Run claude mcp list or open /mcp inside Claude Code to verify the connection.

ChatGPT Desktop and Codex

The ChatGPT desktop app, Codex CLI, and the Codex IDE extension share MCP configuration on the same machine. Add the server with:

codex mcp add intune-assignment-checker -- npx -y intune-assignment-checker-mcp@latest

The equivalent ~/.codex/config.toml entry is:

[mcp_servers.intune-assignment-checker]
command = "npx"
args = ["-y", "intune-assignment-checker-mcp@latest"]

Cursor

Add this server to Cursor's MCP configuration:

{
  "mcpServers": {
    "intune-assignment-checker": {
      "command": "npx",
      "args": ["-y", "intune-assignment-checker-mcp@latest"]
    }
  }
}

VS Code

Add this server through MCP: Add Server or place the following in the appropriate VS Code mcp.json file:

{
  "servers": {
    "intune-assignment-checker": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "intune-assignment-checker-mcp@latest"]
    }
  }
}

First use

Ask the client an Intune assignment question. The first functional tool call opens Microsoft sign-in in the browser. After delegated consent, the MCP stores the token cache under the current OS user's protection and reuses it on later launches. Sign in or revoke the local cache explicitly with:

npx -y intune-assignment-checker-mcp@latest login
npx -y intune-assignment-checker-mcp@latest status
npx -y intune-assignment-checker-mcp@latest logout

ChatGPT Web and Claude.ai cannot directly launch an npx process on the user's machine. This local installation path targets their desktop clients and other local stdio MCP hosts.

Local development

Requirements: Node.js 20 or newer. Linux secure persistence also requires a Secret Service implementation such as GNOME Keyring/libsecret.

npm install
npm run check
npm run build

The production client ID is embedded. IAC_MCP_CLIENT_ID remains available only as an explicit override for controlled testing:

export IAC_MCP_CLIENT_ID="your-test-public-client-id"

Optionally pin guest or multi-tenant administrators to a specific tenant GUID:

export IAC_MCP_TENANT_ID="your-tenant-id"

Sign in explicitly, or let the first functional tool open sign-in:

node dist/index.js login
node dist/index.js status
node dist/index.js logout

For a headless session:

node dist/index.js login --device-code

Set IAC_MCP_AUTO_SIGN_IN=false if model-triggered tool calls must return auth_required instead of opening a browser.

Diagnostics

The server logs to stderr only; stdout stays reserved for MCP JSON-RPC framing. Set IAC_MCP_LOG_LEVEL to debug, info (default), warn, or error. The startup line includes the running version, and every tool result carries a correlation ID that matches a stderr entry:

export IAC_MCP_LOG_LEVEL=debug
node dist/index.js --version

MCP client configuration during development

Build first, then point the client to the absolute local file:

{
  "mcpServers": {
    "intune-assignment-checker": {
      "command": "node",
      "args": ["/absolute/path/to/IntuneAssignmentChecker-MCP/dist/index.js"]
    }
  }
}

The public npx configurations are documented in Install from npm.

The one Entra app registration

The standard path uses exactly one publisher-owned registration named Intune Assignment Checker MCP:

  • Supported accounts: any organizational directory.

  • Public/native client; no client secret or certificate.

  • Delegated Graph permissions only.

  • Loopback redirect URI: http://localhost.

  • Authority: organizations, with IAC_MCP_TENANT_ID override.

  • No exposed MCP API and no application Graph permissions.

The current tools request only:

  • DeviceManagementConfiguration.Read.All

  • DeviceManagementApps.Read.All

  • GroupMember.Read.All

Additional delegated permissions will be added to this same registration only when the tools that use them ship. CloudPC.Read.All remains optional and is not part of the current consent bundle.

The publisher-only setup script is idempotent, requires the intended publisher tenant GUID, and supports -WhatIf:

./scripts/Register-IntuneAssignmentCheckerMcpApp.ps1 -TenantId '<publisher-tenant-guid>' -WhatIf
./scripts/Register-IntuneAssignmentCheckerMcpApp.ps1 -TenantId '<publisher-tenant-guid>'

The script refuses an unexpected tenant, another API, or application permissions, and always converges on the exact three current read-only delegated scopes. It does not grant customer consent. The production registration was created and read back through Microsoft Graph /beta; live delegated consent and tool calls are verified separately before package publication.

Security and privacy boundaries

  • Tokens never appear in tool arguments, tool results, stdout, or application logs.

  • stdout is reserved for MCP JSON-RPC; diagnostics use stderr.

  • No tool accepts a Graph URL or arbitrary Graph path.

  • Graph redirects are rejected rather than followed.

  • Policy, group, and filter names are untrusted data: control characters are stripped and lengths are bounded.

  • Delegated Intune RBAC can silently narrow successful Graph results. Coverage reports this uncertainty; an empty result is not proof that the tenant has no matching object.

  • Policy names, group names, filter rules, and other returned fields are sent by the MCP client to its configured model provider. Tokens and raw Graph payloads are not.

  • Secure cache initialization never falls back to an unencrypted token file. If the OS keyring is unavailable, tokens remain in memory for that process only.

Because this is a shared multi-tenant public client, the publisher registration itself is security-critical. Its owners should use phishing-resistant MFA and privileged access controls, and changes to redirect URIs, permissions, or credentials should be monitored.

Supported policy categories

The first slice includes configuration policies, device configurations, compliance policies, mobile applications, and managed app configuration policies. Search uses client-side matching because Intune $filter/$search behavior is inconsistent across these collections.

The live verification tenant confirmed that these collections can return @odata.nextLink, assignment targets are polymorphic and include assignment-filter fields, empty value arrays are valid, and @odata.type is returned automatically but rejected when placed in $select.

Verification

npm run format:check
npm run lint
npm run typecheck
npm test
npm run build
npm audit

The tests cover URL and /beta enforcement, opaque cursor isolation, throttling, polymorphic targets, filter/group normalization, category contracts, and an in-memory MCP client/server exchange.

Automated PowerShell parity

The PowerShell module remains the behavioral reference, but synchronization is now enforced rather than assumed:

  1. Tests/Parity/Export-McpParityFixtures.ps1 in the PowerShell repository generates a deterministic, versioned Graph beta fixture.

  2. PowerShell Pester tests fail when that committed fixture is stale.

  3. npm run parity:sync vendors the fixture into this repository.

  4. The TypeScript parity suite runs the same raw policies, polymorphic targets, filters, groups, app intents, and platform values through the MCP normalizer.

  5. Cross-repository CI fails until the TypeScript result matches the current PowerShell result.

Run the complete local handoff from this repository with:

npm run parity:sync
npm run parity:check
npm run check
npm run build

The MCP workflow also checks the PowerShell main branch every day. In the PowerShell GitHub repository, set the Actions variable IAC_MCP_REPOSITORY=ugurkocde/IntuneAssignmentChecker-MCP after this repository is published. If the MCP repository is private, also add an IAC_MCP_REPOSITORY_TOKEN secret with read access. Until that remote exists and the variable is configured, the PowerShell-side cross-repository job is safely skipped; local parity and the PowerShell fixture-drift test remain active.

This automation detects and blocks behavioral drift. It deliberately does not translate arbitrary PowerShell into TypeScript. After a reviewed version change is released on GitHub, the npm publication is performed by the provenance-enabled workflow documented in RELEASING.md.

Available Tools

6 tools
get_connection_statusGet Intune connection statusA
Read-onlyIdempotent

Checks local delegated Microsoft authentication without returning or logging any token.

Inputs: no named parameters. Returns: state, status, message, tenantId, +7 more

get_policy_assignmentsGet Intune policy assignmentsA
Read-onlyIdempotent

Returns normalized include, exclude, all-user, all-device, group, intent, and assignment-filter details for one supported policy. It never accepts a Graph URL or path.

Inputs: category (required), policyId (required), limit, cursor. Returns: policy, status, coverage, tenantId, +5 more

list_all_device_assignmentsList assignments targeting All DevicesA
Read-onlyIdempotent

Lists policies and applications that directly target All Devices. For questions about apps assigned to All Devices, set category to application. Results include policyId, app or policy name, application intent when available, assignment filters, pageSummary, coverage, and an opaque continuation cursor. resultCount, pageSummary, and graphUsage describe only the current tool call; follow nextCursor for complete coverage.

Inputs: limit, cursor, category, platform. Returns: status, coverage, tenantId, graphUsage, +5 more

list_all_user_assignmentsList assignments targeting All UsersA
Read-onlyIdempotent

Lists policies and applications that directly target All Users. For questions about apps assigned to All Users, set category to application. Results include policyId, app or policy name, application intent when available, assignment filters, pageSummary, coverage, and an opaque continuation cursor. resultCount, pageSummary, and graphUsage describe only the current tool call; follow nextCursor for complete coverage.

Inputs: limit, cursor, category, platform. Returns: status, coverage, tenantId, graphUsage, +5 more

list_unassigned_policiesList unassigned Intune policiesA
Read-onlyIdempotent

Lists supported Intune policies and applications whose assignment collection is empty. For unassigned apps, set category to application. Results include stable policy IDs, category IDs, platform metadata, pageSummary, explicit coverage, and an opaque continuation cursor. graphUsage describes only the current tool call; resultCount is the number of records on this page.

Inputs: limit, cursor, category, platform. Returns: status, records, coverage, tenantId, +5 more

search_policiesSearch Intune policiesA
Read-onlyIdempotent

Searches supported Intune policy and application categories through internally generated Microsoft Graph /beta requests. Every record returns an id and categoryId; pass those values as policyId and category to get_policy_assignments. Display names are not unique: never silently choose one record when multiple results match. Search isAssigned values are Graph-reported hints; get_policy_assignments reconciles them against the assignment collection. Results can be RBAC-filtered for the signed-in administrator.

Inputs: limit, query, cursor, category, +1 more. Returns: status, records, coverage, tenantId, +4 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool has a clear, distinct purpose: auth check, search, two scoped listing tools (device vs user), unassigned listing, and per-policy details. The names and descriptions make boundaries obvious, with no overlapping responsibilities.

    Naming Consistency5/5

    All tools use a consistent lowercase snake_case verb_noun pattern: get_*, search_*, list_*. Scoped variations (list_all_, list_unassigned_) are predictable and readable, with no mixed conventions.

    Tool Count5/5

    6 tools is well-scoped for an Intune assignment checker, covering authentication, policy discovery, assignment scopes, and detailed lookups without bloat or redundancy.

    Completeness5/5

    The tool set covers all core read-only workflows: find policies, see All Device/All User assignments, identify unassigned policies, and inspect detailed assignments for a single policy. No obvious dead ends for the stated checker purpose.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      A Model Context Protocol server for Microsoft 365 administration using Graph API application permissions, enabling security monitoring, identity audits, incident response, and service health management.
      96 npm
      19
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      A local MCP server for read-only SQL Server / MS Fabric queries. It authenticates as the user via Entra ID and runs one server process per tenant.
      4
      27 PyPI
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      A read-only MCP server for Microsoft Intune and Entra ID that enables list, get, search, and reporting operations for tenant visibility, audits, troubleshooting, and health reporting without write actions. It includes authentication helpers, report exports, and metadata discovery tools.
      36
      1
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Read-only MCP server for Microsoft Entra ID (Azure AD) that enables querying user sign-in logs, group memberships, and assigned Microsoft 365 licenses via Microsoft Graph API. Provides security and audit visibility without any write operations.
      -