Skip to main content
Glama
README.md
# BloodHound Enterprise MCP

[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

A Model Context Protocol (MCP) server that connects LLMs to BloodHound Enterprise. Ask questions in natural language, get attack path analysis, run Cypher queries, and explore Active Directory, Azure/Entra ID, and OpenGraph environments — all from your AI assistant.

## Fork Attribution

This project is a fork of [mwnickerson/bloodhound_mcp](https://github.com/mwnickerson/bloodhound_mcp). The original project and its contributors created the BloodHound MCP foundation this fork builds on.

This fork modifies the original BloodHound Community Edition-focused implementation for BloodHound Enterprise API coverage, multi-tenant MCP configuration, expanded endpoint wrappers, Enterprise attack path/risk posture workflows, and BHE-specific documentation. The project remains licensed under GPL-3.0; see [LICENSE](LICENSE) and [NOTICE](NOTICE).

---

## How It Works

The server exposes BloodHound Enterprise's REST API and Neo4j graph through a set of composite MCP tools, reference resources, and a system prompt tuned for offensive security analysis.

### Composite Tools

Each tool uses an `info_type` parameter to select what data is returned, keeping the tool surface small and token-efficient:

| Tool | `info_type` Options |
|------|---------------------|
| `domain_info` | `list`, `info`, `search`, `users`, `groups`, `computers`, `controllers`, `gpos`, `ous`, `dc_syncers`, `foreign_admins`, `foreign_gpo_controllers`, `foreign_groups`, `foreign_users`, `inbound_trusts`, `outbound_trusts`, `linked_gpos`, `adcs_escalations` |
| `entity_info` | `base_info`, `base_controllables`, `base_controllers`, `container_info`, `container_controllers`, `azure_entity` |
| `user_info` | `info`, `sessions`, `memberships`, `admin_rights`, `rdp_rights`, `dcom_rights`, `ps_remote_rights`, `sql_admin_rights`, `constrained_delegation`, `controllables`, `controllers` |
| `group_info` | `info`, `members`, `memberships`, `admin_rights`, `rdp_rights`, `dcom_rights`, `ps_remote_rights`, `controllers`, `controllables` |
| `computer_info` | `info`, `sessions`, `local_admins`, `rdp_rights`, `dcom_rights`, `ps_remote_rights`, `sql_admins`, `constrained_delegation`, `controllables`, `controllers` |
| `ou_info` | `info`, `users`, `groups`, `computers`, `gpos` |
| `gpo_info` | `info`, `computers`, `controllers`, `ous`, `tier_zeros`, `users` |
| `graph_analysis` | `kinds`, `search`, `shortest_path`, `edge_composition`, `relay_targets`, `pathfinding`, `acl_inheritance` |
| `adcs_info` | `cert_template_info`, `cert_template_controllers`, `cert_template_published_to_cas`, `root_ca_info`, `root_ca_controllers`, `root_ca_pki_hierarchy`, `enterprise_ca_info`, `enterprise_ca_controllers`, `enterprise_ca_pki_hierarchy`, `enterprise_ca_published_templates`, `aia_ca_info`, `aia_ca_controllers`, `aia_ca_pki_hierarchy`, `nt_auth_store_info`, `nt_auth_store_controllers`, `nt_auth_store_trusted_cas` |
| `cypher_query` | `run`, `interpret`, `list_saved`, `create_saved`, `get_saved`, `update_saved`, `delete_saved`, `share_saved`, `saved_permissions`, `export_saved`, `import_saved`, `export_saved_many`, `validate` |
| `attack_paths` | `domain_findings`, `finding_trends`, `types`, `start_analysis`, `details`, `domain_available_types`, `domain_details`, `domain_sparkline`, `acceptance` |
| `risk_posture` | `stats`, `history` |
| `enterprise_info` | `version`, `spec`, `audit`, `config`, `features` |
| `enterprise_admin` | `self`, `permissions`, `permission`, `roles`, `role`, `users`, `users_minimal`, `user`, `saml`, `saml_sso`, `saml_provider`, `sso_providers`, `sso_signing_certificate` |
| `data_quality` | `completeness`, `ad_domain`, `azure_tenant`, `platform` |
| `asset_groups` | `list`, `get`, `create`, `update`, `delete`, `collections`, `custom_selectors`, `members`, `member_counts`, `combo_node`, `create_selectors`, `update_selectors`, `delete_selector`, `list_tags`, `create_tag`, `tag_members`, `tag_member_selectors`, `tag_member_counts`, `tag_selectors`, `tag_selector_members`, `tag_selector_member_counts`, `preview_tag_selectors`, `search_tags`, `tag_history`, `search_tag_history`, `certifications`, `update_certifications` |
| `custom_nodes` | `list`, `get`, `create`, `update`, `delete`, `validate_icon`, `extension_list`, `extension_upsert`, `extension_delete`, `extension_edges` |
| `file_upload` | `upload`, `start_job`, `upload_to_job`, `end_job`, `list_jobs`, `completed_tasks`, `accepted_types` |
| `operations_info` | `datapipe_status`, `analysis`, `meta_nodes`, `meta_tree`, `meta_entity` |
| `collection_info` | `collector_manifest`, `collector_checksum`, `kennel_manifest`, `kennel_enterprise_manifest`, `clients`, `client`, `client_completed_tasks`, `client_completed_jobs`, `jobs_available`, `jobs_finished`, `jobs`, `job_current`, `job`, `job_log`, `tasks_available`, `tasks_finished`, `tasks`, `task_current`, `task`, `task_log`, `events`, `event` |

### Resources

Reference material the LLM loads on demand — no extra API calls:

| Resource URI | Contents |
|---|---|
| `bloodhound://cypher/reference` | Cypher syntax, schema, property names, patterns |
| `bloodhound://cypher/query-building-reference` | Quick query-building syntax patterns |
| `bloodhound://cypher/supported-syntax` | Supported BloodHound Cypher syntax, caveats, and unsupported constructs |
| `bloodhound://cypher/offensive-queries` | Battle-tested templates: DCSync, Kerberoasting, GPO abuse, delegation, ADCS, shadow credentials, NTLM relay, and more |
| `bloodhound://guides/ad` | AD node types and relationships quick reference |
| `bloodhound://guides/ad-methodology` | Full AD attack methodology and workflow |
| `bloodhound://guides/azure` | Azure/Entra ID analysis quick reference |
| `bloodhound://guides/azure-methodology` | Full Azure attack chains |
| `bloodhound://guides/adcs` | ADCS ESC1–ESC13 quick reference |
| `bloodhound://guides/adcs-methodology` | Detailed ESC analysis and exploitation |
| `bloodhound://opengraph/guide` | Custom node schema design and best practices |
| `bloodhound://opengraph/examples` | SQL Server and Web App OpenGraph examples |

### System Prompt

The `bloodhound_assistant` prompt includes behavioral rules that guide the LLM:

- Load the offensive query library before writing Cypher for any attack scenario
- Never draw privilege conclusions without checking group memberships and `admincount`
- Respect BloodHound's property naming conventions (`hasspn`, `enabled`, `admincount` — all lowercase)
- Handle uppercase name storage (`DOMAIN ADMINS@CORP.LOCAL`) correctly in filters
- Follow proper DCSync and GPO edge traversal patterns

---

## Prerequisites

- Python 3.11+
- [uv](https://docs.astral.sh/uv/)
- BloodHound Enterprise instance with data loaded
- BloodHound API credentials (Token ID + Token Key)

---

## Installation

```bash
git clone https://github.com/mwnickerson/bloodhound_mcp.git ~/git/bhe_mcp
cd ~/git/bhe_mcp
uv sync
```

Create a `.env` file in the project root:

```env
BLOODHOUND_DOMAIN=your-bloodhound-instance.domain.com
BLOODHOUND_TOKEN_ID=your-token-id
BLOODHOUND_TOKEN_KEY=your-token-key
```

The server defaults to `https` on port `443`. Override if needed:

```env
BLOODHOUND_PORT=8080
BLOODHOUND_SCHEME=http
```

---

## Configuration

### Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "bhe_mcp": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/bhe_mcp",
        "run",
        "main.py"
      ]
    }
  }
}
```

### Claude Code

Add to `~/.claude/mcp.json`:

```json
{
  "mcpServers": {
    "bhe_mcp": {
      "type": "stdio",
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/bhe_mcp",
        "run",
        "main.py"
      ]
    }
  }
}
```

### OpenAI Codex CLI

Add to `~/.codex/config.toml` (or `.codex/config.toml` for project-scoped config):

```toml
[mcp_servers.bhe_mcp]
command = "uv"
args = ["--directory", "/path/to/bhe_mcp", "run", "main.py"]
```

Since the server loads credentials from `.env` automatically, no `env` block is needed. If you prefer to pass them explicitly:

```toml
[mcp_servers.bhe_mcp]
command = "uv"
args = ["--directory", "/path/to/bhe_mcp", "run", "main.py"]

