Skip to main content
Glama
mcpAD

mcpAD

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
MCP_HOSTNoHost/interface to bind when using an HTTP or SSE transport. Default is commonly 127.0.0.1 for local setups.
MCP_PORTNoPort to listen on when using an HTTP or SSE transport. Default is typically 8000 in the provided Makefile examples.
MSAD_DOMAINNoDefault domain when a tool call omits `domain`. Overrides the `[defaults] domain` setting in the msad config file.
MCP_TRANSPORTNoMCP transport to use. Can be 'stdio', 'streamable-http', or 'sse'. Defaults to 'stdio'.stdio
MSAD_CONFIG_FILENoPath to an alternative TOML configuration file. Defaults to ~/.msad.toml if not set.
KRB5_CLIENT_KTNAMENoPath to a Kerberos keytab file, used when running as an unattended service instead of relying on a kinit ticket cache.

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": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
test_connectionA

Test connectivity and bind to the AD server without raising.

Returns a status dict with ok, target, auth and error. Use this to verify the configuration and reachability before running other tools.

whoamiA

Report the identity the connection is bound as.

Uses the RFC 4532 "Who Am I?" extended operation: the directory server reports the identity it actually authenticated, working with Kerberos/ SASL-GSSAPI as well as simple user/password bind. Returns {"authzid": ...}.

healthB

Server health check: reports server name, mcpAD/msad version and AD connectivity.

find_usersB

Find AD users by field. Criteria are ANDed; values may contain * wildcards.

city/state/country match the l/st/co attributes. Pass base (a DN, e.g. an OU) to restrict the search to a subtree.

get_userA

Get a single AD user by sAMAccountName, UPN, mail or cn (exact match).

find_groupsB

Find AD groups by cn/name/sAMAccountName/displayName (supports * wildcards).

Pass base (a DN, e.g. an OU) to restrict the search to a subtree.

get_groupA

Get a single AD group by sAMAccountName or cn (exact match).

get_by_dnA

Fetch any AD entry directly by its distinguished name (DN).

Use this to resolve DN-valued attributes into full records, e.g. the manager of a user or the managedBy owner of a group. Returns None if the DN does not exist.

find_contactsA

Find AD contact objects by cn/mail/displayName (supports * wildcards).

Passing no string matches every contact. Pass base (a DN, e.g. an OU) to restrict the search to a subtree.

find_computersA

Find AD computers by cn (name), dNSHostName (dns) or operatingSystem (os).

Criteria are ANDed; values may contain * wildcards. Set exclude_domain_controllers=True to drop domain controllers from the results. Pass base (a DN, e.g. an OU) to restrict the search to a subtree.

get_computerA

Get a single AD computer by sAMAccountName, cn or dNSHostName (exact match).

find_ousB

Find AD organizational units (OUs) by name (matches ou; may contain *).

Pass base (a DN) to search under a specific parent OU instead of the whole domain.

get_ouA

Get a single AD organizational unit by its ou name or full DN (exact).

find_empty_ousA

Find organizational units with no nested sub-OU (hygiene/audit).

Matches OUs whose ou attribute has no children. Pass base (a DN) to scope to a parent OU.

get_ou_contentsB

List the objects contained under an OU (given its DN).

Optionally restrict to a single object_class (e.g. user, group, computer, organizationalUnit). Returns an empty list if the OU DN does not exist.

find_inactive_usersA

Find users whose last logon is older than days (default 90).

Matches lastLogonTimestamp at or before the cutoff. Set include_never=True to also return users that never logged on. Pass base (a DN) to scope to an OU.

find_stale_computersB

Find computers whose last logon is older than days (default 90).

Matches lastLogonTimestamp at or before the cutoff. Set include_never=True to also return computers that never logged on. Pass base (a DN) to scope to an OU.

get_domain_infoB

Read the domain object: security-relevant settings and metadata (audit).

get_password_policyB

Read the default domain password policy (maxPwdAge, minPwdLength, ...).

get_password_policy_violationsA

Find users whose password violates the domain policy (audit).

Flags enabled users whose password has expired (older than the domain maxPwdAge) and, when include_never_set is True, users who must set a password at next logon (pwdLastSet=0). Accounts whose password never expires are excluded. Returns an empty list if the domain has no maximum password age.

get_privileged_groupsA

Report on well-known privileged groups (Domain Admins, ...) with counts.

Each entry includes the group's attributes plus member_count. Set with_members=True to include a members list (use nested=True to expand nested membership).

group_membersB

List members of a group. Set nested=True for recursive membership.

user_groupsB

List the groups a user belongs to (nested/recursive by default).

is_memberB

Return True if the user is a (nested) member of the group.

is_disabledB

Return True if the account is disabled, None if the user is not found.

is_lockedB

Return True if the account is locked, None if the user is not found.

disabled_usersA

List disabled user accounts (userAccountControl flag 2).

Audit counterpart of is_disabled: returns every disabled account instead of checking a single user. Pass base (a DN) to scope to an OU, or extra_filter to AND an extra raw LDAP clause (must be pre-escaped).

locked_usersA

List locked-out user accounts (lockoutTime >= 1).

Audit counterpart of is_locked: returns every locked account instead of checking a single user. Pass base (a DN) to scope to an OU, or extra_filter to AND an extra raw LDAP clause (must be pre-escaped).

never_expires_passwordA

List users whose password never expires (userAccountControl flag 65536).

A common security-audit check. Pass base (a DN) to scope to an OU, or extra_filter to AND an extra raw LDAP clause (must be pre-escaped).

never_expiring_accountsA

List users whose ACCOUNT (not password) never expires.

Matches accountExpires set to the "never" sentinel values (0 or 9223372036854775807). Distinct from never_expires_password, which checks the password-never-expires UAC flag instead. Pass base (a DN) to scope to an OU.

expired_accountsB

List users whose accountExpires date is in the past (excluding "never").

Pass base (a DN) to scope to an OU.

password_not_requiredA

Risk: list users with the PASSWD_NOTREQD UAC flag (account may have no password).

These accounts may have no password at all, letting anyone authenticate as them and set their own. Pass base (a DN) to scope to an OU.

kerberos_preauth_not_requiredA

Risk: list users not requiring Kerberos pre-authentication.

These accounts are vulnerable to offline (AS-REP roasting) password guessing. Pass base (a DN) to scope to an OU.

not_delegatedA

Risk: list accounts flagged "sensitive and cannot be delegated".

Worth auditing when a sensitive privilege was granted without also excluding the account from delegation (or vice versa). Pass base (a DN) to scope to an OU.

find_service_accountsB

Risk: list users with a Service Principal Name (SPN) set.

Any account with an SPN can have a Kerberos service ticket requested for it by any authenticated user, then cracked offline ("Kerberoasting") if its password is weak. Pass base (a DN) to scope to an OU.

find_admin_count_accountsB

Find users with adminCount=1 (current or stale protected-admin marker).

AD sets adminCount=1 via AdminSDHolder on members of protected groups (Domain Admins, Enterprise Admins, ...) and does not automatically clear it once the account is later removed from every such group. Accounts that still carry adminCount=1 but are no longer privileged keep a non-inherited, hardened ACL and are a common audit finding. Pass base (a DN) to scope to an OU.

find_must_change_passwordA

Find enabled users who must change their password at next logon.

Matches pwdLastSet=0, excluding disabled accounts. Pass base (a DN) to scope to an OU.

find_users_without_emailA

Data-quality check: list users with no mail attribute set.

Accounts without an email address often can't receive password-expiry notices, MFA prompts or other automated notifications. Pass base (a DN) to scope to an OU.

get_dnA

Resolve a sAMAccountName (or DN) to a distinguished name (DN).

Returns the value unchanged if it already looks like a DN, otherwise looks it up. Returns None if not found. Handy before get_by_dn or get_ou_contents.

audit_admin_accountsA

Audit administrative accounts: members of well-known privileged groups.

Builds on get_privileged_groups (Domain Admins, Enterprise Admins, Administrators, ...) and returns, per group that exists, its attributes, member_count and the expanded members list. Set nested=False to list only direct members instead of recursing into nested groups.

list_fsmo_rolesA

Report the owner of each of the five FSMO roles (audit).

Returns one entry per role (schema_master, domain_naming_master, pdc_emulator, rid_master, infrastructure_master) with the container queried and the owning DSA DN (owner). The schema and domain-naming masters live in the Configuration naming context, derived from the domain base for a single-domain forest; pass config_base explicitly for a multi-domain forest. Containers the service account cannot read are skipped.

list_trustsA

List the domain's trust relationships (audit).

Reads trustedDomain objects under CN=System,<base>: trust partner, direction, type and attributes. Returns an empty list if the container cannot be read.

list_sitesA

List the Active Directory sites (audit).

