Open-ended graph investigation via raw OpenCypher queries. Use when the prebuilt tools don't capture the question — bespoke "find every X that can reach Y via Z" queries, ad-hoc relationship walks, novel attack-path patterns, or one-off exports for analysis. Read-only by default; writes require explicit opt-in.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bloodhound-enterprise:cypher-investigationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The pre-built BHE endpoints answer most common questions, but the graph holds far more than they expose. Cypher is the escape hatch — a query language that walks nodes and edges arbitrarily — and `run_cypher` is the tool that lets the agent ask anything.
The pre-built BHE endpoints answer most common questions, but the graph holds far more than they expose. Cypher is the escape hatch — a query language that walks nodes and edges arbitrarily — and run_cypher is the tool that lets the agent ask anything.
The cost of that flexibility is that bad queries can either drown the session in results or accidentally mutate state. This skill walks the agent through the discipline of writing safe, scoped, useful Cypher.
bhe-bootstrap has run.
Before writing Cypher, check whether the question maps to one of the dedicated tools:
computer_admins.user_admin_rights(kind="rdp-rights").domain_attack_paths.list_tag_members.Use Cypher only when the answer needs a graph traversal the prebuilt tools don't cover.
Call list_saved_queries. The deployment usually carries a curated set: "Find all kerberoastable users", "Map domain trusts", "Find shortest paths from owned to high value". Run a saved query before writing a fresh one — saved queries have been reviewed by operators and tend to handle edge cases (excluding gMSAs, capping by domain) the agent's first attempt won't.
A few rules that keep queries productive:
LIMIT — even small graphs can return tens of thousands of paths from a MATCH p=shortestPath(...) query. The runtime injects a default LIMIT, but explicit limits give the agent control.MATCH (u:User) vs MATCH (u). The latter walks every node kind and is dramatically slower.objectid ENDS WITH for well-known SIDs — '-512' for Domain Admins, '-513' for Domain Users, '-519' for Enterprise Admins.shortestPath for attack paths — finds the minimal route between two anchors. Often the only practical way to enumerate paths in a large graph.MATCH clauses without a relationship between them produces N×M rows. Bound them with WHERE predicates joined by AND.Examples that come up often:
// Every user in Tier Zero who has an SPN (Kerberoastable Tier Zero)
MATCH (u:User)
WHERE u.hasspn = true AND u.enabled = true
AND u.gmsa <> true AND u.msa <> true AND u.highvalue = true
RETURN u
LIMIT 100
// Shortest paths from Domain Users to Tier Zero
MATCH p = shortestPath((g:Group)-[*1..]->(t))
WHERE g.objectid ENDS WITH '-513' AND t.highvalue = true
RETURN p
LIMIT 50
// Cert templates with dangerous ESC1 prerequisites
MATCH (ct:CertTemplate)
WHERE ct.requiresmanagerapproval = false
AND ct.authenticationenabled = true
AND ct.enrolleessuppliessubject = true
AND ct.nocertificatemapping = false
RETURN ct
LIMIT 100
allow_writes=FalseThe tool's default refuses queries containing CREATE, MERGE, DELETE, SET, REMOVE, DETACH, or DROP. That blocks accidental mutation. If the query genuinely needs to write (rare — usually selector creation is the right path), pass allow_writes=True explicitly and document why.
The tool returns a digest: counts + the first N nodes / edges. If the result is truncated, refine the query rather than asking for more rows — refining is cheaper and produces better-targeted answers. Common refinements:
AND n.domain_sid = 'S-1-5-21-...'.MATCH (n:User|Computer).[*1..3] instead of [*1..].If a query answers a recurring question, persist it via create_saved_query so the rest of the team (and future agents) can reuse it. Use a clear name and one-paragraph description — saved queries get accumulated, not curated.
For one-off investigations, the digest from run_cypher is sufficient. For recurring patterns, the output is the persisted saved query plus a one-paragraph explanation of what the query answers and when to reach for it.
list_saved_queries per session.MATCH (n) RETURN n — even with the default LIMIT, it returns nodes the agent can't act on.WHERE n.objectid = $oid) when you can; we just don't have a parameter-binding tool yet.allow_writes=True for read queries. The flag is auditable; misuse muddies the audit trail.npx claudepluginhub s3cr1z/capabilities --plugin bloodhound-enterpriseProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.