Skip to main content
Glama
shigechika

entraadm-mcp

by shigechika

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
health_checkA

Fleet-standard health probe: service/version/status plus two independent Graph probes.

graph confirms Microsoft Graph is reachable at all (GET /users with $top=1 -- needs only User.Read.All, the minimum permission every deployment of this server needs anyway). signin_probe additionally confirms the current credential can read sign-in logs -- the permission every other tool here except get_user depends on. Both probes always run, independently of each other: a tenant that has AuditLog.Read.All but not (yet) the baseline User.Read.All would otherwise have this report "Graph unreachable" -- a fabricated diagnosis, since Graph plainly is reachable if the other probe succeeds. status is derived from the two outcomes: healthy when both succeed, degraded when exactly one does (Graph is reachable but some permission is missing), error only when neither does.

Read-only. Always returns the same keys regardless of outcome (detail is null on success, a translated message on failure), so a caller never has to branch on which keys are present.

get_userA

One account's identity/lifecycle state -- the first thing to check on any triage report.

account_enabled=false means the account itself is the whole story; stop there. A stale last_password_change_date_time alongside a fresh "wrong password" complaint (AADSTS50126 in signin_logs) is the most common on-the-ground pattern: the password changed or expired somewhere, and a cached credential on one device is now stale. on_premises_sync_enabled=true means this account is synced from an on-premises directory (Entra Connect) -- Entra is a downstream copy of its password via Password Hash Sync, not the source of truth. licenses names are resolved from the tenant's SKU catalog (/subscribedSkus, page budget from ENTRAADM_MAX_PAGES_DEFAULT); licenses_capped: true appears only when that scan was cut short before resolving one of this account's own licenses -- when present, one or more licenses entries is a raw skuId rather than a friendly name.

sign_in_activity needs an additional Graph read (AuditLog.Read.All application permission, or -- for azure-cli auth -- the Reports Reader directory role) beyond what the rest of this tool needs. If that permission is missing, every other field above still returns and sign_in_activity alone degrades to {"error": ..., "missing_permission": "AuditLog.Read.All"}.

A nonexistent account is a normal answer, not a tool failure: the result is {"found": false, "user_principal_name": upn} rather than an error key, so a typo'd UPN in a triage report cannot be mistaken for this tool being broken.

Read-only (User.Read.All application permission, or an equivalent delegated read). Requires an exact userPrincipalName, not a display name or partial match.

Args: upn: The account's userPrincipalName, e.g. "user@example.edu".

signin_logsA

One user's recent sign-in events, AADSTS-annotated.

The most direct answer to "why can't this person log in": each entry's error_code_meaning translates the raw AADSTS code (e.g. 50126 -> "invalid credentials (wrong password)") so triage rarely needs a second lookup. result filters client-side after the Graph fetch (Graph cannot filter sign-ins on status/errorCode server-side): "failure" (the default) keeps only failed attempts, "success" keeps only clean ones, "all" keeps everything.

Because the filter is client-side, this walks pages until it has collected top matching entries or exhausts max_pages -- a mostly- successful user can otherwise mean paging through hundreds of rows to find a handful of failures. capped=true means the page budget ran out (or top was reached) before the whole window was scanned; a low match count alongside capped=true is evidence of "no more found within the budget", not "no more exist".

Read-only (AuditLog.Read.All application permission, or -- for azure-cli auth -- the Reports Reader directory role). Entra ID P1 retains sign-in logs for 30 days; hours beyond that returns an empty result, not an error.

Args: user: The account's userPrincipalName. hours: How far back to look, clamped to [1, 720] (30 days). result: "failure" (default), "success", or "all". top: Maximum matching entries to return, clamped to [1, 500]. max_pages: Page budget for the client-side filter walk (default: ENTRAADM_MAX_PAGES_DEFAULT).

signin_failure_statsA

Tenant-wide sign-in failure aggregation -- the Entra ID counterpart to the RADIUS failure patrol.

Aggregates failed sign-ins across the whole tenant into four views: top AADSTS error codes (with the same meaning annotations as signin_logs), top failing users, top applications, and top source IPs. spray_suspects flags any IP with failed sign-ins against 5 or more distinct users -- Entra's smart lockout is per-account, so a low-and-slow password spray from one IP across many accounts does not trip it the way a brute force against one account does; this is the observation a per-account view cannot make on its own. This mirrors the KeyCloak-side spray detection this fleet already relies on; neither the official Microsoft MCP Server for Enterprise nor Graph itself offers this aggregation.

Read-only (AuditLog.Read.All application permission, or -- for azure-cli auth -- the Reports Reader directory role). Graph cannot filter sign-ins on status/errorCode server-side, so this walks up to max_pages of the full sign-in log for the window and aggregates client-side -- capped=true means the page budget ran out before the window was fully scanned, so the counts below are a sample of the window, not a census of it.

Args: hours: How far back to look, clamped to [1, 720] (30 days). max_pages: Page budget (default: ENTRAADM_MAX_PAGES_DEFAULT).

directory_auditsA

Who did what to the directory, and when -- the operator-side counterpart to signin_logs.

Every admin action against a user object (block/unblock, password reset, role assignment, attribute edits) appears here, naming the actor (initiated_by) and the affected object(s) (target_resources). This is the record a manual "unblock and reset" intervention -- like the one that closed the 2026-08-21 case this server exists to shorten -- leaves behind; it is how a later triage can tell "already handled by a human" from "still open".

user, when given, matches audits where that account is either the initiator or a target resource. Graph's directoryAudits endpoint only supports server-side $filter on the initiator (initiatedBy/user/userPrincipalName), not on targetResources, so this fetches the full time window and matches both sides client-side -- a window with many unrelated admin actions can need a larger max_pages budget than signin_logs/signin_failure_stats to find one specific user's audits; capped=true warns when that budget ran out before the window was fully scanned.

Read-only (AuditLog.Read.All application permission, or -- for azure-cli auth -- the Reports Reader directory role). Entra ID retains directory audit logs for 30 days, same as sign-in logs.

Args: user: Restrict to audits naming this userPrincipalName as actor or target (default: all). hours: How far back to look, clamped to [1, 720] (30 days). top: Maximum records to return, clamped to [1, 500]. max_pages: Page budget (default: ENTRAADM_MAX_PAGES_DEFAULT).

get_user_auth_methodsA

Registered authentication methods for one account -- is MFA actually set up?

mfa_registered answers "would this account survive a password-spray hit": True iff at least one non-password method is registered (Authenticator app, phone, FIDO2 security key, Windows Hello, a temporary access pass, software OATH token, or a platform credential/passkey). password itself is excluded from that count -- every account has one, so its presence alone says nothing about MFA coverage.

A nonexistent account is a normal answer, not a tool failure: the result is {"found": false, "user_principal_name": upn} rather than an error key, matching get_user's contract.

Read-only (UserAuthenticationMethod.Read.All application permission). This endpoint is app-only only: it is not exposed to delegated (azure-cli) auth under this tenant's current role assignment, so it degrades to a permission error under azure-cli auth even when other tools work.

Args: upn: The account's userPrincipalName.

daily_briefA

One-call morning-patrol summary: sign-in failures, spray suspects, and admin actions.

Combines signin_failure_stats and directory_audits into one result with a compact summary on top, matching the shape of this fleet's other daily_brief tools. A permission failure in one section degrades only that section's contribution to summary -- the other section still returns in full.

Runs both sections synchronously in one tool call, unlike the sibling gwsadm-mcp's job+poll daily_brief. If this proves too slow for a tenant's sign-in volume against the client's tool-call timeout, port that job+poll pattern here (tracked in this repo's CLAUDE.md Roadmap).

Args: hours: How far back to look, clamped to [1, 720] (30 days). max_pages: Page budget passed to both sections (default: ENTRAADM_MAX_PAGES_DEFAULT). samples: Reserved for a future drill-down sample size; currently unused.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shigechika/entraadm-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server