mcp-activedirectory
README.md
# mcp-activedirectory
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for **Microsoft Active Directory**, providing AI assistants with access to on-prem AD (via LDAP) and Azure AD / Entra ID (via Microsoft Graph API).
## Features
Supports two modes simultaneously:
- **On-prem Active Directory** — connects to a domain controller via LDAP/LDAPS using the `ldapts` library
- **Azure AD / Entra ID** — connects via the Microsoft Graph API using OAuth2 Client Credentials
**18 tools** across five categories:
### User Management
| Tool | Description |
|------|-------------|
| `list_users` | List users with optional name, email, or department filter |
| `get_user` | Get full user details including decoded UAC flags (on-prem) or full profile (Azure AD) |
| `get_user_groups` | List all groups a user is a member of |
| `search_users` | Advanced search by name, email, department, title, phone, or UPN |
### Group Management
| Tool | Description |
|------|-------------|
| `list_groups` | List groups with optional name filter |
| `get_group` | Get group details including member count and decoded group type |
| `get_group_members` | List all group members; supports recursive nested group expansion (on-prem) |
| `search_groups` | Search groups by name or description |
### Computer Accounts (On-prem AD only)
| Tool | Description |
|------|-------------|
| `list_computers` | List computer accounts with OS, last logon (human-readable), and OU |
| `get_computer` | Get full computer account details |
| `search_computers` | Search by name, OS, OU path, DNS hostname, or description |
### Organizational Units (On-prem AD only)
| Tool | Description |
|------|-------------|
| `list_ous` | List OUs with full path, sorted by depth |
| `get_ou` | Get OU details |
| `search_ous` | Search OUs by name, description, or parent path |
### Azure AD / Entra ID (Azure AD only)
| Tool | Description |
|------|-------------|
| `list_devices` | List Entra ID registered/joined devices with OS and compliance status |
| `get_device` | Get full device details by object ID |
| `list_service_principals` | List app registrations and service principals |
| `get_user_sign_in_activity` | Get last sign-in information for a user |
## Installation
```bash
git clone git@github.com:fredriksknese/mcp-activedirectory.git
cd mcp-activedirectory
npm install
npm run build
```
## Configuration
The server is configured via environment variables. At least one of `AD_HOST` or `AZURE_TENANT_ID` must be set.
### On-prem Active Directory (LDAP)
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `AD_HOST` | Yes | — | Domain controller hostname or IP address |
| `AD_PORT` | No | `389` | LDAP port (`636` for LDAPS) |
| `AD_USE_SSL` | No | `false` | Use LDAPS (`true`/`false`) |
| `AD_BIND_DN` | Yes | — | Bind DN, e.g. `CN=svc-mcp,OU=Service Accounts,DC=corp,DC=example,DC=com` |
| `AD_BIND_PASSWORD` | Yes | — | Bind account password |
| `AD_BASE_DN` | Yes | — | Base DN for all searches, e.g. `DC=corp,DC=example,DC=com` |
| `AD_ALLOW_SELF_SIGNED` | No | `true` | Accept self-signed TLS certificates |
### Azure AD / Entra ID (Microsoft Graph API)
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `AZURE_TENANT_ID` | Yes | — | Azure AD tenant ID (GUID) |
| `AZURE_CLIENT_ID` | Yes | — | App registration (client) ID |
| `AZURE_CLIENT_SECRET` | Yes | — | App registration client secret |
## Required Permissions
### On-prem Active Directory
The service account (`AD_BIND_DN`) needs **read access** to the directory. The minimum required permissions are:
- **Read** on User objects (all attributes listed below)
- **Read** on Group objects
- **Read** on Computer objects
- **Read** on OrganizationalUnit objects
Recommended: add the service account to the built-in **Domain Users** group and grant **Read** delegated permissions on the domain root, or use the built-in **Read-only Domain Controllers** access pattern.
Attributes read for users: `cn`, `sAMAccountName`, `displayName`, `mail`, `userPrincipalName`, `department`, `title`, `telephoneNumber`, `mobile`, `manager`, `memberOf`, `userAccountControl`, `lastLogon`, `whenCreated`, `whenChanged`, `description`, `distinguishedName`, `objectGUID`
### Azure AD / Entra ID (Microsoft Graph)
Create an **App Registration** in Azure AD and grant the following **Application permissions** (not Delegated):
| Permission | Scope | Required for |
|------------|-------|--------------|
| `User.Read.All` | Microsoft Graph | Reading user profiles and group memberships |
| `Group.Read.All` | Microsoft Graph | Reading groups and group members |
| `Device.Read.All` | Microsoft Graph | Reading Entra ID registered/joined devices |
| `AuditLog.Read.All` | Microsoft Graph | Reading sign-in activity (`signInActivity` field) |
Grant **Admin Consent** for all permissions in the Azure portal.
## Usage with Claude Desktop
Add to your `claude_desktop_config.json`:
### On-prem AD only
```json
{
"mcpServers": {
"activedirectory": {
"command": "node",
"args": ["/absolute/path/to/mcp-activedirectory/dist/index.js"],
"env": {
"AD_HOST": "dc01.corp.example.com",
"AD_BIND_DN": "CN=svc-mcp,OU=Service Accounts,DC=corp,DC=example,DC=com",
"AD_BIND_PASSWORD": "your-service-account-password",
"AD_BASE_DN": "DC=corp,DC=example,DC=com"
}
}
}
}
```
### Azure AD / Entra ID only
```json
{
"mcpServers": {
"activedirectory": {
"command": "node",
"args": ["/absolute/path/to/mcp-activedirectory/dist/index.js"],
"env": {
"AZURE_TENANT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"AZURE_CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"AZURE_CLIENT_SECRET": "your-client-secret"
}
}
}
}
```
### Both simultaneously
```json
{
"mcpServers": {
"activedirectory": {
"command": "node",
"args": ["/absolute/path/to/mcp-activedirectory/dist/index.js"],
"env": {
"AD_HOST": "dc01.corp.example.com",
"AD_BIND_DN": "CN=svc-mcp,OU=Service Accounts,DC=corp,DC=example,DC=com",
"AD_BIND_PASSWORD": "your-service-account-password",
"AD_BASE_DN": "DC=corp,DC=example,DC=com",
"AZURE_TENANT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"AZURE_CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"AZURE_CLIENT_SECRET": "your-client-secret"
}
}
}
}
```
## Usage with Claude Code
```bash
claude mcp add activedirectory -- node /absolute/path/to/mcp-activedirectory/dist/index.js
```
## LDAPS / SSL Configuration
To use LDAPS (port 636):
```json
"env": {
"AD_HOST": "dc01.corp.example.com",
"AD_PORT": "636",
"AD_USE_SSL": "true",
"AD_ALLOW_SELF_SIGNED": "true"
}
```
Set `AD_ALLOW_SELF_SIGNED` to `"false"` if your domain controller uses a certificate from a trusted CA.
## Example Prompts
Once connected, you can ask your AI assistant things like:
- *"List all users in the IT department"*
- *"Get details for user jdoe including their group memberships"*
- *"Which groups does john.doe@company.com belong to?"*
- *"Show me all members of the Domain Admins group"*
- *"List all Windows Server 2022 computers in the Servers OU"*
- *"Which computer accounts haven't logged in since 2024?"*
- *"Show me the top-level OUs in the domain"*
- *"List all Azure AD joined devices"*
- *"When did user@company.com last sign in?"*
- *"List all service principals of type ManagedIdentity"*
## Architecture
```
src/
├── index.ts # Entry point — creates MCP server + STDIO transport
├── ad-client.ts # LDAP client wrapping ldapts for on-prem AD
├── graph-client.ts # Microsoft Graph API client with OAuth2 token caching
└── tools/
├── users.ts # User tools (list, get, search, groups) — AD + Azure
├── groups.ts # Group tools (list, get, members, search) — AD + Azure
├── computers.ts # Computer account tools — on-prem AD only
├── ous.ts # Organizational unit tools — on-prem AD only
└── azure.ts # Azure-specific tools (devices, service principals, sign-in)
```
## Development
```bash
npm run dev # Run with tsx (no compilation needed)
npm run build # Compile TypeScript to dist/
npm start # Run compiled output
```
## Requirements
- Node.js 18+
- For on-prem AD: network access to a domain controller on port 389 (LDAP) or 636 (LDAPS)
- For Azure AD: an App Registration with the required Graph API permissions
## License
SEE LICENSE IN LICENSE
TDQS
A3.5/5.0
Scored across 18 tools
Disambiguation5/5
Each tool targets a distinct resource type or operation (e.g., get vs list vs search, computer vs device, group vs group members). There is no ambiguity between tools.
Naming Consistency5/5
All tool names follow the verb_noun pattern consistently (e.g., get_computer, list_users, search_groups). No mixing of naming conventions.
Tool Count5/5
18 tools cover both on-prem AD and Azure AD resources (users, groups, computers, devices, OUs, service principals) without being excessive. The scope is appropriate for a directory server.
Completeness2/5
The tool set is entirely read-only; there are no create, update, or delete operations. For an Active Directory server, this is a significant gap that prevents full lifecycle management.
Maintenance
ActivityInactive
ResponsivenessNo issues