Skip to main content
Glama
shigechika

entraadm-mcp

by shigechika

compromise_suspects

Identifies probable account takeovers in Entra ID sign-in logs by flagging password-spray breaches, foreign sign-ins, and Microsoft risky users for triage.

Instructions

Accounts that were probably taken over, from one walk of the sign-in log.

The success-side counterpart of signin_failure_stats' spray suspects. Two findings, both from EXTERNAL source IPs (outside the address ranges in ENTRAADM_SITES_INI; without that file every IP counts as external):

  • spray_breaches (severity high): an IP with credential failures (wrong password, unknown, locked or disabled account -- not MFA prompts, session interrupts or Conditional Access blocks, which follow a correct password) for min_spray_users or more distinct accounts in the window AND a successful sign-in as at least one account. Without internal ranges (ENTRAADM_SITES_INI unset or unreadable, internal_ranges_known: false) these are medium with a note: the tenant's own NAT egress can look like a spray source. One row per account and IP: failed_distinct_users from that IP, first/last success, client apps, countries, legacy_auth. The strongest signal: a spray that found a working password.

  • foreign_successes: successes from a country outside ENTRAADM_HOME_COUNTRIES (assigned ISO 3166-1 alpha-2 codes, e.g. "JP"; one invalid code disables this list, see home_countries.error), grouped per account with countries, the most used IPs (10, with counts), client apps, first/last, and home_success_in_window (the account also signed in from a home country or an internal IP in the window; null when not seen in a capped scan, since the unread part may hold it). high when a legacy protocol was used (password only, no MFA) or the account is also a high spray_breaches entry; medium otherwise. Unset home countries: home_countries.configured is false and this list stays empty -- nothing is guessed. A success with no country is never called foreign.

  • microsoft_risky_users: Microsoft's own verdicts from Identity Protection, which needs Entra ID P2 and the optional IdentityRiskyUser.Read.All permission. A cheap probe (cached per tenant) decides: without P2 the section is {"available": false, "reason": "not_licensed" | "hidden" | "no_permission" | "error"} and nothing else changes -- never read it as "no risky users". With P2: open (atRisk / confirmedCompromised) high and, separately, medium risky users (50 each, *_capped), each marked when also in spray_breaches / foreign_successes.

counts are distinct accounts over every finding (case-insensitive, counted before the lists are cut): high is any account high in this tool's own lists or in Microsoft's high list; medium is any account medium here or in Microsoft's medium list that is not high. With P2, microsoft_high / microsoft_medium say how many accounts Microsoft lists. Lists are capped at 50 (*_capped). how_to_read says what to act on. Like signin_failure_stats this walks the interactive sign-in log for the window (every legacy-protocol authentication is interactive) under ENTRAADM_DEADLINE; capped=true means the window was not fully read and the findings are a lower bound.

Read-only (AuditLog.Read.All application permission, or -- for azure-cli auth -- the Reports Reader directory role; IdentityRiskyUser.Read.All, optional, for microsoft_risky_users).

Args: hours: How far back to look, clamped to [1, 720] (30 days). tenant: Tenant to read: a [tenant.] section name or one of its domains (default: the default tenant). min_spray_users: Distinct failed accounts that make an IP a spray source (default 5, clamped to >= 2). max_pages: Page budget (default: ENTRAADM_MAX_PAGES_DEFAULT).

Input Schema

NameRequiredDescriptionDefault
hoursNo
tenantNo
max_pagesNo
min_spray_usersNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv1.8.0

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so thoroughly: it states read-only access, required permissions, optional Identity Protection permission, behavior when P2 is absent, how ENTRAADM_SITES_INI and ENTRAADM_HOME_COUNTRIES affect judgments, capping behavior, lower-bound semantics under deadline, and the crucial warning not to read unavailable Microsoft risk data as 'no risky users'.

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 description is front-loaded with purpose and the main findings, and its bullet structure makes a complex tool readable. It is still very long and dense, with some repetition and parenthetical detail, but much of that detail substitutes for a missing output schema.

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 complex read-only tool with no output schema and no annotations, the description is complete: it explains return sections, severity rules, count semantics, caps, environment dependencies, permissions, and the meaning of partial scans. An agent has enough information to call and interpret the tool correctly.

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 description coverage is 0%, so the description must fully annotate parameters. Its Args section defines all four: hours clamped to [1, 720], tenant as a section name or domain, min_spray_users default/clamp, and max_pages defaulting to an environment value.

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?

The description states a precise purpose: finding accounts probably taken over from one walk of the sign-in log. It explicitly positions itself as the success-side counterpart of signin_failure_stats' spray suspects, so an agent can distinguish it from sibling tools without opening schemas.

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?

It clearly names signin_failure_stats as the contrasting failure-side tool and explains what findings this tool returns, but it does not explicitly state when to choose it over signin_success_stats, signin_by_ip, or daily_brief. The usage context is clear but lacks explicit exclusions or decision criteria.

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