[mcp_servers.bhe_mcp.env]
BLOODHOUND_DOMAIN = "your-bloodhound-instance.domain.com"
BLOODHOUND_TOKEN_ID = "your-token-id"
BLOODHOUND_TOKEN_KEY = "your-token-key"
```

For multiple BHE tenants, point each MCP server at the same checkout and give each one its own env file. This keeps `demo` and `maplesyrup` distinct by server name and by the codename in the env file path:

```toml
[mcp_servers.bloodhound_demo]
command = "uv"
args = ["--directory", "/path/to/bhe_mcp", "run", "main.py"]

[mcp_servers.bloodhound_demo.env]
UV_CACHE_DIR = "/path/to/uv-cache"
BLOODHOUND_ENV_FILE = "/path/to/bloodhound_demo.env"

[mcp_servers.bloodhound_maplesyrup]
command = "uv"
args = ["--directory", "/path/to/bhe_mcp", "run", "main.py"]

[mcp_servers.bloodhound_maplesyrup.env]
UV_CACHE_DIR = "/path/to/uv-cache"
BLOODHOUND_ENV_FILE = "/path/to/bloodhound_maplesyrup.env"
```

### MCP Inspector

- **Command:** `uv`
- **Args:** `--directory /path/to/bhe_mcp run main.py`

### BloodHound API Token

1. Log into BloodHound Enterprise
2. Navigate to **Administration** → **API Tokens**
3. Create a new token and copy the Token ID and Token Key into your `.env`

---

## Usage

### Example Queries

**Reconnaissance:**
```
What domains are in BloodHound?
Show me all Domain Admins in CORP.LOCAL
Find all kerberoastable users
Which computers have unconstrained delegation?
```

**User and Group Analysis:**
```
What admin rights does jsmith@corp.local have?
Show me all sessions for the administrator account
What groups is this user a member of?
Who controls the IT ADMINS group?
```

**Attack Path Analysis:**
```
Find the shortest path from jsmith@corp.local to Domain Admins
Who has DCSync rights in the domain?
Show me all GPO abuse paths
Find ADCS ESC1 paths in the domain
```

**Custom Cypher:**
```
Run a Cypher query to find all users with SPN set and admincount=1
Find all computers where DOMAIN USERS can RDP
```

---

## OpenGraph Support

BloodHound 8.0+ supports custom node types via OpenGraph, letting you model non-AD infrastructure (cloud resources, databases, custom assets) in the same graph as Active Directory.

The `custom_nodes` tool handles legacy CRUD operations on node type display configurations through `/api/v2/custom-nodes`. For BloodHound v9.0.0+ instances with OpenGraph extension management enabled, the same composite tool also supports `/api/v2/extensions` and `/api/v2/extensions-edges` via `extension_list`, `extension_upsert`, `extension_delete`, and `extension_edges`.

Use the `bloodhound://opengraph/guide` and `bloodhound://opengraph/examples` resources for schema design and Cypher patterns. For structured OpenGraph schemas, upsert the extension schema first, then ingest collection data with `file_upload`.

