Back to Articles

Building an AI Security Researcher: How h1-brain Turns Claude into a Bug Bounty Hunter

[ View on GitHub ]

Building an AI Security Researcher: How h1-brain Turns Claude into a Bug Bounty Hunter

Hook

What if your AI assistant could analyze 3,600 real vulnerability disclosures, correlate them with your past findings, and generate a personalized attack plan—all before you even open Burp Suite?

Context

Bug bounty hunting is a game of pattern recognition and information synthesis. Before you probe a target, you need to know what's in scope, which assets haven't been picked over, what vulnerabilities similar programs have suffered, and which attack vectors previously paid out. This requires bouncing between HackerOne's web interface, your personal notes, GitHub reconnaissance tools, and public disclosure feeds—a cognitively expensive context-switching loop that happens before any actual security testing begins.

The Model Context Protocol (MCP), introduced by Anthropic, provides a standardized way to connect AI assistants to external data sources and tools. While most MCP servers expose generic capabilities like file systems or databases, h1-brain takes a domain-specific approach: it transforms Claude into a security research assistant that understands the bug bounty ecosystem. By maintaining dual databases of personal reconnaissance history and community intelligence, then exposing synthesis functions through MCP tools, it collapses the pre-hunting research phase into a single conversational interface.

Technical Insight

The architecture centers on two SQLite databases with distinct purposes. The h1_data.db database stores your personal HackerOne activity—rewarded reports, program scopes, and asset inventories—populated through the platform's GraphQL API. The disclosed_reports.db ships pre-loaded with 3,600+ community-disclosed reports including titles, descriptions, weakness types, severity ratings, and bounty amounts. This separation allows private analysis of your own attack patterns while enabling pattern matching against the broader vulnerability corpus.

The MCP server exposes these databases through tools defined in the protocol's schema. For example, the search_disclosed_reports tool provides structured querying:

@server.call_tool()
async def search_disclosed_reports(
    weakness: str | None = None,
    min_bounty: int | None = None,
    severity: str | None = None,
    limit: int = 10
) -> list[dict]:
    query = "SELECT * FROM disclosed_reports WHERE 1=1"
    params = []
    
    if weakness:
        query += " AND weakness LIKE ?"
        params.append(f"%{weakness}%")
    if min_bounty:
        query += " AND bounty >= ?"
        params.append(min_bounty)
    if severity:
        query += " AND severity = ?"
        params.append(severity)
    
    query += " ORDER BY bounty DESC LIMIT ?"
    params.append(limit)
    
    results = await db.execute(query, params)
    return [dict(row) for row in results]

When Claude invokes this tool, it receives structured data that includes not just vulnerability types but also the bounty economics—critical context for prioritizing research time. A researcher can ask "Show me SQL injection bugs that paid over $5,000" and receive actual disclosure reports with write-ups, teaching the AI what successful findings look like.

The hack() function represents the system's synthesis capability. Rather than exposing raw database access, it performs multi-source correlation in a single invocation:

async def hack(program_handle: str) -> str:
    # Fetch fresh scope data from HackerOne API
    scope_data = await fetch_program_scope(program_handle)
    
    # Query personal report history for this program
    personal_reports = await db.execute(
        "SELECT * FROM rewarded_reports WHERE program_handle = ?",
        [program_handle]
    )
    
    # Find untested assets by comparing scope to past targets
    tested_assets = {r['asset'] for r in personal_reports}
    untested = [s for s in scope_data if s['asset'] not in tested_assets]
    
    # Retrieve similar program vulnerabilities from public disclosures
    program_type = scope_data.get('program_type', 'web')
    similar_vulns = await search_disclosed_reports(
        program_type=program_type,
        limit=20
    )
    
    # Analyze weakness patterns across your successful reports
    weakness_stats = await db.execute(
        "SELECT weakness, COUNT(*) as count, AVG(bounty) as avg_bounty "
        "FROM rewarded_reports WHERE program_handle = ? "
        "GROUP BY weakness ORDER BY count DESC",
        [program_handle]
    )
    
    # Generate structured briefing
    briefing = f"""ATTACK BRIEFING: {program_handle}
    
    FRESH SCOPE ({len(scope_data)} assets):
    {format_scope(scope_data)}
    
    UNTESTED ASSETS ({len(untested)}):
    {format_assets(untested)}
    
    YOUR SUCCESSFUL PATTERNS:
    {format_weakness_stats(weakness_stats)}
    
    SIMILAR PROGRAM VULNERABILITIES:
    {format_public_disclosures(similar_vulns)}
    
    INSTRUCTIONS: You are now in offensive security mode. Analyze the untested
    assets for the weakness patterns that have historically succeeded. Prioritize
    vulnerability classes that appear in similar program disclosures with high
    bounty amounts. Generate specific test cases.
    """
    
    return briefing

