MCP server for PingCastle Enterprise — query AD/Entra security reports, findings, comparisons, and scans from your LLM
Project description
pingcastle-mcp
Talk to PingCastle Enterprise from Claude
An MCP server that plugs a PingCastle Enterprise instance straight into Claude — browse domains and reports, surface critical Active Directory findings, compare scans over time, and kick off on-demand health checks, all in natural language.
7 MCP tools · reports & critical findings · scan diffing & score trends · on-demand scans · OS-keyring credentials · standalone Windows .exe
Install · Configure · Tools · Clients & local LLMs · How it works · Build
✨ Why
PingCastle Enterprise already scores your Active Directory and Entra ID security posture. pingcastle-mcp makes that data conversational:
"What changed in cloud.lab since last month?" "Show me the critical findings on the latest report." "Compare report 1002 against 1 and tell me what got fixed." "Run a fresh health check on cloud.lab."
Your LLM calls the right tool, pulls live data from the Enterprise REST API, and answers — no portal-clicking required.
🧰 Tools
| Tool | What it does |
|---|---|
list_domains |
Enumerate scanned domains / forests (and Entra tenants) with their latest score and report count |
list_reports |
List a domain's reports — id, date, global + category scores, maturity level |
get_report_summary |
Scores by category, maturity level, finding counts by category, and the top findings by points (for a report id, or a domain's latest) |
get_findings |
Matched risk rules for a report — filter by category and min_points (severity ≈ points) |
compare_reports |
Diff two reports: new / resolved / unchanged findings (by riskId) plus per-category & global score deltas |
score_trend |
Global score over time for a domain, sorted chronologically |
run_scan |
Trigger an on-demand PingCastle.exe health check and upload it to Enterprise (Windows + AD reachability) |
The read tools work on any OS with just an Enterprise URL + API key.
run_scanadditionally needsPingCastle.exe, so it lights up on a Windows host; elsewhere it degrades gracefully with a clear message.
📦 Install
From PyPI (recommended once published):
claude mcp add pingcastle -- uvx pingcastle-mcp
From GitHub, no clone:
claude mcp add pingcastle -- uvx --from git+https://github.com/dfirdeferred/PingCastle-MCP pingcastle-mcp
Manual clone:
git clone https://github.com/dfirdeferred/PingCastle-MCP && cd PingCastle-MCP
pip install .
claude mcp add pingcastle -- pingcastle-mcp
Standalone Windows .exe (no Python required) — download from Releases, verify, and register:
# verify the download against the published checksum
Get-FileHash .\pingcastle-mcp.exe -Algorithm SHA256
# compare with pingcastle-mcp.exe.sha256
claude mcp add pingcastle -- C:\path\to\pingcastle-mcp.exe
Project-scoped .mcp.json:
{ "mcpServers": { "pingcastle": { "command": "uvx", "args": ["pingcastle-mcp"] } } }
Using a different assistant (Cursor, Claude Desktop, VS Code, Cline, Ollama / LM Studio / local models, …)? See docs/CLIENTS.md for per-client setup.
🔐 Configure
Run the one-time setup — it prompts for your Enterprise URL and API key, validates them against the server, stores the URL in a config file and the API key in your OS keyring (Windows Credential Manager / macOS Keychain / Linux Secret Service):
pingcastle-mcp configure
Re-running configure rotates the key by overwriting it. Prefer environment variables (CI / headless)? Set them instead:
| Env var | Purpose |
|---|---|
PINGCASTLE_ENTERPRISE_URL |
Enterprise base URL |
PINGCASTLE_API_KEY |
API key (exchanged for a short-lived JWT at runtime) |
PINGCASTLE_EXE_PATH |
Path to PingCastle.exe — enables run_scan |
PINGCASTLE_INSECURE_TLS |
1 to skip TLS verification (self-signed lab certs) |
PINGCASTLE_LOGIN_LOCATION |
Override the location sent at login (default pingcastle-mcp) |
Resolution order: environment variables first, then stored config + keyring. The API key and JWT are never logged or written to disk in plaintext.
🏗 How it works
LLM client ──stdio──▶ FastMCP tool handlers (thin)
├──▶ EnterpriseClient ──HTTPS──▶ PingCastle Enterprise REST API
│ (API key → POST /api/Agent/Login → JWT; auto-refresh)
└──▶ Scanner ──▶ PingCastle.exe --healthcheck --api-endpoint … (upload to Enterprise)
- EnterpriseClient owns auth and all reads. The API key is exchanged for a
BearerJWT at/api/Agent/Login; the token is cached, proactively refreshed before expiry, and re-issued on a401. - Scanner wraps
PingCastle.exe, with a timeout that reaps the child process and graceful degradation when the exe isn't available. - Pure parsing/diff (summaries, filtering, report comparison, trends) is isolated and unit-tested against real captured API responses.
🩻 Requirements
- Python 3.11+ (for the pip/uvx install paths; the
.exebundles its own runtime) - A reachable PingCastle Enterprise instance + an API key (Agent authorization)
- For
run_scan: a Windows host withPingCastle.exeand AD/network reachability
🛠 Build from source
git clone https://github.com/dfirdeferred/PingCastle-MCP && cd PingCastle-MCP
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
pytest # 50 unit tests; live tests are opt-in via RUN_LIVE=1
Standalone Windows .exe (build on a Windows host — PyInstaller does not cross-compile):
pip install -e ".[dev]"
pyinstaller --clean packaging/pingcastle-mcp.spec
# -> dist\pingcastle-mcp.exe
See packaging/README-build.md for the build notes (entry-point wrapper, hidden imports).
🧪 Tests
- Unit tests run offline against real captured API fixtures (
50 passed). - Live integration tests are opt-in and hit a real server:
RUN_LIVE=1 PINGCASTLE_INSECURE_TLS=1 \ PINGCASTLE_ENTERPRISE_URL=https://your-pingcastle \ PINGCASTLE_API_KEY=… \ pytest tests/integration -v
🤝 Contributing
Issues and PRs welcome. The codebase is small, typed, and test-first — please add or update tests with any change.
📄 License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pingcastle_mcp-1.0.0.tar.gz.
File metadata
- Download URL: pingcastle_mcp-1.0.0.tar.gz
- Upload date:
- Size: 11.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cd329df208456698f5ad3a7913acb12acdf37b94f16cce89e0385696dcc2b5f
|
|
| MD5 |
224e61134df6a47b8ef5e87fa6142c17
|
|
| BLAKE2b-256 |
d54e907f57e801a36026d2f88a8abb50c2b9e007251ea0327c4ed8318f3524ad
|
File details
Details for the file pingcastle_mcp-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pingcastle_mcp-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9773ca73fbc4f15e104f19c55a64857c0ef3fa7bbd5345612408427d9bbc8c7
|
|
| MD5 |
f810249af2e5ed304bc13d7d29f29fc7
|
|
| BLAKE2b-256 |
f93f28a2fada09b31fdfc140969f22c7bf6e319332387fd1a96412ae6fdfbaab
|