# Building a Threat Intelligence Enrichment Agent with Multi-Source IOC Querying Using Claude

> Build a threat intelligence enrichment agent querying multiple sources with Claude. Automate IOC analysis and enhance your security posture. Learn how to leverage Claude's tool-use for advanced threat hunting.

- Repository: [Anthropic/claude-cookbooks](https://github.com/anthropics/claude-cookbooks)
- Tags: how-to-guide
- Published: 2026-04-14

---

**This guide demonstrates how to build an autonomous threat intelligence enrichment agent that leverages Claude's tool-use capabilities to automatically query multiple intelligence sources and analyze Indicators of Compromise (IOCs).**

The `anthropics/claude-cookbooks` repository provides a complete implementation in `tool_use/threat_intel_enrichment_agent.ipynb` that transforms Claude into a security analyst capable of ingesting arbitrary IOCs and enriching them through simulated intelligence databases. This approach allows you to automate the correlation of IP addresses, file hashes, and domains with threat intelligence feeds without writing complex orchestration logic.

## Architecture of the Threat Intelligence Enrichment Agent

The enrichment agent follows a modular, tool-based architecture that separates schema definitions, backend implementations, and orchestration logic into distinct layers.

### Tool Schema Definition

At the core of the system is a `tools` list that describes each available intelligence source using JSON Schema. Each entry contains `name`, `description`, and `input_schema` properties that tell Claude exactly what arguments each tool expects and when to use it.

```python
tools = [
    {
        "name": "lookup_ip_reputation",
        "description": "Query IP reputation database for threat intelligence",
        "input_schema": {
            "type": "object",
            "properties": {"ip_address": {"type": "string"}},
            "required": ["ip_address"],
        },
    },
    {
        "name": "lookup_file_hash",
        "description": "Query file hash against malware databases",
        "input_schema": {
            "type": "object",
            "properties": {
                "file_hash": {"type": "string"},
                "hash_type": {"type": "string"}
            },
            "required": ["file_hash", "hash_type"],
        },
    },
    {
        "name": "lookup_domain",
        "description": "Query domain reputation and categorization",
        "input_schema": {
            "type": "object",
            "properties": {"domain": {"type": "string"}},
            "required": ["domain"],
        },
    },
    {
        "name": "get_mitre_techniques",
        "description": "Retrieve MITRE ATT&CK techniques related to threat actors",
        "input_schema": {
            "type": "object",
            "properties": {"query": {"type": "string"}},
            "required": ["query"],
        },
    },
]

```

### Simulated Backend Functions

The agent uses pure-Python stubs to simulate real intelligence APIs. In production, these would wrap actual services like VirusTotal or AbuseIPDB. The `lookup_ip_reputation` function in `tool_use/threat_intel_enrichment_agent.ipynb` demonstrates this pattern:

```python
def lookup_ip_reputation(ip_address: str) -> dict:
    """Return a fabricated IP reputation record."""
    ip_database = {
        "203.0.113.42": {
            "ip": "203.0.113.42",
            "country": "Russia",
            "abuse_confidence_score": 87,
            "threat_types": ["botnet_c2", "malware_distribution"],
            "last_reported": "2024-01-15",
            "isp": "Example ISP"
        },
    }
    return ip_database.get(
        ip_address,
        {
            "ip": ip_address, 
            "country": "Unknown", 
            "abuse_confidence_score": 0, 
            "threat_types": []
        },
    )

```

### Agent Loop and Orchestration

The `run_threat_intel_agent` function implements the main control flow that manages the conversation between Claude and the backend tools. It uses a `SYSTEM_PROMPT` to establish Claude's persona as a senior security analyst and sets `MAX_TURNS` to cap tool-use cycles and prevent runaway costs.

The loop repeatedly calls `client.messages.create` with the `tools` parameter attached. Claude responds with either:

- **`stop_reason == "end_turn"`** – The analysis is complete, and the final text is returned.
- **`stop_reason == "tool_use"`** – The response contains `tool_use` blocks requiring execution.

When tool use is requested, the loop extracts each block, executes the corresponding function, and feeds the JSON result back to Claude as a `tool_result` message.

### Tool-Call Routing

The `process_tool_call` function acts as a router that maps tool names to their implementation handlers. This design makes adding new intelligence sources straightforward—simply extend the `handlers` dictionary with a new lambda:

```python
def process_tool_call(tool_name: str, tool_input: dict) -> str:
    handlers = {
        "lookup_ip_reputation": lambda inp: lookup_ip_reputation(inp["ip_address"]),
        "lookup_file_hash": lambda inp: lookup_file_hash(inp["file_hash"], inp["hash_type"]),
        "lookup_domain": lambda inp: lookup_domain(inp["domain"]),
        "get_mitre_techniques": lambda inp: get_mitre_techniques(inp["query"]),
    }
    handler = handlers.get(tool_name)
    if handler is None:
        return json.dumps({"error": f"Unknown tool: {tool_name}"})
    return json.dumps(handler(tool_input), indent=2)

```

## Implementing the Multi-Source Query Workflow

To build your own threat intelligence enrichment agent with multi-source IOC querying, you instantiate the tools list, define your backend handlers, and invoke the agent loop. The notebook in `anthropics/claude-cookbooks` provides the complete reference implementation.

The `SYSTEM_PROMPT` explicitly instructs Claude to "identify the IOC type and query the most relevant source first," which enables automatic tool selection without hardcoded routing logic. This means Claude intelligently chooses between IP reputation lookups, hash analysis, domain checks, and MITRE ATT&CK mapping based on the input context.

## Running the Enrichment Agent

Execute the agent by calling `run_threat_intel_agent` with an IOC and its type. The function returns both the analysis text and a complete trace of tool calls for audit purposes.

```python
analysis, calls = run_threat_intel_agent(
    ioc="203.0.113.42",
    ioc_type="ip_address",
)

print("=== ANALYSIS ====================================================")
print(analysis)
print("\n=== TOOL CALL TRACE =============================================")
for c in calls:
    print(f"- {c['tool']}({c['input']})")

```

The output includes a structured threat assessment report with confidence scores, geolocation data, associated threat actors, and MITRE ATT&CK technique mappings—providing actionable intelligence for security teams.

## Summary

- **Claude's tool-use API** enables building autonomous enrichment agents that automatically select and query multiple threat intelligence sources based on IOC type.
- **The architecture** in `tool_use/threat_intel_enrichment_agent.ipynb` separates concerns between schema definitions (`tools`), backend implementations (`lookup_ip_reputation` and related stubs), and orchestration logic (`run_threat_intel_agent`).
- **The agent loop** handles multi-turn conversations, automatically routing tool calls through `process_tool_call` and aggregating results into comprehensive security reports.
- **Extensibility** is built-in—adding new intelligence sources requires only adding a tool schema and corresponding handler function.
- **Safety controls** like `MAX_TURNS` prevent excessive API calls while the system prompt establishes clear analytical reasoning patterns.

## Frequently Asked Questions

### How does the agent decide which intelligence sources to query?

The agent relies on the system prompt and tool descriptions to make autonomous decisions. By instructing Claude to "identify the IOC type and query the most relevant source first" within the `SYSTEM_PROMPT`, Claude analyzes the input context and selects the appropriate tools from the available schemas. For composite investigations, Claude may chain multiple tool calls in sequence, using results from one query to inform subsequent lookups.

### Can I replace the simulated backends with real threat intelligence APIs?

Yes. The `lookup_ip_reputation`, `lookup_file_hash`, `lookup_domain`, and `get_mitre_techniques` functions are designed as swappable stubs. Simply replace the dictionary-based return values with actual API calls to services like VirusTotal, AbuseIPDB, or your internal threat intelligence platform. Ensure your replacement functions return JSON-serializable dictionaries to maintain compatibility with the `process_tool_call` router.

### What prevents the agent from making excessive API calls in an infinite loop?

The implementation includes a `MAX_TURNS` constant that caps the number of tool-use cycles allowed per IOC analysis. Once the agent reaches this limit, the loop terminates regardless of whether the investigation is complete. Additionally, Claude's `stop_reason` mechanism naturally concludes the workflow when the model determines sufficient information has been gathered to render a final analysis.

### Where can I find the complete source code for this implementation?

The full implementation resides in the `anthropics/claude-cookbooks` repository at `tool_use/threat_intel_enrichment_agent.ipynb`. This Jupyter notebook contains the complete tool schemas, simulated backend functions, agent loop implementation, and example runs. The repository also includes [`CLAUDE.md`](https://github.com/anthropics/claude-cookbooks/blob/main/CLAUDE.md) for setup instructions regarding Anthropic SDK installation and API key configuration via environment variables.