Skip to main content

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.

License Python PyPI MCP Server Tools Platforms PingCastle PRs Welcome

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_scan additionally needs PingCastle.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 Bearer JWT at /api/Agent/Login; the token is cached, proactively refreshed before expiry, and re-issued on a 401.
  • 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 .exe bundles its own runtime)
  • A reachable PingCastle Enterprise instance + an API key (Agent authorization)
  • For run_scan: a Windows host with PingCastle.exe and 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.


Not affiliated with or endorsed by Netwrix / PingCastle. "PingCastle" is a trademark of its respective owner.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pingcastle_mcp-1.0.0.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pingcastle_mcp-1.0.0-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

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

Hashes for pingcastle_mcp-1.0.0.tar.gz
Algorithm Hash digest
SHA256 6cd329df208456698f5ad3a7913acb12acdf37b94f16cce89e0385696dcc2b5f
MD5 224e61134df6a47b8ef5e87fa6142c17
BLAKE2b-256 d54e907f57e801a36026d2f88a8abb50c2b9e007251ea0327c4ed8318f3524ad

See more details on using hashes here.

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

Hashes for pingcastle_mcp-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c9773ca73fbc4f15e104f19c55a64857c0ef3fa7bbd5345612408427d9bbc8c7
MD5 f810249af2e5ed304bc13d7d29f29fc7
BLAKE2b-256 f93f28a2fada09b31fdfc140969f22c7bf6e319332387fd1a96412ae6fdfbaab

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page