adds-mcp

adds-mcp

Provides read-only tools for monitoring and investigating Active Directory Domain Services, including users, groups, OUs, computers, GPOs, and domain metadata via LDAPS.

Category
Visit Server

README

ms-ad-mcp

Read-only Model Context Protocol (MCP) servers for the Microsoft Active Directory family. Three sibling servers in one repository, one shared LDAPS bind, one optional WinRM bind for the online issuing CAs. Designed for monitoring, investigation, and answering "who / what / where" questions about a Windows domain without ever mutating directory state.

  • adds-mcp — AD DS: users, groups, OUs, computers, GPOs, domain metadata
  • adcs-mcp — AD CS: CAs, certificate templates, issued/pending/revoked certs, CA config
  • addns-mcp — AD-integrated DNS: zones, records, delegations, stale entries, IP/name search

Every tool has readOnlyHint: true. adds-mcp opens LDAP with read_only=True, so mutating LDAP verbs are rejected even if a tool tried to issue one. adcs-mcp runs only Get-* PowerShell and read-only registry reads on the CA hosts.


Table of contents

  1. Architecture at a glance
  2. Credentials you need to provision
    1. LDAPS service account (shared)
    2. WinRM service account (adcs-mcp only)
  3. Network access matrix
  4. What each server queries — data sources in detail
    1. adds-mcp — Active Directory Domain Services
    2. adcs-mcp — Active Directory Certificate Services
    3. addns-mcp — AD-integrated DNS
  5. Preparing the environment
    1. Domain controllers
    2. Issuing CAs (adcs-mcp only)
    3. The MCP host itself
  6. Installation
  7. Configuration reference
  8. Running the servers
  9. Wiring into an MCP client
  10. Security posture
  11. Troubleshooting
  12. Tool reference
  13. Repository layout

Architecture at a glance

                ┌──────────────────────────────────────────────────┐
                │                MCP host (Linux)                  │
                │                                                  │
                │  ┌──────────┐  ┌──────────┐  ┌──────────┐        │
                │  │ adds-mcp │  │ adcs-mcp │  │addns-mcp │        │
                │  │  :8080   │  │  :8081   │  │  :8082   │        │
                │  └────┬─────┘  └────┬─────┘  └────┬─────┘        │
                │       │             │             │              │
                │       └──────┬──────┴──────┬──────┘              │
                │              │             │                     │
                │       ┌──────▼─────┐  ┌────▼──────┐              │
                │       │  LDAPS 636 │  │ WinRM 5986│              │
                │       │  (shared)  │  │  (Kerberos│              │
                │       │            │  │   or NTLM)│              │
                │       └──────┬─────┘  └────┬──────┘              │
                └──────────────┼─────────────┼─────────────────────┘
                               │             │
                               │             │
              ┌────────────────▼───┐   ┌─────▼────────────────┐
              │                    │   │                      │
              │  Domain Controllers│   │ Issuing / Enterprise │
              │   (any DC — pool)  │   │ CAs listed in        │
              │                    │   │ ADCS_CA_HOSTS        │
              │  • adds-mcp        │   │                      │
              │  • adcs-mcp (AD    │   │  • adcs-mcp only     │
              │      PKI subtree)  │   │  • PowerShell + PSPKI│
              │  • addns-mcp       │   │                      │
              │                    │   │  ⚠ NOT the offline   │
              │                    │   │    Root/Policy CAs   │
              └────────────────────┘   └──────────────────────┘

Not queried live: Tier 0 (offline Root) and Tier 1 (offline Policy) CAs. There's no live endpoint on an offline CA. Use parse_certificate_pem on exported certs/CRLs from those tiers instead, then cross-check the trust chain against list_ntauth_cas / list_aia_entries / list_root_cas.


Credentials you need to provision

Two distinct service accounts. Provision them separately even if the same person operates both — keeping them separate is what makes least-privilege auditable.

1. LDAPS service account (shared)

Used by: adds-mcp, adcs-mcp (AD-side tools), addns-mcp (all tools).

Purpose: Bind to any DC over LDAPS and read AD content. Never writes.

