{
  "markdown": "# LDAP Assistant MCP\n\n<!-- mcp-name: io.github.droideck/ldap-assistant-mcp -->\n\n[![Version](https://img.shields.io/badge/version-0.5.0-blue.svg)](CHANGELOG.md)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE)\n\n> **Beta** — read-only 389 Directory Server diagnostics, suitable for evaluation and internal troubleshooting. Tool schemas, output formats, and configuration fields may still change before 1.0.0.\n\n**LDAP Assistant MCP turns your AI assistant into a 389 Directory Server support engineer.** Point it at live servers, stopped instances, or an SOS report from a customer case, and ask:\n\n- *\"What's wrong with my directory servers?\"*\n- *\"Summarize this SOS report before I open the case.\"*\n- *\"Replication looks broken between these servers — why?\"*\n\nIt answers with prioritized findings (severity, impact, remediation) from 42 read-only diagnostic tools built on [lib389](https://pypi.org/project/lib389/), the official 389 DS administration library. **Privacy mode is on by default**: DNs, hostnames, and IPs are redacted before anything reaches the LLM.\n\n**Supported provider: 389 Directory Server.** (OpenLDAP provider code exists experimentally behind an opt-in flag, with no privacy guarantees, and is not part of the support contract — see [Environment Variables](#environment-variable-reference).)\n\n## Install\n\n### Prerequisites\n\n- Linux (primary) or macOS. Windows is not supported natively (python-ldap has no official Windows wheels) — use WSL2 (see the [install playbook](docs/playbooks/install-troubleshooting.md#windows-and-wsl2))\n- Python 3.11+ (3.13 is what CI tests against)\n- [`uv`](https://docs.astral.sh/uv/) package manager\n- MCP client (Claude Desktop, Claude Code, Cursor, Gemini CLI, etc.)\n- System development libraries (needed to build `python-ldap`):\n\n  **Fedora / RHEL / CentOS:**\n  ```bash\n  sudo dnf install python3-devel openldap-devel cyrus-sasl-devel openssl-devel gcc\n  ```\n\n  **Ubuntu / Debian:**\n  ```bash\n  sudo apt install python3-dev libldap2-dev libsasl2-dev libssl-dev gcc\n  ```\n\n  **macOS (Homebrew):**\n  ```bash\n  brew install openldap\n  export LDFLAGS=\"-L$(brew --prefix openldap)/lib\"\n  export CPPFLAGS=\"-I$(brew --prefix openldap)/include\"\n  ```\n\nAnything failing during install? → [Installation troubleshooting playbook](docs/playbooks/install-troubleshooting.md)\n\n### From PyPI (recommended)\n\nNo clone needed — your MCP client runs the published package via `uvx`. Skip ahead to [Configure your servers](#configure-your-servers), then use this client configuration (Claude Desktop: `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):\n\n```json\n{\n  \"mcpServers\": {\n    \"ldap-assistant-mcp\": {\n      \"command\": \"uvx\",\n      \"args\": [\"ldap-assistant-mcp\"],\n      \"env\": {\n        \"LDAP_SERVERS_CONFIG\": \"/absolute/path/to/servers.json\"\n      }\n    }\n  }\n}\n```\n\nUse an **absolute path** for `LDAP_SERVERS_CONFIG` — relative paths resolve against the MCP client's working directory, which is usually not where you think.\n\n### From source (development)\n\n```bash\ngit clone https://github.com/droideck/ldap-assistant-mcp.git\ncd ldap-assistant-mcp\nuv venv && source .venv/bin/activate\nuv pip install -e .[dev]\n\n# Register with your MCP client via FastMCP:\nfastmcp install claude-desktop fastmcp.json   # or: fastmcp install claude-code fastmcp.json\n```\n\nThen set `LDAP_SERVERS_CONFIG` in the generated client entry as above. See the [Development Guide](docs/DEVELOPMENT.md) for test containers and architecture.\n\n## Configure your servers\n\nCreate a `servers.json` with your LDAP server(s). **Note:** the `name` field is never redacted in privacy mode — it is passed as-is to AI agents so they can reference servers across tool calls. Do not put hostnames, IPs, or other private information in server names.\n\n```json\n{\n  \"servers\": [\n    {\n      \"name\": \"local-ds\",\n      \"ldap_url\": \"ldap://localhost:389\",\n      \"base_dn\": \"dc=example,dc=com\",\n      \"bind_dn\": \"cn=Directory Manager\",\n      \"bind_password\": \"your-password\",\n      \"provider_type\": \"389ds\",\n      \"is_local\": true,\n      \"serverid\": \"localhost\"\n    },\n    {\n      \"name\": \"remote-ds\",\n      \"ldap_url\": \"ldap://ldap.example.com:389\",\n      \"base_dn\": \"dc=example,dc=com\",\n      \"bind_dn\": \"cn=Directory Manager\",\n      \"bind_password\": \"your-password\",\n      \"provider_type\": \"389ds\"\n    },\n    {\n      \"name\": \"stopped-ds\",\n      \"ldap_url\": \"ldap://localhost:389\",\n      \"base_dn\": \"dc=example,dc=com\",\n      \"bind_dn\": \"cn=Directory Manager\",\n      \"bind_password\": \"unused-in-offline-mode\",\n      \"provider_type\": \"389ds\",\n      \"is_local\": true,\n      \"serverid\": \"localhost\",\n      \"is_offline\": true\n    },\n    {\n      \"name\": \"sos-report\",\n      \"provider_type\": \"389ds\",\n      \"is_archive\": true,\n      \"archive_path\": \"/path/to/sosreport-host-2025/\",\n      \"instance_name\": \"slapd-instance\"\n    }\n  ]\n}\n```\n\n**Note:** `serverid` is the instance name *without* the `slapd-` prefix (e.g. `localhost` for the instance `slapd-localhost`).\n\n### The four server modes\n\n| Mode | Config | What you get |\n|------|--------|--------------|\n| **Remote** | `ldap_url` only | Health, replication, performance, config, and entry tools over LDAP. No log/disk/cert access |\n| **Local** | + `is_local: true`, `serverid` | Everything above **plus** log analysis, disk monitoring, certificate checks, process metrics |\n| **Offline** | + `is_offline: true` | A stopped local instance, analyzed via dse.ldif and log files — no LDAP connection. For post-mortems and instances that won't start |\n| **Archive** | `is_archive: true`, `archive_path` | An SOS report or config/log extract from **any** machine (tarball or directory, auto-detected layout). No LDAP, no local instance required |\n\nTools that need a live connection tell you so — the error names the tools that *do* work in that server's mode, so the investigation continues instead of dead-ending.\n\n**Remote LDAPS certificate verification:** remote `ldaps://` servers verify the server certificate by default (`\"tls_verify\": true`, or the `LDAP_TLS_VERIFY` environment variable for env-based config). To connect to a server with a self-signed or otherwise untrusted certificate, set `\"tls_verify\": false` on that server entry — this disables certificate verification entirely, so use it only for trusted lab environments. Local instances (`is_local: true`) instead use the instance's own NSS certificate directory.\n\nAfter editing the client config or `servers.json`, restart your MCP client, then verify: ask *\"Which LDAP servers are configured?\"*\n\n## Privacy mode\n\nBy default, **privacy mode is enabled** — sensitive data (DNs, hostnames, IPs, user details) is redacted from tool outputs. Tools that expose individual entries (`get_user_details`, `ldap_search`) are disabled; list tools return counts only. Diagnostic metrics (counts, ratios, percentages) remain visible.\n\nTo enable full data access in **trusted environments only**:\n\n```json\n{\n  \"env\": {\n    \"LDAP_MCP_EXPOSE_SENSITIVE_DATA\": \"true\"\n  }\n}\n```\n\n**Important:** Only enable this with local models, private cloud LLM instances, or when working with test/sample data. Avoid enabling with public LLMs when connected to production directories — your directory information could be included in their training data or logs.\n\nWhen privacy mode is enabled (default):\n- Hostnames, DNs, IP addresses, and suffixes are anonymized\n- Configuration values are redacted\n- Sensitive tools are disabled\n- Diagnostic metrics (counts, ratios, percentages) remain visible\n- Server names (the `name` field in `servers.json`) are **never** redacted — they are user-chosen labels that must remain stable across tool calls. Do not put hostnames, IPs, or other private information in server names.\n\n### Data handling\n\n- **No telemetry.** The server collects nothing and phones home to no one.\n- **Everything runs locally.** Directory data is read from your LDAP servers, local instances, or archive files and returned only to your MCP client — which forwards tool results to whatever LLM you have configured. Privacy mode (on by default) redacts sensitive values before they leave the server process.\n- **Credentials** stay in your local `servers.json` / environment variables; they are never included in tool output and tool errors are sanitized.\n\n## First questions to ask\n\n| You want | Ask / use | Behind it |\n|----------|-----------|-----------|\n| A health overview of everything | *\"What's wrong with my directory servers?\"* | `first_look` |\n| An SOS report summarized | *\"Analyze the sos-report archive\"* or the `archive_investigation` prompt | `analyze_archive` → [archive playbook](docs/playbooks/archive-sos.md) |\n| To know which tool fits a goal | the `tool_navigator` prompt | tool map for a stated goal |\n| Guided replication triage | the `diagnose_replication` prompt | replication tool sequence |\n| Guided performance triage | the `performance_investigation` prompt | performance tool sequence |\n| A morning ops review | the `daily_health_check` prompt | health + monitoring sweep |\n\n**Playbooks** (symptom → tools → what they can't know → how to verify by hand):\n\n- [Summarize an SOS report before opening the case](docs/playbooks/archive-sos.md)\n- [Installation troubleshooting](docs/playbooks/install-troubleshooting.md)\n\n## Tools by group\n\n42 read-only tools — full reference with parameters in [TOOLS.md](src/ldap_assistant_mcp/dirsrv_mcp/TOOLS.md).\n\n| Group | Tools | Highlights |\n|-------|-------|-----------|\n| Health | `first_look`, `run_healthcheck`, `list_healthchecks`, `server_health` | Multi-server overview; full `dsctl healthcheck` equivalent |\n| Replication | `get_replication_status`, `get_replication_topology`, `check_replication_lag`, `list_replication_conflicts`, `get_agreement_status` | RUV/CSN analysis, topology mapping, conflict entries |\n| Performance | `get_performance_summary`, cache/connection/operation/thread/resource statistics | Bottleneck detection and tuning recommendations |\n| Indexes | `list_indexes`, `analyze_index_configuration`, `find_unindexed_searches` | Access-log-driven unindexed search hunting |\n| Configuration | `get_server_configuration`, `compare_server_configurations`, `list_plugins`, `get_backend_configuration` | Live **and** offline (dse.ldif) paths |\n| Logs | `analyze_access_log` / `analyze_error_log` / `analyze_audit_log` (stats, privacy-safe), `parse_*_log` (full entries, requires sensitive-data mode) | Traditional and JSON log formats |\n| Archive / SOS | `analyze_archive`, `validate_configuration`, `compare_dse_configs` | Inventory, offline config lint, full dse.ldif diff |\n| Users & Groups | list/search/inspect users, active/locked filters, groups | Count-only in privacy mode |\n| Advanced | `ldap_search`, `run_monitor`, `list_servers`, cn=config resources | Generic search (sensitive-data mode only) |\n\n## Environment Variable Reference\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `LDAP_SERVERS_CONFIG` | – | Absolute path to `servers.json` (multi-server config; preferred) |\n| `LDAP_PROVIDER` | `dirsrv` | Server implementation. Only `dirsrv` (389 DS) is supported; `openldap` requires the opt-in flag below |\n| `LDAP_MCP_EXPERIMENTAL_OPENLDAP` | `false` | Opt in to the experimental OpenLDAP provider (two tools, **no privacy guarantees**) |\n| `LDAP_MCP_EXPOSE_SENSITIVE_DATA` | `false` | Disable privacy mode (see [Privacy Mode](#privacy-mode)) |\n| `LDAP_MCP_DEBUG` | `false` | Enable debug logging and tracebacks in tool errors |\n| `LDAP_MCP_TOOL_TIMEOUT` | `30` | Per-tool-call timeout in seconds |\n| `LDAP_MCP_MAX_TOOL_TIMEOUT` | `120` | Timeout ceiling for heavy tools (`first_look`, archive comparison, …) |\n| `LDAP_CONNECT_TIMEOUT` | `30` | LDAP network/operation timeout in seconds (prevents hangs on unreachable servers) |\n\nSingle-server fallback (used only when `LDAP_SERVERS_CONFIG` is not set):\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `LDAP_URL` | – | Full LDAP URL (alternative to hostname/port/SSL vars) |\n| `LDAP_HOSTNAME` / `LDAP_PORT` / `LDAP_USE_SSL` | `localhost` / `389` / `false` | Connection parameters |\n| `LDAP_BASE_DN` | – | Default search base |\n| `LDAP_BIND_DN` / `LDAP_BIND_PASSWORD` | `cn=Directory Manager` / – | Bind credentials (no default password) |\n| `LDAP_AUTH_METHOD` | `simple` | `simple` or `anonymous` (the only implemented binds; LDAPI/SASL EXTERNAL is selected via `LDAP_USE_LDAPI`, not here) |\n| `LDAP_IS_LOCAL` / `LDAP_SERVERID` | `false` / – | Enable local-instance features (logs, disk, certs) |\n| `LDAP_USE_LDAPI` | `false` | Connect over the LDAPI unix socket |\n| `LDAP_IS_OFFLINE` | `false` | Treat the local instance as stopped (offline mode) |\n| `LDAP_TLS_VERIFY` | `true` | Verify the server certificate on remote `ldaps://` connections (set `false` only for trusted labs) |\n\n## Troubleshooting\n\n| Symptom | Cause / Fix |\n|---------|-------------|\n| `python-ldap` fails to build during install | Missing system headers — see the [install playbook](docs/playbooks/install-troubleshooting.md#python-ldap-build-failures) |\n| Tools report a default `localhost` server instead of your config | `LDAP_SERVERS_CONFIG` not set or not loadable in the MCP client config — see [servers.json path resolution](docs/playbooks/install-troubleshooting.md#serversjson-path-resolution) |\n| `list_*` tools return only counts; `ldap_search`/`get_user_details` refuse to run | That's privacy mode (default, working as intended) — see [Privacy Mode](#privacy-mode) |\n| \"requires a running server with a live LDAP connection\" errors | The target is an offline/archive server — the error message lists the tools that do work there |\n| LDAPI connection fails for a local server | Check `serverid` has no `slapd-` prefix and the instance socket exists |\n\nNo LDAP server to test against? The [Development Guide](docs/DEVELOPMENT.md) spins up test containers with Docker.\n\n## Limitations\n\n- **Beta** — Tool schemas, output formats, and configuration fields may change before 1.0.0\n- **LLM interpretation** — Tools return accurate data, but the LLM interprets it. Hallucinations are possible. Always verify recommendations before acting.\n- **Read-only** — No write operations yet\n- **Plain text passwords** — Use restrictive file permissions on config files\n- **STDIO transport only** — No HTTP/SSE support yet\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [Changelog](CHANGELOG.md) | Version history and release notes |\n| [Archive / SOS playbook](docs/playbooks/archive-sos.md) | Summarize an SOS report before opening the case |\n| [Install playbook](docs/playbooks/install-troubleshooting.md) | python-ldap builds, WSL2, uvx, config path resolution |\n| [Development Guide](docs/DEVELOPMENT.md) | Dev environment setup, configuration, architecture |\n| [Testing Guide](docs/TESTING.md) | Running and writing tests |\n| [Contributing Guide](docs/CONTRIBUTING.md) | How to contribute |\n| [Release Checklist](docs/RELEASE.md) | How releases are cut and verified |\n| [389 DS Tools](src/ldap_assistant_mcp/dirsrv_mcp/TOOLS.md) | 389 Directory Server tools reference |\n| [OpenLDAP Tools](src/ldap_assistant_mcp/openldap_mcp/TOOLS.md) | OpenLDAP tools reference (experimental, opt-in only) |\n\n## License\n\n[GPL-3.0-or-later](LICENSE). Built on [lib389](https://pypi.org/project/lib389/) (the official 389 Directory Server administration library) and [FastMCP](https://gofastmcp.com).\n\n## References\n\n- [PyPI package](https://pypi.org/project/ldap-assistant-mcp/)\n- [Official MCP Registry](https://registry.modelcontextprotocol.io) — listed as `io.github.droideck/ldap-assistant-mcp`\n- [Model Context Protocol](https://modelcontextprotocol.io/introduction)\n- [389 Directory Server](https://www.port389.org/docs/389ds/documentation.html)\n- [FastMCP 2.0](https://gofastmcp.com)\n",
  "bytes": 15821,
  "sha": "7caede4f96b49ffd51c8cb56248021a048083facd180a803ecd6b503b2241cc8",
  "repo_slug": "droideck/ldap-assistant-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_droideck_ldap_assistant_mcp_8ed8a17f/readme"
}