This function eliminates manual reconnaissance correlation. Instead of separately checking what's in scope, reviewing your notes, searching public disclosures, and then mentally synthesizing a test plan, you ask Claude to "hack example-corp" and receive a pre-analyzed briefing that includes explicit agent instructions. The AI shifts from general assistant mode into security researcher mode with full context already loaded.

The MCP integration happens through a simple server declaration that Claude Desktop or Claude Code can discover:

from mcp.server import Server
from mcp.server.stdio import stdio_server

server = Server("h1-brain")

# Tool registrations
@server.list_tools()
async def list_tools() -> list[dict]:
    return [
        {
            "name": "hack",
            "description": "Generate comprehensive attack briefing for a program",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "program_handle": {"type": "string"}
                },
                "required": ["program_handle"]
            }
        },
        # Additional tools...
    ]

if __name__ == "__main__":
    asyncio.run(stdio_server(server))

Once configured in Claude's MCP settings, these tools appear as callable functions during conversation. The AI can autonomously decide when to fetch data, search disclosures, or generate briefings based on conversational context—no manual CLI invocations required.

Gotcha

The HackerOne platform lock-in is fundamental to the architecture. All API integrations, data schemas, and synthesis logic assume HackerOne's GraphQL API and disclosure format. If you split time between Bugcrowd, Intigriti, and HackerOne, you'll need separate tools for each platform—h1-brain won't help with 66% of your work. This isn't easily extensible either; the schema differences between platforms would require significant refactoring beyond simple API endpoint swaps.

The synchronization model requires manual intervention. After completing new reconnaissance or earning new bounties, you must explicitly call fetch_rewarded_reports() and fetch_programs() to update the local database. There's no webhook listener or automatic polling, which means the AI's context can drift from reality if you forget to sync. The disclosed reports database has it worse—it's a static SQLite file shipped with the repository. As new public disclosures appear on HackerOne, your local corpus becomes stale unless the maintainer publishes updates and you pull the latest version. This means you might miss recent vulnerability trends that could inform your testing strategy.

Verdict

Use if: you're an active HackerOne researcher with multiple programs in rotation who uses Claude Desktop or Claude Code and finds yourself manually correlating the same data sources before each session—program scopes, your past findings, untested assets, and public disclosures. The hack() briefing alone will save 20-30 minutes of reconnaissance prep per target. Also use if you want to train Claude on real vulnerability patterns from 3,600+ disclosures rather than generic security knowledge. Skip if: you work primarily on Bugcrowd, Intigriti, or private programs not listed on HackerOne, since the platform integration won't help. Skip if you prefer manual control over your reconnaissance workflow or don't use MCP-compatible AI assistants. Also skip if you're learning bug bounties—this amplifies existing pattern recognition skills rather than teaching security fundamentals. The tool assumes you already know what to do with a briefing that says "focus on IDOR in API endpoints based on your historical success rate."

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/patrikfehrenbach-h1-brain.svg)](https://starlog.is/api/badge-click/cybersecurity/patrikfehrenbach-h1-brain)