Item Value
Suggested name svc-msadmcp-ro
Object class User (standard domain user account)
Password Long, random, rotated on your normal schedule. Stored in a secret manager, not in git.
Group memberships None special. Any authenticated domain user has enough rights for ~95% of tools. See below for the exceptions.
Logon rights Deny interactive/local logon everywhere; allow only "Access this computer from the network" on DCs.
UAC flags to set PASSWD_CANT_CHANGE, SMARTCARD_REQUIRED=no. Never DONT_EXPIRE_PASSWORD.
Kerberos SPNs None required

Where its bind DN goes: ADDS_BIND_DN in the environment. Example: CN=svc-msadmcp-ro,OU=Service Accounts,DC=corp,DC=example,DC=com.

Optional extra rights (only if you want the corresponding tools to work fully — they degrade gracefully otherwise):

Extra right Enables
Read on CN=Password Settings Container,CN=System,DC=… adds-mcplist_fine_grained_password_policies returns PSO contents
Read on nTSecurityDescriptor on certificate templates adcs-mcp → template ACL fields populate on get_certificate_template
Read on msLAPS-Password / ms-Mcs-AdmPwd (LAPS) Future LAPS tools (not yet exposed); do not grant unless you specifically want this

By default we recommend granting none of the above — the tools still work, they just return null where the account lacks read rights.

2. WinRM service account (adcs-mcp only)

Used by: the WinRM-side tools in adcs-mcp (list_issued_certificates, get_ca_configuration, list_ca_role_holders, …). Roughly half of adcs-mcp's 24 tools. If you never call those tools, you don't need this account at all.

Purpose: Run Get-* PowerShell (mostly the PSPKI module) on each online issuing CA to read the CA database and configuration.

Item Value
Suggested name svc-adcsmcp-ro
Object class User
Password Same policy as above. Prefer a Kerberos keytab in production and don't put the password in .env at all.
Group memberships On each CA host: Remote Management Users (for WinRM listen access) + Event Log Readers (only if you enable the audit-log tool).
CA-role assignment On each CA host: CA Auditor role (assigned via certsrv.msc → CA → Security). Auditor is read-only and is exactly what we need. Do not grant Manage CA or Issue and Manage Certificates.
Logon rights Deny interactive; allow only "Access this computer from the network".
Kerberos SPNs None (the CA host publishes its own HTTP SPN for WinRM).

Where its credentials go: ADCS_WINRM_USER and ADCS_WINRM_PASSWORD. Recommended format: CORP\svc-adcsmcp-ro for NTLM/negotiate, or svc-adcsmcp-ro@CORP.EXAMPLE.COM for Kerberos.

Preferred auth: Kerberos. With Kerberos you can drop the password entirely and use a keytab; see the Kerberos setup on the MCP host section.


Network access matrix

From wherever the MCP servers run, to wherever they read from. If you're deploying inside a segmented environment, this is the firewall ask.

Source (MCP host) Destination Protocol Port Required by
MCP host Every DC (or a load-balanced VIP) TCP TLS 636 adds-mcp, adcs-mcp (AD-side), addns-mcp
MCP host DCs (Global Catalog, optional) TCP TLS 3269 Not required for any current tool
MCP host Each issuing CA in ADCS_CA_HOSTS TCP TLS 5986 adcs-mcp (WinRM-side tools)
MCP host KDCs (usually the DCs) TCP+UDP 88 Only if ADCS_WINRM_AUTH=kerberos
MCP host KDCs (Kerberos password change) TCP+UDP 464 Only if you actively rotate the keytab from Linux
MCP host Internal DNS resolvers UDP/TCP 53 To resolve DC + CA hostnames (and Kerberos)
Any MCP client MCP host HTTP 8080/8081/8082 MCP over Streamable HTTP

Notes:

  • LDAPS TCP 636 is non-negotiable. Do not fall back to plain LDAP 389 — the LDAPS bind carries the service account password.
  • WinRM 5986 (HTTPS) is required, not 5985. Plain-HTTP WinRM sends credentials in the clear on the wire even with Kerberos auth, and is disabled by default on Windows Server.
  • Reverse DNS for every DC and every CA host must be correct if you use Kerberos WinRM auth. nslookup <ip> on the MCP host must return the same FQDN that the certificate presents.

What each server queries — data sources in detail