> Requires BloodHound 8.0 or later.
> OpenGraph extension management requires BloodHound 9.0.0+ and the corresponding feature flag to be enabled.

---

## Security Considerations

BloodHound data processed through this tool is transmitted to your LLM provider's servers. **Do not use this with production AD data unless you have assessed that risk.**

Recommended use cases:
- Lab environments (GOAD, DetectionLab, custom ranges)
- Training and certification prep
- Research and tool development
- Non-production domain analysis

Best practices:
- Rotate BloodHound API tokens regularly
- Use a read-only API token where possible
- Consider a local LLM bridge for sensitive environments

---

## Testing

```bash
# Full test suite
uv run pytest

# Specific modules
uv run pytest tests/test_main_mcp_tools.py -v
uv run pytest tests/test_bloodhound_api.py -v

# Integration tests (requires a live BloodHound instance)
BLOODHOUND_INTEGRATION_TESTS=1 uv run pytest tests/test_integration.py -v
```

---

## Contributing

Contributions are welcome. Open an issue to discuss significant changes before submitting a PR.

1. Fork the repo
2. Create a feature branch
3. Add tests for new functionality
4. Run `uv run pytest` and confirm everything passes
5. Submit a pull request

---

## Acknowledgments

- **SpecterOps** for [BloodHound](https://github.com/SpecterOps/BloodHound)
- **Orange Cyberdefense** for [GOAD](https://github.com/Orange-Cyberdefense/GOAD) (used for testing)
- **@jlowin** for [FastMCP](https://github.com/jlowin/fastmcp)
- **@xpn** for MCP inspiration via the Mythic MCP project

## License

GNU General Public License v3.0 — see [LICENSE](LICENSE) for details.

TDQS

A3.9/5.0

Scored across 20 tools

Disambiguation4/5

Most tools target distinct entity types or domains (group, user, computer, domain, GPO, OU, ADCS, etc.), but there is some potential confusion between graph_analysis and cypher_query (both can explore paths) and between enterprise_info, operations_info, and collection_info which all deal with BHE system metadata. Descriptions are detailed enough to disambiguate in most cases.

Naming Consistency3/5

Tool names are all snake_case and readable, but there is no consistent verb_noun pattern. Many use an '_info' suffix (group_info, user_info, computer_info), while others are noun phrases (asset_groups, attack_paths, cypher_query) or verb phrases (file_upload). This mix is acceptable but not a uniform convention.

Tool Count4/5

20 tools is on the higher end but appropriate given the breadth of the BloodHound Enterprise API. Each tool covers a distinct functional area, and many pack multiple sub-operations via info_type, so the count is justified without being excessive.

Completeness4/5

The tool set covers major BloodHound domains: entity queries, graph analysis, cypher execution, attack paths, enterprise admin, file upload, collection status, and data quality. Minor gaps exist, such as limited Azure entity support and missing some niche BHE endpoints, but the surface is generally comprehensive for common workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues