Skip to main content
Glama

About

Active Directory MCP is an open-source Model Context Protocol server that lets AI assistants (Claude, Gemini CLI, ChatGPT via API, etc.) safely manage Active Directory environments.

Key features

  • 45 tools covering users, groups, computers, OUs, security, and audit, plus 15 MSP prompt playbooks served through the MCP prompts protocol.

  • Two transports: stdio (server.py) for direct CLI/desktop clients, and Streamable HTTP via FastAPI (server_fastapi.py) for everything else. An earlier FastMCP-based HTTP transport (server_http.py) has been removed.

  • Two deployment modes: single (default) binds one process to one AD via AD_MCP_CONFIG — run one process per tenant to serve several; multi binds one process to N ADs via AD_MCP_SERVERS, adding a required/optional ad_server parameter to every directory-bound tool. See Multi-tenant architecture.

  • Write-operation guard rails: every mutating tool requires either a per-tenant client confirmation string or an automation Bearer token before touching AD.

  • Audit log on every operation: each call records operation name, target, mode (CONFIRMED / AUTOMATION / NO_CONFIRMATION_REQUIRED), and outcome.

Naming convention

All MCP tool names use the ad_* prefix with a descriptive suffix — e.g. ad_list_users_with_filters, ad_create_user_account, ad_disable_computer_account_trust. This avoids collisions when this MCP runs alongside other servers (GLPI, Hudu, etc.) connected to the same AI client.


Related MCP server: Shell MCP

Multi-tenant architecture

There are two ways to serve more than one AD with this codebase. Both read the same active_directory / organizational_units / security / client schema (see Configuration); pick one per deployment, not both.

Mode 1 — one process per tenant (AD_MCP_MODE=single, the default)

.base-code/                    <- this repository (shared source of truth)
  src/active_directory_mcp/
  ad-config/
    ad-config.example.json     <- template only (real configs are .gitignored)

<deployment>/                  <- one directory per tenant, OUTSIDE this repo
  tenant-a/
    ad-config/ad-config.json   <- real credentials (NEVER committed)
    start.sh                   <- exports AD_MCP_CONFIG and launches the server
  tenant-b/
    ad-config/ad-config.json
    start.sh

Each start.sh exports AD_MCP_CONFIG pointing at that tenant's config and runs python -m active_directory_mcp.server_fastapi on a dedicated port. Update the shared .base-code/ once, restart every tenant process &mdash; same code, isolated state. Tools take no ad_server parameter in this mode; this is the original, unchanged behavior.

Mode 2 &mdash; one process serving several ADs (AD_MCP_MODE=multi)

A single server_fastapi.py process can instead serve N directories, selected via AD_MCP_SERVERS pointing at an ad-servers.json (schema: ad-config/ad-servers.example.json &mdash; each entry is an ad-config.json block plus label/aliases/enabled). Every directory-bound tool then gains an ad_server parameter:

  • Write tools: ad_server is required and must name exactly one directory &mdash; there is no "all".

  • Read tools: ad_server is optional; omitted (or all/todos/*) runs the query against every configured directory and the response reports where each result was found.

  • Catalog tools: ad_list_configured_clients and ad_check_client_configuration are replaced by ad_list_ad_servers and ad_check_ad_server_configured, which resolve a name, alias, domain or client name to the exact value to pass as ad_server. ad_get_client_tenant_info still exists but, like every other directory-bound tool, now takes ad_server (optional) instead of describing "the" tenant.

ad_server matching ignores case, accents and surrounding whitespace; a name that matches more than one directory is refused with the list of candidates rather than guessed. Write confirmation (client_confirmation, below) is validated against the same directory named by ad_server.

export AD_MCP_MODE=multi
export AD_MCP_SERVERS=/etc/ad-mcp/ad-servers.json
python -m active_directory_mcp.server_fastapi --host 0.0.0.0 --port 8820

The stdio transport (server.py) only supports single mode.


Quick Start

Prerequisites

  • Python 3.11+

  • LDAP/LDAPS reachable from the host

  • An AD service account with the permissions required by the operations you plan to expose

1. Install

git clone https://github.com/DevSkillsIT/Skills-MCP-Active-Directory.git
cd Skills-MCP-Active-Directory

python -m venv .venv
source .venv/bin/activate          # Linux/macOS
# .venv\Scripts\activate           # Windows

pip install -e .                   # installs from pyproject.toml

2. Configure

mkdir -p /etc/ad-mcp
cp ad-config/ad-config.example.json /etc/ad-mcp/ad-config.json
$EDITOR /etc/ad-mcp/ad-config.json   # set server, bind_dn, password, base_dn, OUs
chmod 600 /etc/ad-mcp/ad-config.json

The example file is the only template kept in git. Any real ad-config.json is blocked by .gitignore (ad-config/*.json + !ad-config/*.example.json).

3. Run

export AD_MCP_CONFIG=/etc/ad-mcp/ad-config.json

# stdio transport (for direct Claude Desktop / mcp-cli use):
python -m active_directory_mcp.server

# HTTP transport (for Claude Code, Gemini CLI, n8n, etc.):
python -m active_directory_mcp.server_fastapi --host 0.0.0.0 --port 8820
# MCP endpoint: http://localhost:8820/mcp   Health (no auth): http://localhost:8820/health

Set AD_MCP_API_TOKEN in the environment to require a Bearer token on the HTTP transport; without it the server accepts unauthenticated requests (development only &mdash; always set it in production). See HTTP_MCP_GUIDE.md for the full transport reference, including the multi mode.

4. Connect from Claude Code

claude mcp add --transport http ad http://localhost:8820/mcp \
  --headers "Authorization: Bearer YOUR_AUTOMATION_TOKEN"

5. Connect from Gemini CLI

~/.gemini/settings.json:

{
  "mcpServers": {
    "ad": {
      "httpUrl": "http://localhost:8820/mcp",
      "headers": { "Authorization": "Bearer YOUR_AUTOMATION_TOKEN" },
      "timeout": 30000
    }
  }
}

Tools

All tools use the ad_* prefix. Tools marked as Write require a confirmation string OR an automation Bearer token. The tables below describe single mode (the default, 45 tools). In multi mode every tool listed here also gets an ad_server parameter, and ad_list_configured_clients / ad_check_client_configuration below are replaced by ad_list_ad_servers / ad_check_ad_server_configured &mdash; see Multi-tenant architecture.

Tenant identification (3)

Tool

Operation

ad_get_client_tenant_info

Return tenant info for this instance (call first)

ad_list_configured_clients

List all clients registered in the client registry (single mode only)

ad_check_client_configuration

Check if a given client slug has an AD configured (single mode only)

User management (9)

Tool

Write

Operation

ad_list_users_with_filters

&mdash;

List users (optionally filtered by OU/criteria)

ad_get_user_details_by_username

&mdash;

Fetch user attributes by sAMAccountName

ad_get_user_group_memberships

&mdash;

List groups a user is member of

ad_create_user_account

yes

Create a new user

ad_modify_user_attributes

yes

Modify user attributes

ad_delete_user_account_permanently

yes

Delete a user

ad_enable_user_account_access

yes

Enable user account

ad_disable_user_account_access

yes

Disable user account

ad_reset_user_password_forced

yes

Reset password (force change on next login)

Group management (8)

Tool

Write

Operation

ad_list_groups_with_filters

&mdash;

List groups

ad_get_group_details_by_name

&mdash;

Fetch group attributes

ad_get_group_members_recursive

&mdash;

List members, optionally recursive

ad_create_group_security_or_distribution

yes

Create security or distribution group

ad_modify_group_attributes

yes

Modify group attributes

ad_delete_group_permanently

yes

Delete a group

ad_add_member_to_group

yes

Add member

ad_remove_member_from_group

yes

Remove member

Computer management (9)

Tool

Write

Operation

ad_list_computers_with_filters

&mdash;

List computers

ad_get_computer_details_by_name

&mdash;

Fetch computer attributes

ad_get_inactive_computers_by_days

&mdash;

List computers idle for N+ days

ad_create_computer_account

yes

Create computer object

ad_modify_computer_attributes

yes

Modify computer attributes

ad_delete_computer_account_permanently

yes

Delete computer object

ad_enable_computer_account_trust

yes

Enable computer account

ad_disable_computer_account_trust

yes

Disable computer account

ad_reset_computer_password_trust

yes

Reset computer secure-channel password

Organizational Unit management (7)

Tool

Write

Operation

ad_list_organizational_units_hierarchy

&mdash;

List OUs (recursive option)

ad_get_organizational_unit_details

&mdash;

Fetch OU attributes

ad_get_organizational_unit_objects

&mdash;

List objects inside an OU

ad_create_organizational_unit

yes

Create OU

ad_modify_organizational_unit_attributes

yes

Modify OU

ad_delete_organizational_unit_forced

yes

Delete OU (force=true to delete non-empty)

ad_move_organizational_unit_parent

yes

Move OU to a new parent

Security & audit (6)

Tool

Operation

ad_get_domain_security_policy_info

Domain info + password/lockout policy

ad_get_privileged_security_groups

List privileged groups (Domain Admins, Enterprise Admins, etc.)

ad_get_user_effective_permissions

Show effective permissions for a user

ad_get_inactive_users_by_days

Users with no logon for N+ days

ad_get_password_policy_violations

Accounts violating the password policy

ad_audit_administrative_accounts

Audit privileged account hygiene

MSP prompts (15)

The 15 professional MSP playbooks (7 manager + 8 analyst) are not tools &mdash; they are served through the standard MCP prompts protocol, prompts/list and prompts/get, over the FastAPI HTTP transport only (the stdio transport does not expose them). See PROMPTS.md for the full catalog and usage.

System (3)

Tool

Operation

ad_test_ldap_connection_status

LDAP connectivity probe

ad_health_check_mcp_server

Full health check (server + LDAP search test + stats)

ad_get_mcp_schema_tools_info

Self-describing schema of all registered tools


Configuration

The runtime configuration file path is provided via the AD_MCP_CONFIG environment variable. Schema in ad-config/ad-config.example.json.

Key fields

Field

Required

Description

active_directory.server

yes

Primary LDAP URL, e.g. ldaps://dc.example.com:636

active_directory.server_pool

no

Additional LDAP URLs for failover

active_directory.bind_dn

yes

Full DN of the service account

active_directory.password

yes

Service account password (keep file at chmod 600)

active_directory.base_dn

yes

Base DN, e.g. DC=example,DC=com

organizational_units.*

yes

Default OUs for users/groups/computers/service accounts

security.enable_tls

no

Force StartTLS / LDAPS

security.validate_certificate

no

Verify server certificate against ca_cert_file

security.require_secure_connection

no

Refuse to bind over plaintext

automation.token

no

Bearer token for unattended write operations

client.slug

no

Tenant identifier reported by ad_get_client_tenant_info

Service account permissions

Grant the bind account the minimum delegated rights required by the operations you intend to expose:

  • Read-only deployments: "Read all properties" + "List contents" on the domain root is enough.

  • User/group write: delegate "Create/Delete objects" + "Write all properties" on the target OUs.

  • Password reset: delegate the "Reset password" extended right on the target OUs.

  • Computer join/leave: delegate "Create/Delete computer objects" on the computers OU.

Always use a dedicated service account, LDAPS in production, and rotate the password regularly.


Security

Write protection model

Every mutating tool (ad_create_*, ad_modify_*, ad_delete_*, ad_enable_*, ad_disable_*, ad_reset_*, ad_add_*, ad_remove_*, ad_move_*) calls check_write_permission() before reaching LDAP. It accepts the write if one of:

  1. automation_token matches automation.token in the config &mdash; intended for CI / scheduled jobs.

  2. client_confirmation matches the tenant slug &mdash; the AI assistant must call ad_get_client_tenant_info first, read the slug back to the user, and pass that exact string.

  3. The tenant has require_confirmation_for_writes: false (explicit opt-out, not recommended).

If none of the above is satisfied, the call short-circuits with a permitted: false message and the LDAP write is never attempted.

Audit logging

All operations write a structured log line including: timestamp, tool name, target, confirmation mode (AUTOMATION / CONFIRMED / WRONG_CONFIRMATION / NO_CONFIRMATION_REQUIRED), and success/failure. Logs go wherever logging.file points.

Secrets hygiene

  • Real ad-config.json files are git-ignored. Only *.example.json is tracked.

  • Never paste a config containing a real password or automation.token into a chat that's logged or transcribed by a third party.

  • Rotate automation.token whenever you regenerate it; treat it as a privileged credential.


Testing

# Unit + integration tests
pytest tests/ -v

# Coverage
pytest --cov=src/active_directory_mcp --cov-report=term-missing

# Lint
ruff check .

A bundled docker-compose-ad.yml spins up a Samba AD container at 192.168.1.100 plus an MCP container so the integration tests can run against a real LDAP backend without touching production.


Troubleshooting

Symptom

Likely cause

Fix

LDAP bind failed

bad bind_dn / password

Verify against ldapsearch -H <server> -D '<bind_dn>' -W

Insufficient permissions

service account lacks delegated rights

Re-delegate on the target OU

Certificate verification failed

self-signed cert without trust

Set ca_cert_file or validate_certificate: false (test only)

permitted: false on every write

Missing confirmation/token

Call ad_get_client_tenant_info first, or pass automation_token

Health degraded

socket open but LDAP search failed

Check service-account lockout / replication / network ACLs


Contributing

  1. Fork the repo.

  2. Create a feature branch: git checkout -b feat/your-feature.

  3. Run tests: pytest.

  4. Open a PR with a clear description and a link to the relevant issue.

Commits follow Conventional Commits.


License

MIT &mdash; see LICENSE.

Acknowledgments

Support

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive MCP server for managing Active Directory environments through LDAP, enabling user, group, computer, and OU management, as well as security auditing and policy compliance checks.
    46
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A production-ready MCP server that enables AI assistants to execute shell commands, manage files, monitor system resources, and automate complex workflows with advanced features like stock tracking and web automation.
    7
    18 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that enables AI-powered assessment of Active Directory on-premises environments by exposing AD data as queryable tools for LLMs like Claude.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that enables AI assistants to manage, monitor, and diagnose Windows systems through 42 tools across 8 modules, including services, event viewer, task scheduler, processes, network, diagnostics, observability, and safety features.
    10 npm
    9
    MIT