Skills MCP AD
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Skills MCP ADReset the password for user bwayne and unlock their account"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 viaAD_MCP_CONFIG— run one process per tenant to serve several;multibinds one process to N ADs viaAD_MCP_SERVERS, adding a required/optionalad_serverparameter 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.shEach 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 — same code, isolated state. Tools take no ad_server parameter in this mode; this is the original, unchanged behavior.
Mode 2 — 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 — 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_serveris required and must name exactly one directory — there is no "all".Read tools:
ad_serveris optional; omitted (orall/todos/*) runs the query against every configured directory and the response reports where each result was found.Catalog tools:
ad_list_configured_clientsandad_check_client_configurationare replaced byad_list_ad_serversandad_check_ad_server_configured, which resolve a name, alias, domain or client name to the exact value to pass asad_server.ad_get_client_tenant_infostill exists but, like every other directory-bound tool, now takesad_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 8820The 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.toml2. 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.jsonThe example file is the only template kept in git. Any real
ad-config.jsonis 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/healthSet 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 — 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 — see Multi-tenant architecture.
Tenant identification (3)
Tool | Operation |
| Return tenant info for this instance (call first) |
| List all clients registered in the client registry ( |
| Check if a given client slug has an AD configured ( |
User management (9)
Tool | Write | Operation |
| — | List users (optionally filtered by OU/criteria) |
| — | Fetch user attributes by sAMAccountName |
| — | List groups a user is member of |
| yes | Create a new user |
| yes | Modify user attributes |
| yes | Delete a user |
| yes | Enable user account |
| yes | Disable user account |
| yes | Reset password (force change on next login) |
Group management (8)
Tool | Write | Operation |
| — | List groups |
| — | Fetch group attributes |
| — | List members, optionally recursive |
| yes | Create security or distribution group |
| yes | Modify group attributes |
| yes | Delete a group |
| yes | Add member |
| yes | Remove member |
Computer management (9)
Tool | Write | Operation |
| — | List computers |
| — | Fetch computer attributes |
| — | List computers idle for N+ days |
| yes | Create computer object |
| yes | Modify computer attributes |
| yes | Delete computer object |
| yes | Enable computer account |
| yes | Disable computer account |
| yes | Reset computer secure-channel password |
Organizational Unit management (7)
Tool | Write | Operation |
| — | List OUs (recursive option) |
| — | Fetch OU attributes |
| — | List objects inside an OU |
| yes | Create OU |
| yes | Modify OU |
| yes | Delete OU (force=true to delete non-empty) |
| yes | Move OU to a new parent |
Security & audit (6)
Tool | Operation |
| Domain info + password/lockout policy |
| List privileged groups (Domain Admins, Enterprise Admins, etc.) |
| Show effective permissions for a user |
| Users with no logon for N+ days |
| Accounts violating the password policy |
| Audit privileged account hygiene |
MSP prompts (15)
The 15 professional MSP playbooks (7 manager + 8 analyst) are not tools — 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 |
| LDAP connectivity probe |
| Full health check (server + LDAP search test + stats) |
| 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 |
| yes | Primary LDAP URL, e.g. |
| no | Additional LDAP URLs for failover |
| yes | Full DN of the service account |
| yes | Service account password (keep file at |
| yes | Base DN, e.g. |
| yes | Default OUs for users/groups/computers/service accounts |
| no | Force StartTLS / LDAPS |
| no | Verify server certificate against |
| no | Refuse to bind over plaintext |
| no | Bearer token for unattended write operations |
| no | Tenant identifier reported by |
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:
automation_tokenmatchesautomation.tokenin the config — intended for CI / scheduled jobs.client_confirmationmatches the tenant slug — the AI assistant must callad_get_client_tenant_infofirst, read the slug back to the user, and pass that exact string.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.jsonfiles are git-ignored. Only*.example.jsonis tracked.Never paste a config containing a real
passwordorautomation.tokeninto a chat that's logged or transcribed by a third party.Rotate
automation.tokenwhenever 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 |
| bad | Verify against |
| service account lacks delegated rights | Re-delegate on the target OU |
| self-signed cert without trust | Set |
| Missing confirmation/token | Call |
| socket open but LDAP search failed | Check service-account lockout / replication / network ACLs |
Contributing
Fork the repo.
Create a feature branch:
git checkout -b feat/your-feature.Run tests:
pytest.Open a PR with a clear description and a link to the relevant issue.
Commits follow Conventional Commits.
License
MIT — see LICENSE.
Acknowledgments
Based on the upstream
alpadalar/ActiveDirectoryMCPproject by Alperen Adalar.
Support
Bug reports: GitHub Issues
Discussions: GitHub Discussions
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA 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.46MIT
- AlicenseAqualityDmaintenanceA 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.718 npmMIT
- AlicenseNot gradedqualityBmaintenanceMCP server that enables AI-powered assessment of Active Directory on-premises environments by exposing AD data as queryable tools for LLMs like Claude.MIT
- AlicenseNot gradedqualityDmaintenanceAn 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 npm9MIT