# What Are Context Providers in ADR? How They Power Threat Intelligence

> Discover context providers in ADR: lightweight servers that fuel threat intelligence by separating data from logic, enabling dynamic ATT&CK framework queries for better detection.

- Repository: [Uber Open Source/ADR](https://github.com/uber/ADR)
- Tags: deep-dive
- Published: 2026-08-06

---

**Context providers in ADR are lightweight MCP (Micro-Component Platform) servers that expose curated threat knowledge through callable tools, separating intelligence data from detection logic so detectors can query up-to-date ATT&CK-like frameworks without hard-coded dependencies.**

The ADR (Automated Detection and Response) system from Uber uses a modular architecture where threat intelligence lives in dedicated services rather than embedded in detector code. This article explains how context providers work, how the threat-intelligence provider specifically operates, and why this design enables faster, more maintainable security detection.

## How Context Providers Work in ADR

A **context provider** is a standalone MCP server that registers a set of **tools**—Python functions exposed to the ADR reasoning engine. Each provider runs in its own process and communicates via the FastMCP protocol, allowing detectors to invoke remote procedures as if they were local functions.

The architecture follows three principles:
- **Separation of concerns**: Knowledge about the environment (threats, policies, code structure) lives outside detectors
- **Runtime discoverability**: The orchestrator reads a central registry to find and launch providers
- **Composability**: Multiple providers combine to enrich analysis with multi-domain context

## The Threat-Intelligence Context Provider

The `threat_intelligence_server` ([`Detection/context_providers/threat_intelligence_server.py`](https://github.com/uber/ADR/blob/main/Detection/context_providers/threat_intelligence_server.py)) is the primary vehicle for bringing structured threat intelligence into ADR. It loads a YAML-encoded threat repository from [`Detection/context_providers/data/threat_repository.yaml`](https://github.com/uber/ADR/blob/main/Detection/context_providers/data/threat_repository.yaml) and registers three core tools:

| Tool | Purpose |
|------|---------|
| `get_threat_framework` | Returns the complete tactics-and-techniques structure |
| `search_techniques` | Queries techniques by keywords or patterns |
| `get_technique_details` | Retrieves full metadata for a specific technique ID |

Because these tools run server-side, the threat repository can be updated—new techniques, refreshed MITRE mappings, custom organizational threats—without restarting detectors.

## Registry and Lifecycle Management

The [`Detection/context_providers_registry.json`](https://github.com/uber/ADR/blob/main/Detection/context_providers_registry.json) file governs how ADR discovers and launches providers. Each entry specifies:

```json
{
  "servers": {
    "threat_intelligence_server": {
      "category": "threat_intelligence",
      "description": "Provides ATT&CK-like threat framework data",
      "command": "uv run python -m Detection.context_providers.threat_intelligence_server",
      "args_template": ["uv", "run", "python", "-m", "Detection.context_providers.threat_intelligence_server"],
      "capabilities": ["get_threat_framework", "search_techniques", "get_technique_details"]
    }
  }
}

```

At startup, the ADR orchestrator reads this registry, spawns each server as a subprocess, and constructs a unified toolbox that detectors access through the FastMCP client.

## Querying Threat Intelligence from Detectors

Detectors interact with context providers through the `FastMCP` client. The base detector class ([`Detection/guardrail/base_detector.py`](https://github.com/uber/ADR/blob/main/Detection/guardrail/base_detector.py)) handles connection management, so individual detectors only need to call the tool they need.

### Retrieve the Full Threat Framework

```python
from mcp.client.fastmcp import FastMCP

# Connect to the running threat-intelligence server

mcp = FastMCP("threat_intelligence_server")

# Fetch complete framework and list available tactics

framework = mcp.get_threat_framework()
print(framework["available_tactics"])

```

This returns the structured YAML content as a Python dictionary, including tactics like **initial-access**, **execution**, **persistence**, and their associated techniques.

### Search for Specific Techniques

```python
from mcp.client.fastmcp import FastMCP

mcp = FastMCP("threat_intelligence_server")
result = mcp.search_techniques(keywords=["credential"])

for tech in result["matching_techniques"]:
    print(f"{tech['tactic']}: {tech['name']} – {tech['description']}")

```

The `search_techniques` tool performs substring matching across technique names, descriptions, and metadata tags, returning ranked results for detector logic to consume.

### Launch a Provider Programmatically

For testing or custom orchestration, you can replicate ADR's startup behavior:

```python
import json
import subprocess
import pathlib

registry_path = pathlib.Path(__file__).parent / "Detection/context_providers_registry.json"
with open(registry_path) as f:
    registry = json.load(f)

ti_conf = registry["servers"]["threat_intelligence_server"]
cmd = ["uv", "run", "python"] + ti_conf["args_template"][2:]
subprocess.Popen(cmd)  # Background server process

```

This extracts the launch command from the registry and spawns the provider with the same arguments ADR uses in production.

## Integration with Multi-Provider Pipelines

The real power of context providers emerges when detectors combine multiple intelligence sources. The [`llamafirewall_baseline.py`](https://github.com/uber/ADR/blob/main/llamafirewall_baseline.py) detector ([`Detection/guardrail/llamafirewall_agent/llamafirewall_baseline.py`](https://github.com/uber/ADR/blob/main/Detection/guardrail/llamafirewall_agent/llamafirewall_baseline.py)) demonstrates this pattern: it queries not only the threat-intelligence provider but also policy-store and source-code-analyzer providers to build a comprehensive assessment.

A detector might execute this flow:
1. Receive an alert or log entry
2. Call `search_techniques` to identify relevant ATT&CK patterns
3. Query the policy store for organizational constraints
4. Invoke the source-code analyzer if the alert involves custom applications
5. Synthesize all context into a final decision

## Why Context Providers Matter for Threat Intelligence

The threat-intelligence context provider contributes to ADR's effectiveness in four concrete ways:

- **Encapsulation**: Curated threat data lives in a dedicated, versionable service rather than scattered across detector implementations
- **Queryability**: Fine-grained tools like `search_techniques` let detectors retrieve exactly the context they need, when they need it
- **Decoupled updates**: Security analysts can refresh the [`threat_repository.yaml`](https://github.com/uber/ADR/blob/main/threat_repository.yaml) and restart only the provider, with zero detector downtime
- **Composability**: Threat intelligence blends with other domains (policy, code, infrastructure) to create richer detection narratives

## Summary

- **Context providers** are MCP servers that expose environment knowledge through callable tools, implementing separation between data and detection logic in ADR
- The **threat-intelligence provider** ([`threat_intelligence_server.py`](https://github.com/uber/ADR/blob/main/threat_intelligence_server.py)) loads YAML threat frameworks and registers `get_threat_framework`, `search_techniques`, and `get_technique_details` tools
- **Registry-driven discovery** via [`context_providers_registry.json`](https://github.com/uber/ADR/blob/main/context_providers_registry.json) lets ADR dynamically launch and wire providers without hard-coded configuration
- **FastMCP client calls** from detectors enable real-time threat lookups during analysis pipelines
- **Multi-provider composition** allows threat intelligence to combine with policy and code analysis for holistic security decisions

## Frequently Asked Questions

### What protocol do ADR context providers use?

ADR context providers implement the **MCP (Micro-Component Platform)** protocol via the `FastMCP` library. This provides standardized request routing, tool registration, and cross-process communication between detectors and providers.

### Can I add custom threat intelligence to the threat-intelligence provider?

Yes. The provider reads from [`Detection/context_providers/data/threat_repository.yaml`](https://github.com/uber/ADR/blob/main/Detection/context_providers/data/threat_repository.yaml), which follows a structured format compatible with ATT&CK-style frameworks. Adding organizational-specific techniques, custom tactic categories, or supplemental metadata requires only editing this YAML file and restarting the provider process—no detector changes needed.

### How does ADR handle provider failures or restarts?

The registry architecture and subprocess-based spawning mean ADR can monitor provider health and restart individual servers independently. Detectors using the FastMCP client receive connection errors that can trigger fallback logic or queue retries, maintaining pipeline resilience without full system restarts.

### What other context providers exist besides threat intelligence?

According to the registry and codebase, ADR includes or supports providers for **policy stores** (organizational security policies), **source-code analyzers** (repository and application context), and extensible categories for infrastructure or telemetry data. Each follows the same MCP server pattern with tool-based interfaces.