adds-mcp — Active Directory Domain Services

Data Where it lives (LDAP path) Which tools read it
User accounts CN=Users and any OU under ADDS_BASE_DN search_users, get_user, list_locked_out_users, list_disabled_users, list_stale_users, list_recently_changed_users, list_password_never_expires
Group memberships member / memberOf on user and group objects list_user_groups, list_group_members
Security & distribution groups CN=Users and any OU search_groups, get_group, list_empty_groups, list_privileged_groups
Organizational Units Any DN under ADDS_BASE_DN list_ous, get_ou, list_ou_children, get_ou_tree
Computer accounts CN=Computers and OUs search_computers, get_computer, list_domain_controllers, list_stale_computers, summarize_computer_os
Group Policy Objects CN=Policies,CN=System,<base> (metadata) list_gpos, get_gpo
GPO links gPLink attribute on OUs, domain root, sites find_gpo_links, list_links_on_ou
Password / lockout policy Domain root attributes on <base> get_password_policy
Fine-grained password policies (PSOs) CN=Password Settings Container,CN=System,<base> list_fine_grained_password_policies
FSMO owners fSMORoleOwner on 5 well-known containers under CN=Schema, CN=Partitions, CN=RID Manager$, CN=Infrastructure, and the domain root list_fsmo_roles
Trust relationships CN=System,<base> (objectClass=trustedDomain) list_trusts
Sites / subnets / site links CN=Sites,CN=Configuration,<forest root> list_sites

Servers this hits: any domain controller reachable on port 636. adds-mcp uses ldap3's ServerPool with strategy=FIRST so you can list multiple DCs in ADDS_SERVERS and it will fail over.

adcs-mcp — Active Directory Certificate Services

Split into two data-source halves. Both halves share the adcs-mcp process, but you can leave the WinRM half unconfigured if you only need AD-side reads.

AD-side half (LDAPS to any DC)

All Enterprise CA metadata is published in the Configuration NC:

CN=Public Key Services,CN=Services,CN=Configuration,<forest root>
AD child container Object class Tools
CN=Enrollment Services pKIEnrollmentService list_enrollment_services, get_enrollment_service, find_templates_offered_by_ca
CN=Certification Authorities certificationAuthority list_root_cas
CN=NTAuthCertificates (single object) list_ntauth_cas
CN=Certificate Templates pKICertificateTemplate list_certificate_templates, get_certificate_template, list_templates_by_eku
CN=AIA certificationAuthority list_aia_entries
CN=CDP (subtree) cRLDistributionPoint / container list_cdp_entries
CN=KRA msPKI-PrivateKeyRecoveryAgent list_kra_certificates
CN=OID msPKI-Enterprise-Oid list_pki_oids

Servers this hits: the same DCs adds-mcp uses. Reuses the same LDAPS bind.

WinRM half (PowerShell on each online issuing CA)

The CA database — the actual issued / pending / revoked cert history — is not in AD. It's a Jet database on each issuing CA (certsrv.mdb). We read it by running PowerShell over WinRM.

Tools in this half:

Tool PowerShell it runs Requires on the CA
list_issued_certificates Get-CertificationAuthority | Get-IssuedRequest (PSPKI) PSPKI installed; CA Auditor role
list_pending_requests `` ``
list_failed_requests `` ``
list_revoked_certificates `` ``
get_certificate_by_serial `` filtered by serial ``
count_certificates_by_disposition Get-IssuedRequest | Group-Object ``
get_ca_configuration Get-CACrlDistributionPoint, Get-CAAuthorityInformationAccess, Get-CATemplate PSPKI; CA Auditor
list_ca_role_holders Get-CertificationAuthorityAcl PSPKI; CA Auditor
list_officer_rights Get-CertificateManagerRights PSPKI; CA Auditor
get_ca_certificate_chain Get-CertificationAuthorityCertificate PSPKI; CA Auditor
list_ca_backup_settings Get-ItemProperty HKLM:\...\CertSvc\Configuration Read on the CertSvc config registry (usually implied by CA Auditor)

Standalone half (no directory or WinRM access):

  • parse_certificate_pem — pure cryptography X.509 decode. Feed it any PEM or base64 DER (including CRLs and offline Root/Policy CA certs).

Servers this hits: every host you list in ADCS_CA_HOSTS. Typically your two-or-more online Enterprise/Issuing CAs. Not the offline root or policy CAs — they aren't reachable over the network by design.

addns-mcp — AD-integrated DNS

DNS zones and records that live in Active Directory. Three partitions are searched; whichever one holds the zone wins:

Partition DN When it's used
Domain-scoped DNS DC=DomainDnsZones,<base> Default for new zones since Windows 2003
Forest-scoped DNS DC=ForestDnsZones,<base> Forest-wide zones (e.g. _msdcs)
Legacy System container CN=MicrosoftDNS,CN=System,<base> Pre-2003 or zones explicitly stored in the domain NC
Data Object class / storage Tools
Zone objects dnsZone list_zones, get_zone, list_conditional_forwarders
RR nodes dnsNode (children of a zone) list_records, get_record, list_stale_records, list_zone_delegations, search_by_name
Record data dnsRecord binary attribute on each node Decoded in-process per MS-DNSP DNS_RECORD
Reverse zones dnsZone where dc=*.in-addr.arpa / *.ip6.arpa search_by_ip

Servers this hits: the same DCs adds-mcp uses. All DCs typically hold the DNS partitions.


Preparing the environment

Domain controllers

You almost certainly already have LDAPS enabled — modern Windows requires it for a variety of common tasks. Confirm with:

# On any DC:
Get-Certificate -Template DomainController -CertStoreLocation Cert:\LocalMachine\My
netstat -an | Select-String ":636"

If port 636 doesn't listen, you're on plain LDAP only and need to publish a DC cert first (certreq with the DomainController template, or the DomainController template auto-enrolls if it's assigned to Domain Controllers). This is a one-time domain-wide fix and out of scope for this README.

Issuing CAs (adcs-mcp only)

On each host you plan to list in ADCS_CA_HOSTS:

# 1. Enable WinRM over HTTPS with a machine-cert listener.
Enable-PSRemoting -Force
# Ensure an HTTPS listener exists; run this only if one is missing:
New-Item WSMan:\LocalHost\Listener -Transport HTTPS -Address * `
  -CertificateThumbPrint (Get-ChildItem Cert:\LocalMachine\My |
      Where-Object { $_.EnhancedKeyUsageList.FriendlyName -contains 'Server Authentication' } |
      Select-Object -First 1).Thumbprint -Force

# 2. Allow the firewall to accept 5986 from your MCP host.
New-NetFirewallRule -Name winrm-https-mcp -DisplayName "WinRM HTTPS from MCP" `
  -Protocol TCP -LocalPort 5986 -Direction Inbound -Action Allow `
  -RemoteAddress <MCP-HOST-IP>/32

# 3. Install PSPKI (Microsoft-owned, open source).
Install-Module PSPKI -Scope AllUsers -Force

# 4. Add the service account to the Remote Management Users group.
Add-LocalGroupMember -Group "Remote Management Users" -Member "CORP\svc-adcsmcp-ro"

# 5. Grant the Auditor role on the CA. Do this from certsrv.msc:
#    Right-click the CA → Properties → Security tab → Add
#    → CORP\svc-adcsmcp-ro → check "Read" and "Audit" (Auditor role)
# Programmatic equivalent:
$acl = Get-CertificationAuthorityAcl
$acl.Access.Add((New-CertificationAuthorityAccessRule `
    -Identity "CORP\svc-adcsmcp-ro" -Rights ReadOnly,Auditor -AccessControlType Allow))
$acl | Set-CertificationAuthorityAcl -RestartCA

The MCP host itself

Linux, Python 3.11+. If you want Kerberos-authenticated WinRM (recommended):

# Install Kerberos client + GSSAPI libraries.
sudo apt-get install -y krb5-user libkrb5-dev libssl-dev

# /etc/krb5.conf — minimum sane config for CORP.EXAMPLE.COM.
sudo tee /etc/krb5.conf > /dev/null <<'EOF'
[libdefaults]
    default_realm = CORP.EXAMPLE.COM
    rdns = false
    dns_canonicalize_hostname = true
    forwardable = true