Reads site objects from CN=Sites,CN=Configuration,<forest root>. The Configuration naming context is derived from the domain base for a single-domain forest; pass config_base explicitly for a multi-domain forest. Returns an empty list if the container cannot be read.

list_domain_controllersB

List the domain controllers (computer accounts flagged as DCs).

Matches the SERVER_TRUST_ACCOUNT userAccountControl flag. Returns the usual computer attributes for each DC.

list_empty_groupsA

List groups with no direct members (hygiene/audit).

Matches groups whose member attribute is unset. Pass base (a DN) to scope to an OU.

find_security_groupsA

List security-enabled groups (as opposed to distribution groups).

Pass scope to restrict to one group scope: "global", "domain_local" or "universal" (None returns security groups of any scope). Pass base (a DN) to scope to an OU.

find_distribution_groupsB

List distribution groups (complement of find_security_groups).

Pass base (a DN) to scope to an OU.

summarize_computer_osA

Summarize computer accounts grouped by operating system (audit/report).

Returns {operatingSystem, count} rows sorted by descending count; computers without an operatingSystem are grouped under (unknown). Pass base (a DN) to scope to an OU.

list_gposB

List Group Policy Objects (audit).

Reads groupPolicyContainer objects under CN=Policies,CN=System,<base>. Each GPO's cn is its GUID and displayName the friendly name. Returns an empty list if the Policies container cannot be read.

get_gpoA

Get a single Group Policy Object by its cn (GUID) or displayName.

The GUID may be given with or without braces. Returns None if not found.

list_fine_grained_password_policiesA

List fine-grained password policies (PSOs) (audit).

Reads msDS-PasswordSettings objects under CN=Password Settings Container,CN=System,<base>. Reading them may require extra directory rights; returns an empty list if the container is not readable.

find_recently_modifiedA

Find objects whose whenChanged is within the last days days (default 7).

Useful for a "what changed recently in AD" audit. Pass object_class (e.g. "user", "group", "computer") to restrict to one object type, and base (a DN) to scope to an OU.

find_recently_createdA

Find objects whose whenCreated is within the last days days (default 7).

Pass object_class (e.g. "user", "group", "computer") to restrict to one object type, and base (a DN) to scope to an OU.

search_ldapA

Run a raw LDAP search with a custom filter (read-only, power-user escape hatch).

Use this when the typed tools (find_users, find_groups, ...) don't cover a query. The search_filter is passed to LDAP verbatim, so it must be a valid, already-escaped RFC 4515 filter, e.g. (&(objectClass=user)(title=Manager)) or (&(objectClass=group)(!(member=*))) for empty groups.

Prompts

Interactive templates invoked by user choice

NameDescription
security_auditGuide a read-only security audit of the Active Directory domain.
find_inactiveGuide finding and triaging inactive users and stale computers.
group_membership_reportGuide a membership report for a specific group.

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.3/5.0

Scored across 54 tools

Disambiguation4/5

Most tools target a distinct object class plus action, and adjacent tools (find_users vs get_user vs get_by_dn, find_inactive_users vs find_stale_computers, is_disabled vs disabled_users) are explicitly cross-referenced in descriptions. The main soft spot is audit_admin_accounts, which is essentially get_privileged_groups(with_members=True, nested=True) wrapped in another tool, and search_ldap overlaps with the entire typed surface as an escape hatch.

Naming Consistency3/5

The dominant pattern is verb_noun (find_users, get_group, list_gpos, get_ou_contents), but a large audit subset abandons verbs entirely for bare-noun or predicate phrasing: disabled_users, locked_users, password_not_required, not_delegated, never_expiring_accounts, group_members, user_groups. Predicate-named tools like password_not_required function as list queries, which reads oddly next to list_gpos. Still parseable, but three conventions coexist.

Tool Count2/5

54 tools is far beyond a comfortable set; dozens are narrow single-purpose audit queries (kerberos_preauth_not_required, never_expires_password, find_users_without_email) that could collapse into a parameterized audit or search_ldap filter. The breadth reflects a genuinely large domain (users, groups, computers, OUs, GPOs, trusts, sites, FSMO, password policies), but the surface is too heavy for reliable tool selection.

Completeness3/5

Read-side coverage is excellent: nearly every AD object class and audit scenario has a dedicated query, plus search_ldap as a fallback. However, the surface is entirely read-only, so an agent that finds a stale or risky account has no path to disable, unlock, reset a password, or modify group membership, which is a notable dead end for an AD server.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues