Skip to main content
Glama
shigechika

entraadm-mcp

by shigechika

directory_audits

Retrieve Entra ID directory audit events to see who performed admin actions, when, and which targets were affected. Filter by category or user to distinguish handled actions from open incidents.

Instructions

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.

Time-bounded: the scan stops after ENTRAADM_DEADLINE seconds (default 45) and returns what it has with capped=true. Over several days the log is dominated by device-registration noise ("Update device"), so pass category (for example UserManagement, RoleManagement, GroupManagement, ApplicationManagement) to have Graph filter server-side; that keeps a multi-day window inside the budget.

Args: category: Only this Graph audit category (letters only; default: all). 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). tenant: Tenant to read: a [tenant.] section name or one of its domains (default: the default tenant).

Input Schema

NameRequiredDescriptionDefault
topNo
userNo
hoursNo
tenantNo
categoryNo
max_pagesNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.8.0
    • addedInput schema / properties / tenant
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Tenant"
      +}
  2. Changed1 schema field changedv1.1.0
    • addedInput schema / properties / category
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Category"
      +}
  3. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present the description carries the full burden and does so thoroughly: read-only, required permission (AuditLog.Read.All or Reports Reader role), 30-day retention, a hard scan deadline (ENTRAADM_DEADLINE, default 45s) that returns partial results with `capped=true`, and the important caveat that Graph only server-filters on the initiator so `user` matching is client-side and can silently miss records if the page budget runs out. This is exactly the behavioral context an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and the key operational caveats are front-loaded, and the Args block is dense and useful. Some narrative framing ('like the one that closed the 2026-08-21 case this server exists to shorten') is atmospheric rather than operational and slightly inflates the length of an otherwise tight definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter, zero-annotation, no-output-schema tool, the description covers everything material: what it returns implicitly (audit records with actor and targets), how to know results are truncated, permission and auth prerequisites, retention limits, and the performance trade-off of client-side user matching. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — the schema only has titles and defaults — so the description must compensate, and the Args block does: it defines clamp ranges for `hours` [1,720] and `top` [1,500], explains that `user` matches either actor or target side, that `category` is letters-only and server-side, and that `tenant` accepts a config section name or a domain. That is substantive meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource framing ('Who did what to the directory, and when') and immediately positions itself as 'the operator-side counterpart to signin_logs.' It enumerates the exact event types captured (block/unblock, password reset, role assignment, attribute edits) and the key fields (initiated_by, target_resources), so an agent can distinguish it from every sibling without reading the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete selection conditions: pass `category` for multi-day windows to avoid device-registration noise, raise `max_pages` when filtering by `user` because target-side matching is client-side, and use the sibling tools for sign-in rather than admin activity. It never explicitly states a 'do not use this when...' exclusion, which is the only gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.