[realms]
    CORP.EXAMPLE.COM = {
        # KDCs are typically your DCs.
        kdc = dc01.corp.example.com
        kdc = dc02.corp.example.com
    }

[domain_realm]
    .corp.example.com = CORP.EXAMPLE.COM
    corp.example.com  = CORP.EXAMPLE.COM
EOF

# Optionally create a keytab for the WinRM service account so
# you don't have to store its password in .env:
sudo ktutil -k /etc/krb5.keytab.svc-adcsmcp-ro
# then export KRB5_CLIENT_KTNAME=/etc/krb5.keytab.svc-adcsmcp-ro in your service unit.

You do not need to domain-join the MCP host. Any Linux host that can resolve the domain's DNS, reach the DCs on 636, and (for adcs-mcp) reach the CAs on 5986 is enough.


Installation

git clone https://github.com/<your-org>/ms-ad-mcp.git
cd ms-ad-mcp
pip install -e .            # adds-mcp + addns-mcp (LDAP only)
pip install -e ".[adcs]"    # adds pypsrp/kerberos deps for adcs-mcp's WinRM half

Or use the pinned images:

docker build -t adds-mcp  -f Dockerfile        .
docker build -t adcs-mcp  -f Dockerfile.adcs   .   # includes Kerberos client libs
docker build -t addns-mcp -f Dockerfile.addns  .

Configuration reference

All configuration is environment-driven and supports .env files. Copy .env.example.env and edit.

Shared LDAPS settings (read by all three servers)

Variable Required Default Description
ADDS_SERVERS Comma-separated DC hostnames or IPs. First reachable wins.
ADDS_PORT 636 LDAPS port.
ADDS_BIND_DN Full DN of the read-only service account.
ADDS_BIND_PASSWORD Password (or use secret-manager templating in the environment).
ADDS_BASE_DN Default search base. Usually the domain NC.
ADDS_DOMAIN DNS/NetBIOS domain name, for display only.
ADDS_TLS_VALIDATE true Set to false only for lab work.
ADDS_CA_CERT_FILE Path to a CA bundle if the DC cert isn't chained to system trust.
ADDS_HTTP_HOST 0.0.0.0 Bind host for adds-mcp.
ADDS_HTTP_PORT 8080 Bind port for adds-mcp.
ADDS_MAX_PAGE_SIZE 500 Hard cap on rows per tool call.
ADDS_DEFAULT_PAGE_SIZE 50 Default page size for paged searches.
ADDS_QUERY_TIMEOUT_SECONDS 30 Per-query timeout.
ADDS_TRANSPORT streamable-http stdio also supported.
ADDS_LOG_LEVEL INFO Python logging level.

adcs-mcp WinRM settings

Variable Required (WinRM tools only) Default Description
ADCS_CA_HOSTS Comma-separated online issuing CA hostnames.
ADCS_WINRM_USER CORP\svc-adcsmcp-ro (NTLM/negotiate) or svc@CORP.EXAMPLE.COM (Kerberos).
ADCS_WINRM_PASSWORD ✓ (unless keytab) Password. Omit if using Kerberos keytab.
ADCS_WINRM_AUTH negotiate negotiate, kerberos, ntlm, basic, or credssp. Prefer kerberos.
ADCS_WINRM_PORT 5986 WinRM HTTPS port.
ADCS_WINRM_USE_HTTPS true Should stay true.
ADCS_WINRM_CERT_VALIDATION true Set to false only for lab work.
ADCS_WINRM_READ_TIMEOUT 60 Seconds.
ADCS_WINRM_OPERATION_TIMEOUT 45 Seconds.
ADCS_HTTP_HOST 0.0.0.0 Bind host for adcs-mcp.
ADCS_HTTP_PORT 8081 Bind port for adcs-mcp.
ADCS_TRANSPORT streamable-http Same as ADDS_TRANSPORT.
ADCS_LOG_LEVEL INFO

addns-mcp settings

Variable Required Default Description
ADDNS_HTTP_HOST 0.0.0.0 Bind host for addns-mcp.
ADDNS_HTTP_PORT 8082 Bind port for addns-mcp.
ADDNS_TRANSPORT streamable-http
ADDNS_LOG_LEVEL INFO

All ADDS_* variables above are also read by addns-mcp (it reuses the same LDAPS bind).


Running the servers

Locally with the installed entrypoints

adds-mcp    # HTTP :8080/mcp
adcs-mcp    # HTTP :8081/mcp
addns-mcp   # HTTP :8082/mcp

Docker

docker run --rm -p 8080:8080 --env-file .env adds-mcp
docker run --rm -p 8081:8081 --env-file .env adcs-mcp
docker run --rm -p 8082:8082 --env-file .env addns-mcp

systemd (all three on one host)

Minimal unit — repeat for each server. Use secret manager or EnvironmentFile from a locked-down path; do not stash secrets in the unit itself.

# /etc/systemd/system/adds-mcp.service
[Unit]
Description=ms-ad-mcp adds-mcp (read-only AD DS MCP server)
After=network-online.target
Wants=network-online.target

[Service]
User=msadmcp
Group=msadmcp
EnvironmentFile=/etc/ms-ad-mcp/adds.env
ExecStart=/opt/ms-ad-mcp/venv/bin/adds-mcp
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Wiring into an MCP client

All three servers speak MCP over Streamable HTTP by default. The endpoint path is /mcp, so a client config looks like:

{
  "mcpServers": {
    "ms-ad-adds":  { "url": "https://mcp.internal.example.com:8080/mcp" },
    "ms-ad-adcs":  { "url": "https://mcp.internal.example.com:8081/mcp" },
    "ms-ad-addns": { "url": "https://mcp.internal.example.com:8082/mcp" }
  }
}

Front them with a TLS-terminating proxy (nginx / Caddy / Traefik) if you're exposing them beyond localhost. This repo doesn't terminate TLS itself.

For stdio-only clients, set ADDS_TRANSPORT=stdio (equivalently ADCS_TRANSPORT, ADDNS_TRANSPORT) and launch the command directly.


Security posture

  • Read-only end to end. ldap3.Connection(read_only=True) at the client layer; every tool uses SEARCH only. No add, modify, delete, modifyDN. On the CA hosts we execute only Get-* PowerShell cmdlets and read-only registry reads.
  • Least privilege. Both service accounts described above are unprivileged domain users. The WinRM account gets one narrowly-scoped role (Auditor) on each CA — nothing else.
  • Two-account separation. LDAPS and WinRM use different accounts on purpose; compromise of one doesn't cross services and each rotates on its own schedule.
  • LDAPS with cert validation. ADDS_TLS_VALIDATE=true is the default. If your DC certs chain through a private root, ship the root as a bundle and set ADDS_CA_CERT_FILE. Don't disable validation.
  • Prefer Kerberos. For WinRM, ADCS_WINRM_AUTH=kerberos with a keytab eliminates the plaintext password from .env entirely.
  • RFC 4515 filter escaping. All user-controlled substrings in LDAP filters go through an escape helper before hitting the DC.
  • Result caps. ADDS_MAX_PAGE_SIZE (default 500) hard-caps any single tool's return size to keep responses bounded and prevent inadvertent DC load.
  • No writes anywhere. If a future tool ever needed to mutate state, that belongs in a different MCP server with a different service account. We won't add write capabilities to these servers.

Troubleshooting

LDAPBindError: invalidCredentials

  • The service account password is wrong, or the bind DN doesn't resolve.
  • Test with ldapsearch -H ldaps://dc01 -x -D "CN=svc-…" -W -b "DC=corp,…" "(sAMAccountName=administrator)".

ldap3.core.exceptions.LDAPSSLConfigurationError / LDAPSocketOpenError

  • The DC cert isn't trusted on the MCP host. Point ADDS_CA_CERT_FILE at your root CA bundle, or verify the DC cert isn't expired (openssl s_client -connect dc01:636 -showcerts).

kerberos: Server not found in Kerberos database

  • The CA host doesn't have an HTTP SPN, or DNS reverse lookup returned a different name than the one you're connecting to.
  • Verify: setspn -L <ca-host> on Windows and nslookup <ca-ip> on Linux.

Access is denied in a PowerShell tool response

  • WinRM auth succeeded but the service account lacks the CA role.
  • On the CA: certutil -getreg CA\Security shows the ACL; re-grant Auditor.

Get-CertificationAuthority : The term is not recognized

  • PSPKI isn't installed on the CA. Run Install-Module PSPKI -Scope AllUsers.

Records come back as strings of gibberish from addns-mcp

  • Some ldap3 builds UTF-8-decode the dnsRecord binary attribute. The decoder tolerates this via a latin-1 re-encode, but if you see garbage, set the dnsRecord attribute to binary in your ldap3 config or file an issue with the exact ldap3 version.

WinRMUnavailable: pypsrp is not installed

  • The [adcs] extra wasn't installed. Run pip install ".[adcs]" or use Dockerfile.adcs which does this for you.

Tool reference

adds-mcp — 35 tools

Domain Tools
Users search_users, get_user, list_user_groups, list_locked_out_users, list_disabled_users, list_stale_users, list_recently_changed_users, list_password_never_expires
Groups search_groups, get_group, list_group_members, list_empty_groups, list_privileged_groups
OUs list_ous, get_ou, list_ou_children, get_ou_tree
Computers search_computers, get_computer, list_domain_controllers, list_stale_computers, summarize_computer_os
Group Policy list_gpos, get_gpo, find_gpo_links, list_links_on_ou
Domain get_domain_info, get_password_policy, list_fine_grained_password_policies, list_fsmo_roles, list_trusts, list_sites
Escape hatch ldap_search, get_object_by_dn, count_objects

Attribute decoding: SIDs → S-1-5-…, GUIDs → canonical form, FILETIMEs → ISO-8601, userAccountControl → decoded flag list + booleans, groupType → scope + security/distribution, lockoutDuration / maxPwdAge → ISO-8601 durations, gPLink → structured list of GPO links with enforced/disabled flags.

adcs-mcp — 24 tools

AD-side (LDAPS): list_enrollment_services, get_enrollment_service, list_root_cas, list_ntauth_cas, list_certificate_templates, get_certificate_template, list_templates_by_eku, find_templates_offered_by_ca, list_aia_entries, list_cdp_entries, list_kra_certificates, list_pki_oids.

WinRM-side (PowerShell + PSPKI): list_issued_certificates, list_pending_requests, list_failed_requests, list_revoked_certificates, get_certificate_by_serial, count_certificates_by_disposition, get_ca_configuration, list_ca_role_holders, list_officer_rights, get_ca_certificate_chain, list_ca_backup_settings.

Standalone: parse_certificate_pem — decode any PEM or base64 DER cert (subject/issuer/EKU/SAN/key usage/fingerprints/PEM).

addns-mcp — 9 tools

list_zones, get_zone, list_records, get_record, list_stale_records, list_conditional_forwarders, list_zone_delegations, search_by_name, search_by_ip.

Decodes dnsRecord blobs for A, AAAA, CNAME, NS, PTR, MX, SRV, TXT, SOA; aging timestamps (hours since 1601-01-01) are surfaced as ISO-8601.


Repository layout

src/
  adds_mcp/          # AD DS server
    __init__.py
    config.py        # ADDS_* settings from env
    client.py        # ldap3 wrapper (read_only=True, filter/DN escaping, paged search)
    formatting.py    # SID / GUID / FILETIME / UAC / groupType decoders
    server.py        # FastMCP entrypoint (Streamable HTTP)
    tools/           # users, groups, ous, computers, gpos, domain, search

  adcs_mcp/          # AD CS server (reuses adds_mcp.client for LDAPS)
    __init__.py
    config.py        # ADCS_* + reuses ADDS_* for LDAPS
    ldap_source.py   # Points reused ldap client at CN=Public Key Services
    winrm_source.py  # pypsrp WinRM PowerShell runner (optional extra)
    cert_utils.py    # X.509 parsing (cryptography)
    server.py
    tools/           # cas, templates, trust, issued, admin, parsing

  addns_mcp/         # AD-integrated DNS server (reuses adds_mcp.client for LDAPS)
    __init__.py
    config.py        # ADDNS_* + reuses ADDS_*
    ldap_source.py   # DomainDnsZones + ForestDnsZones + legacy MicrosoftDNS
    records.py       # MS-DNSP DNS_RECORD blob decoder
    server.py
    tools/           # zones, records, search

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured