# Law Enforcement Intelligence MCP Server (`ryanclinton/law-enforcement-intelligence-mcp`) Actor

Comprehensive threat intelligence and law enforcement screening powered by 7 specialized Apify actors. This MCP server builds threat network graphs with fuzzy name matching across Interpol Red Notices, FBI Most Wanted, OFAC sanctions, and OpenSanctions databases.

- **URL**: https://apify.com/ryanclinton/law-enforcement-intelligence-mcp.md
- **Developed by:** [ryan clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Law Enforcement Intelligence MCP Server

Law enforcement intelligence screening for AI agents — query Interpol, FBI, OFAC, and OpenSanctions in a single MCP tool call. This server connects Claude Desktop, Cursor, Windsurf, and any MCP-compatible client to 7 live government and public databases, delivering threat scores, identity clearance verdicts, sanctions cross-references, and threat network graphs with no subscriptions beyond Apify.

Compliance teams spend hours manually checking names across Interpol Red Notices, the FBI Most Wanted list, the OFAC SDN list, and OpenSanctions. This MCP server automates the entire pipeline: all 7 sources are queried in parallel, a Levenshtein-based fuzzy matching algorithm reconciles name variants across databases, and results are returned as structured JSON your AI agent can reason over directly.

### What data can you extract?

| Data Point | Source | Example |
|------------|--------|---------|
| 📋 International arrest warrants | Interpol Red Notices | Warrant ID, charges, requesting country, physical description |
| 👤 US federal wanted persons | FBI Most Wanted | Name, caution text, subjects, field office, image URL |
| 🚫 US Treasury SDN entries | OFAC SDN List | Entity name, program (e.g. UKRAINE-EO13685), aliases, country |
| 🌐 Multi-jurisdiction watchlist entries | OpenSanctions | 40+ consolidated lists, PEP registries, topics, datasets |
| 🔴 Crime records by category | UK Police API | Category, street, month, outcome status |
| 📍 Crime hotspot coordinates | UK Police API | Latitude, longitude, incident count, dominant category |
| 📰 OSINT context articles | Wikipedia | Article title, excerpt, URL for entity enrichment |
| 🗺️ Geocoded location data | Nominatim (OpenStreetMap) | Coordinates, place type, display name |
| ⚠️ Clearance verdict | Computed | CLEAR / FLAGGED / WATCHLISTED / BLOCKED |
| 🎯 Composite threat score | Computed | 0-100 score across four weighted dimensions |
| 🕸️ Threat network graph | Computed | Typed nodes and edges with confidence scores and evidence |
| 📑 Structured threat brief | Computed | Executive summary, findings, recommendations, caveats |

### Why use Law Enforcement Intelligence MCP Server?

Manually screening one name takes 15-30 minutes: open Interpol's Notice search, run the FBI wanted portal, export from the OFAC SDN list, check OpenSanctions, reconcile spelling variants, document your findings. For a batch of 20 counterparties before a deal close, that is a full working day — and still leaves gaps when a name appears in one database but not another.

This MCP server automates the entire process and brings it into your AI workflow. Your agent calls one tool, all 7 sources are queried simultaneously, and fuzzy name matching identifies the same entity under variant spellings across databases.

- **AI-native integration** — runs inside Claude Desktop, Cursor, Windsurf, or any MCP client without API wrappers
- **Parallel execution** — up to 7 actor calls run simultaneously, not sequentially
- **Fuzzy name matching** — Jaccard token overlap plus substring containment catches transliterated names and aliases
- **Configurable thresholds** — set fuzzy match sensitivity from 0.1 (broad) to 1.0 (exact) per request
- **Structured JSON output** — every response is machine-readable and ready for downstream reasoning or CRM logging
- **Spending limits** — per-event pricing with hard stop when your budget is reached

### Features

- **Threat network graph building** — constructs a directed graph of nodes (suspects, warrants, crimes, sanctions, locations, articles) and edges (wanted_for, sanctioned_as, crime_at, located_in, described_in, associated_with) from up to 7 parallel sources
- **Levenshtein-based fuzzy matching** — Jaccard token overlap scoring combined with substring containment bonus (0.3); configurable threshold from 0.1 to 1.0
- **Cross-database sanctions reconciliation** — matches OFAC SDN entries against OpenSanctions; entities appearing in both with high fuzzy scores are flagged as very likely true positives
- **4-factor threat scoring model** — wanted status (0-25), sanctions presence (0-25), crime proximity (0-25), and information density (0-25) for a maximum composite of 100
- **5-tier clearance classification** — CLEAR, FLAGGED, WATCHLISTED, BLOCKED with machine-readable recommendation text and match type (exact/fuzzy/partial)
- **5-level threat categorization** — LOW, GUARDED, ELEVATED, HIGH, CRITICAL mapped to score ranges
- **Composite geographic risk scoring** — UK crime density (30%), OFAC sanctions hits (40%), and Interpol/FBI wanted presence (30%) producing a composite score from MINIMAL to CRITICAL
- **Crime hotspot detection** — aggregates street-level crime records into a top-10 hotspot heatmap by coordinate cluster with dominant category per cluster
- **Automatic geocoding** — Nominatim resolves location names to coordinates before crime queries when coordinates are not provided
- **Structured threat brief generation** — executive summary, per-category findings with CRITICAL/HIGH/MEDIUM/LOW/INFO severity, network statistics, prioritized recommendations, and 5 standard legal caveats
- **Full standby mode operation** — persistent MCP endpoint, no cold-start latency on tool calls
- **8 registered MCP tools** across entity screening, geographic analysis, and intelligence reporting

### Use cases for law enforcement intelligence screening

#### KYC and AML compliance screening

Compliance teams at fintechs, banks, and trading firms screen customers and counterparties against sanctions and wanted persons databases before onboarding. The `verify_identity_clearance` tool checks all four databases in a single call and returns a categorical verdict — CLEAR, FLAGGED, WATCHLISTED, or BLOCKED — with match details and a plain-language recommendation. Configurable fuzzy thresholds let you tune sensitivity to your risk tolerance.

#### Corporate due diligence and vendor screening

Deal teams and procurement functions verify directors, beneficial owners, and vendors as part of M&A due diligence or supplier qualification. The `score_threat_level` tool produces a 0-100 composite score with a dimensional breakdown, making it easy to rank a list of entities by risk, prioritize manual review, and document findings in a compliance file.

#### Travel risk and site security assessment

Corporate security teams and duty-of-care platforms assess destination risk before executive travel or facility deployment. The `assess_geographic_risk` tool geocodes the target location, pulls UK crime density data, and cross-references local sanctions and wanted person presence to produce a composite risk score (MINIMAL to CRITICAL) with a human-readable factors list.

#### AI agent investigation workflows

Security researchers and analysts building AI investigation pipelines use `map_threat_intelligence` to construct a threat network graph for any entity. The graph — with typed nodes, weighted edges, and confidence scores — can be passed to an LLM for reasoning, exported to a graph database, or used as the foundation for further automated investigation steps.

#### Formal compliance documentation

Risk officers generating investigation records for regulatory audit use `generate_threat_brief` to produce a structured document with an executive summary, per-category findings, network statistics, data source attribution, actionable recommendations, and built-in legal caveats. The output maps directly to standard EDD documentation formats.

#### Area crime pattern analysis

Security consultants and real estate analysts assessing England and Wales locations use `analyze_crime_patterns` to retrieve street-level crime data, aggregate it by category and month, score crime density, and identify the top-10 hotspot coordinates. The temporal breakdown reveals seasonal trends and the outcome statistics show prosecution rates.

### How to use law enforcement intelligence tools in your AI agent

1. **Connect the MCP server** — Add the endpoint URL to your MCP client config (see code examples below). Your Apify token is the only credential needed.
2. **Select your tool** — Use `verify_identity_clearance` for a quick watchlist check, `score_threat_level` for a risk score, `map_threat_intelligence` for a full network graph, or `generate_threat_brief` for a formal report.
3. **Provide the entity name or location** — Enter the person or organization name you want to screen, or a location for geographic risk. Adjust optional source toggles and the fuzzy threshold if needed.
4. **Read the structured result** — Each tool returns JSON with a clearance level or threat score, matched records from each source, and a recommendation the AI agent can reason over directly.

### Input parameters

#### Tool summary

| Tool | Price | Best for |
|------|-------|----------|
| `map_threat_intelligence` | $0.075 | Full network graph across all 7 sources |
| `search_wanted_persons` | $0.075 | Interpol + FBI lookup for a specific name |
| `cross_reference_sanctions` | $0.075 | OFAC vs. OpenSanctions fuzzy cross-match |
| `analyze_crime_patterns` | $0.075 | UK crime data aggregation and hotspot detection |
| `assess_geographic_risk` | $0.075 | Composite risk score for a location |
| `verify_identity_clearance` | $0.075 | Clearance verdict: CLEAR/FLAGGED/WATCHLISTED/BLOCKED |
| `score_threat_level` | $0.075 | 0-100 threat score across four weighted dimensions |
| `generate_threat_brief` | $0.075 | Full structured intelligence report |

#### Key parameters across all tools

| Parameter | Tool(s) | Type | Default | Description |
|-----------|---------|------|---------|-------------|
| `query` / `entity` | all | string | required | Person, organization, or topic to investigate |
| `fuzzy_threshold` | `verify_identity_clearance` | number | `0.6` | Match sensitivity: 0.1=broad, 1.0=exact |
| `search_interpol` | `map_threat_intelligence`, `search_wanted_persons` | boolean | `true` | Include Interpol Red Notices |
| `search_fbi` | `map_threat_intelligence`, `search_wanted_persons` | boolean | `true` | Include FBI Most Wanted |
| `search_ofac` | multiple | boolean | `true` | Include OFAC SDN list |
| `search_open_sanctions` | multiple | boolean | `true` | Include OpenSanctions |
| `search_uk_crime` | `map_threat_intelligence` | boolean | `false` | Include UK Police crime data |
| `location` | `analyze_crime_patterns`, `assess_geographic_risk`, `generate_threat_brief` | string | — | Place name for geographic queries |
| `latitude` / `longitude` | multiple | number | — | Coordinates for precise geographic queries |
| `max_results` | all | number | `25` | Max results per source (1-100, or 1-500 for crime analysis) |

#### Input tips

- **Prefer full legal names** — fuzzy matching catches variants, but a full name outperforms initials for reducing false positives.
- **Lower the threshold for transliterated names** — names from Arabic, Cyrillic, or Chinese may have multiple romanizations; use `fuzzy_threshold` 0.4-0.5.
- **Disable unused sources** — if you only need sanctions screening, set `search_interpol: false` and `search_fbi: false` to cut cost and latency.
- **UK crime data requires UK coordinates** — enable `search_uk_crime` only for England and Wales subjects; it will fail silently for other jurisdictions.

### Output example

```json
{
  "clearance": {
    "entity": "Viktor Petrov",
    "checkedAt": "2025-11-14T09:22:31.007Z",
    "clearanceLevel": "BLOCKED",
    "watchlistHits": [
      {
        "source": "interpol",
        "matchType": "exact",
        "matchScore": 97,
        "details": "Viktor Petrov — Money laundering, fraud, theft of public funds across 3 jurisdictions"
      }
    ],
    "sanctionHits": [
      {
        "source": "ofac",
        "program": "UKRAINE-EO13685",
        "matchScore": 94,
        "details": "Viktor Petrov — Designated for activities destabilizing Ukraine's sovereignty"
      },
      {
        "source": "openSanctions",
        "program": "EU Financial Sanctions",
        "matchScore": 89,
        "details": "Viktor Petrov — EU Council Regulation (EU) 269/2014 designation"
      }
    ],
    "totalHits": 3,
    "recommendation": "EXACT MATCH FOUND. Entity 'Viktor Petrov' has high-confidence matches across watchlists/sanctions. Do NOT proceed without legal review and enhanced due diligence."
  }
}
````

**`score_threat_level` — HIGH result:**

```json
{
  "threatScore": {
    "entity": "Meridian Capital Holdings",
    "overallScore": 62,
    "threatLevel": "HIGH",
    "factors": {
      "wantedScore": 0,
      "sanctionsScore": 22,
      "crimeProximity": 0,
      "informationDensity": 40
    },
    "breakdown": ["4 OFAC sanctions match(es)", "2 OpenSanctions match(es)", "3 Wikipedia article(s) found"],
    "dataSources": ["ofac", "openSanctions", "wikipedia"],
    "confidence": 0.6
  }
}
```

**`assess_geographic_risk` — MEDIUM result:**

```json
{
  "assessment": {
    "location": "Beirut, Lebanon",
    "latitude": 33.8886,
    "longitude": 35.4955,
    "crimeScore": 0,
    "sanctionsScore": 45,
    "wantedScore": 30,
    "compositeRisk": 27,
    "riskLevel": "MEDIUM",
    "factors": [
      "3 OFAC sanctions matches for area",
      "3 Interpol notices linked to area"
    ]
  }
}
```

### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `clearance.clearanceLevel` | string | CLEAR, FLAGGED, WATCHLISTED, or BLOCKED |
| `clearance.watchlistHits[].matchType` | string | exact (≥95%), fuzzy (≥75%), or partial |
| `clearance.watchlistHits[].matchScore` | number | 0-100 fuzzy name similarity score |
| `clearance.recommendation` | string | Plain-language compliance recommendation |
| `threatScore.overallScore` | number | Composite 0-100 threat score |
| `threatScore.threatLevel` | string | LOW, GUARDED, ELEVATED, HIGH, or CRITICAL |
| `threatScore.factors.wantedScore` | number | Wanted status component 0-25 |
| `threatScore.factors.sanctionsScore` | number | Sanctions presence component 0-25 |
| `threatScore.factors.crimeProximity` | number | Geographic crime component 0-25 |
| `threatScore.factors.informationDensity` | number | Information volume component 0-25 |
| `threatScore.confidence` | number | 0-1 confidence based on data availability |
| `assessment.compositeRisk` | number | Weighted geographic risk score 0-100 |
| `assessment.riskLevel` | string | MINIMAL, LOW, MEDIUM, HIGH, or CRITICAL |
| `analysis.byCategory` | object | Crime count keyed by category |
| `analysis.hotspots[].count` | number | Crime incidents in coordinate cluster |
| `network.nodes[].type` | string | suspect, warrant, crime, sanction, location, or article |
| `network.edges[].type` | string | wanted\_for, sanctioned\_as, crime\_at, located\_in, described\_in, associated\_with |
| `network.edges[].weight` | number | 0-1 edge strength (fuzzy match score for cross-source edges) |
| `brief.threatLevel` | string | Overall brief threat assessment |
| `brief.findings[].severity` | string | CRITICAL, HIGH, MEDIUM, LOW, or INFO |
| `brief.recommendations` | array | Actionable compliance recommendations |
| `brief.caveats` | array | Standard legal and data limitation caveats |

### How much does it cost to run law enforcement intelligence checks?

This MCP server uses **pay-per-event pricing** — each tool call costs **$0.075**. Platform compute costs are included.

| Scenario | Tool calls | Cost per call | Total cost |
|----------|------------|---------------|------------|
| Quick test — single clearance check | 1 | $0.075 | $0.075 |
| Small batch — 10 entity screens | 10 | $0.075 | $0.75 |
| Due diligence — 50 counterparties | 50 | $0.075 | $3.75 |
| Continuous monitoring — 200 entities | 200 | $0.075 | $15.00 |
| Enterprise screening — 1,000 entities | 1,000 | $0.075 | $75.00 |

You can set a **maximum spending limit** per run to control costs. The server stops charging when your budget is reached.

Compare this to Refinitiv World-Check at $500-2,000/month or ComplyAdvantage at $600+/month — with this MCP server, most compliance teams spend $5-20/month with no subscription commitment. Apify's free tier includes $5 of monthly credits, enough for approximately 66 identity clearance checks.

### Law enforcement intelligence screening using the API

#### Python

```python
import httpx
import json

APIFY_TOKEN = "YOUR_APIFY_TOKEN"
MCP_URL = "https://law-enforcement-intelligence-mcp.apify.actor/mcp"

payload = {
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "name": "verify_identity_clearance",
        "arguments": {
            "entity": "Viktor Petrov",
            "fuzzy_threshold": 0.65,
            "max_results": 20
        }
    },
    "id": 1
}

response = httpx.post(MCP_URL, json=payload, headers={"Authorization": f"Bearer {APIFY_TOKEN}"})
result = response.json()
clearance = json.loads(result["result"]["content"][0]["text"])
print(f"Clearance level: {clearance['clearance']['clearanceLevel']}")
print(f"Total hits: {clearance['clearance']['totalHits']}")
print(f"Recommendation: {clearance['clearance']['recommendation']}")
```

#### JavaScript

```javascript
const APIFY_TOKEN = "YOUR_APIFY_TOKEN";
const MCP_URL = "https://law-enforcement-intelligence-mcp.apify.actor/mcp";

const response = await fetch(MCP_URL, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${APIFY_TOKEN}`
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    method: "tools/call",
    params: {
      name: "score_threat_level",
      arguments: {
        entity: "Meridian Capital Holdings",
        include_wikipedia: true,
        max_results: 15
      }
    },
    id: 1
  })
});

const data = await response.json();
const score = JSON.parse(data.result.content[0].text);
console.log(`Threat level: ${score.threatScore.threatLevel} (${score.threatScore.overallScore}/100)`);
console.log(`Sanctions score: ${score.threatScore.factors.sanctionsScore}/25`);
```

#### cURL

```bash
## Verify an entity against all watchlists and sanctions lists
curl -X POST "https://law-enforcement-intelligence-mcp.apify.actor/mcp" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"verify_identity_clearance","arguments":{"entity":"Harrington Global Commodities","fuzzy_threshold":0.6,"max_results":25}},"id":1}'

## Generate a full threat intelligence brief
curl -X POST "https://law-enforcement-intelligence-mcp.apify.actor/mcp" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"generate_threat_brief","arguments":{"query":"Novikov Trading Group","max_results":20}},"id":2}'
```

#### Claude Desktop configuration

```json
{
  "mcpServers": {
    "law-enforcement-intelligence": {
      "url": "https://law-enforcement-intelligence-mcp.apify.actor/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_APIFY_TOKEN"
      }
    }
  }
}
```

### How Law Enforcement Intelligence MCP Server works

#### Phase 1: Parallel data collection across 7 sources

Each tool call dispatches actor calls to the relevant sources simultaneously via `Promise.all()`. The seven actors are `ryanclinton/interpol-red-notices`, `ryanclinton/fbi-wanted-search`, `ryanclinton/ofac-sanctions-search`, `ryanclinton/opensanctions-search`, `ryanclinton/uk-police-crime-data`, `ryanclinton/wikipedia-article-search`, and `ryanclinton/nominatim-geocoder`. Each is called with a 120-second timeout and 256 MB memory. For tools with a geographic component, Nominatim geocodes the location first when coordinates are not supplied, then forwards the resolved coordinates to the UK crime actor.

#### Phase 2: Fuzzy name reconciliation across databases

Results are normalized and scored using a two-part algorithm. A Jaccard token overlap score divides the token intersection by the token union after lowercasing and stripping punctuation. A substring containment bonus of 0.3 is added if either normalized string fully contains the other, capped at 1.0. The configurable `fuzzy_threshold` (default 0.6) is the minimum score for a result to count as a match. Entities matching across OFAC and OpenSanctions above 0.5 are flagged as cross-database matches — the strongest positive signal in the system.

#### Phase 3: Graph construction and composite scoring

For network-building tools, a typed directed graph is assembled with deduplication on node ID (type + normalized label) and edge triple (source, target, type). Suspect nodes from different sources are cross-linked if their fuzzy score exceeds 0.6. The four threat score dimensions are computed independently: wanted hits × 8 per relevant match (cap 25), sanctions hits × 6 (cap 25), UK crime volume as a proportion of max results × 25 (cap 25), and total data points as a proportion of 20 × 25 (cap 25). Geographic risk uses a weighted formula: crime score × 0.3 + sanctions score × 0.4 + wanted score × 0.3.

#### Phase 4: Classification, clearance levels, and brief generation

Clearance levels are assigned by match quality: any match scoring ≥95 → BLOCKED, two or more matches scoring ≥75 → WATCHLISTED, any match above threshold → FLAGGED, zero matches → CLEAR. Threat levels map score ranges: 0-19 LOW, 20-39 GUARDED, 40-59 ELEVATED, 60-79 HIGH, 80-100 CRITICAL. The threat brief tool synthesizes all findings into a structured document with severity-ranked findings by category, machine-generated recommendations, network statistics, and five standard legal caveats covering data completeness, fuzzy matching limitations, and non-legal-advice disclaimers.

### Tips for best results

1. **Disable sources you do not need.** Each enabled source adds a parallel actor call. Sanctions-only screening can set `search_interpol: false` and `search_fbi: false` to reduce calls from 7 to 2.
2. **Tune fuzzy threshold per use case.** For high-stakes onboarding where false negatives are costly, use 0.4-0.5. For bulk screening where false positives need manual review, use 0.7-0.8.
3. **Use `score_threat_level` for ranked batch screening.** Run it per entity, sort by `overallScore` descending, then apply manual review only to entities scoring above 40.
4. **Cross-database matches are your strongest signal.** When `cross_reference_sanctions` returns entries in both OFAC and OpenSanctions with scores above 70, treat the entity as very likely genuinely sanctioned.
5. **UK crime analysis is England and Wales only.** For non-UK locations, disable `search_uk_crime` to avoid a failed actor call.
6. **Set `max_results` to 10 for fast preliminary screening.** Default 25 is thorough; 10 cuts response time by roughly half.
7. **Pass `generate_threat_brief` output directly to your LLM.** The executive summary, findings array, and recommendations field are designed for LLM consumption and map to standard EDD documentation formats.

### Combine with other Apify actors

| Actor | How to combine |
|-------|---------------|
| [Sanctions Network Analysis](https://apify.com/ryanclinton/sanctions-network-analysis) | After a BLOCKED clearance result, map the full sanctions evasion network around the entity |
| [Company Deep Research](https://apify.com/ryanclinton/company-deep-research) | Enrich a CLEAR result with corporate registry data, officer lists, and UBO chains before onboarding |
| [WHOIS Domain Lookup](https://apify.com/ryanclinton/whois-domain-lookup) | Correlate domain registration data with suspect locations or aliases found in the threat graph |
| [B2B Lead Qualifier](https://apify.com/ryanclinton/b2b-lead-qualifier) | Screen sales prospects through `verify_identity_clearance` before passing CLEAR entities to the lead scorer |
| [Waterfall Contact Enrichment](https://apify.com/ryanclinton/waterfall-contact-enrichment) | Enrich contact data for CLEAR entities before adding to CRM outreach sequences |
| [OpenSanctions Search](https://apify.com/ryanclinton/opensanctions-search) | Deep search a WATCHLISTED entity in isolation for complete dataset coverage beyond the MCP wrapper |
| [Website Change Monitor](https://apify.com/ryanclinton/website-change-monitor) | Detect changes on Interpol or OFAC pages and trigger re-screening via a scheduled actor run |

### Limitations

- **UK crime data covers England and Wales only.** The `analyze_crime_patterns` tool and crime-related scoring rely on data.police.uk, which has no coverage for Scotland, Northern Ireland, or non-UK jurisdictions.
- **All sources are public databases.** This server does not access classified, law enforcement-only, or subscription-restricted databases. Interpol Red Notices, FBI Most Wanted, OFAC SDN, and OpenSanctions are all publicly available.
- **Fuzzy matching produces false positives.** Common names (e.g. "Mohammed Ali", "John Smith") may match unrelated entries. All FLAGGED, WATCHLISTED, or BLOCKED results must be manually verified before adverse action.
- **No historical or versioned data.** All queries fetch the current live state of each database. Entities removed from a sanctions list will not appear even if they were listed yesterday.
- **Wikipedia results are context only.** Wikipedia articles are used for information density scoring, not as evidence of wrongdoing.
- **Crime proximity scoring requires a UK location.** The `crimeProximity` factor is always 0 for non-UK entities unless you provide an England or Wales `include_location` value.
- **Not a replacement for certified KYC/AML platforms.** For regulated financial institutions with mandatory AML compliance obligations, this supplements but does not replace certified screening platforms with audit-trail requirements.
- **Rate limits may produce partial results.** Very large `max_results` values on high-volume sources like OpenSanctions may hit source rate limits and return fewer results than requested.

### Integrations

- [Claude Desktop](https://claude.ai/download) — connect via the MCP URL to use all 8 tools in your Claude chat interface
- [Cursor](https://cursor.com) — add the server endpoint to use threat intelligence tools inside your IDE
- [Apify API](https://docs.apify.com/api/v2) — trigger the actor programmatically from any HTTP client
- [Webhooks](https://docs.apify.com/platform/integrations/webhooks) — fire downstream alerts when high-risk entities are detected
- [Zapier](https://apify.com/integrations/zapier) — connect clearance results to Slack, HubSpot, or Salesforce workflows
- [Make](https://apify.com/integrations/make) — build automated screening pipelines with conditional routing on clearance level
- [LangChain / LlamaIndex](https://docs.apify.com/platform/integrations) — use threat intelligence output as structured context in RAG pipelines or agent tool calls

### Troubleshooting

**No results returned despite a known high-profile entity.** Try a shorter name substring (surname only), reduce `fuzzy_threshold` to 0.4, or increase `max_results` to 50. Some entities are known by multiple name variants across databases.

**Crime pattern analysis returns an error.** The `analyze_crime_patterns` tool requires either a `location` string or both `latitude` and `longitude`. If your location is outside England and Wales, the UK Police API returns no results — disable UK crime data for non-UK subjects.

**Large number of FLAGGED results for a common name.** Increase `fuzzy_threshold` to 0.75 or higher. Consider adding additional identifiers to the query string (e.g. "John Smith UK 1980") to improve specificity.

**Spending limit reached mid-batch.** Increase your maximum spend limit in Apify account settings or process entities in smaller batches. The error response includes `"eventChargeLimitReached": true` for programmatic detection.

**Threat brief missing crime findings.** Crime data is disabled by default in `generate_threat_brief`. Set `include_crime: true` and provide a `location` within England or Wales to include crime pattern analysis.

### Responsible use

- All data sources accessed by this server are publicly available government and open-data registries.
- Results are for informational due diligence only and do not constitute legal advice, regulatory guidance, or certified compliance screening.
- All FLAGGED, WATCHLISTED, or BLOCKED verdicts must be manually verified before any adverse action is taken against an individual or entity.
- Comply with GDPR, CCPA, and all applicable data protection laws when processing personal data obtained through this service.
- Do not use this tool to harass or discriminate against individuals based on name similarity alone.
- For guidance on the legality of public data access, see [Apify's guide on web scraping legality](https://blog.apify.com/is-web-scraping-legal/).

### FAQ

**How does law enforcement intelligence screening work in this MCP server?**
Each tool call dispatches parallel queries to up to 7 public databases — Interpol, FBI, OFAC, OpenSanctions, UK Police, Wikipedia, and Nominatim. Results are normalized, fuzzy-matched across sources, and returned as structured JSON with a clearance level, threat score, or network graph depending on the tool called.

**Can I use this MCP server for AML compliance screening?**
Yes, with the caveat that this tool queries publicly available databases only. It is appropriate for informational due diligence and pre-screening. Regulated financial institutions with mandatory AML obligations should use this alongside (not instead of) certified platforms with audit trails and regulatory certifications.

**How accurate is the fuzzy name matching for transliterated names?**
The Jaccard token overlap algorithm handles romanization variants well because it matches on word tokens rather than character-level edit distance. For Arabic, Cyrillic, or Chinese names, reduce `fuzzy_threshold` to 0.4-0.5 to capture more variants. Review all matches manually for transliterated names.

**What is the difference between WATCHLISTED and BLOCKED clearance levels?**
BLOCKED means at least one match scored 95 or above — high confidence the entity is genuinely listed. WATCHLISTED means two or more matches scored 75 or above across databases — multiple fuzzy matches that together require manual review. FLAGGED means at least one match above threshold but below WATCHLISTED criteria.

**Does this MCP server access classified or restricted intelligence databases?**
No. All seven sources are public: Interpol Red Notices are publicly searchable on interpol.int, the FBI Most Wanted list is published at fbi.gov, the OFAC SDN list is a public US Treasury download, OpenSanctions is an open-data project, UK Police data is at data.police.uk, Wikipedia is public, and Nominatim uses OpenStreetMap data.

**How is this different from Refinitiv World-Check or ComplyAdvantage?**
Refinitiv World-Check and ComplyAdvantage are certified AML platforms with proprietary coverage, audit trails, and regulatory certifications at $500-2,000+/month. This MCP server targets developers and compliance teams embedding threat intelligence into AI agent workflows, using only public data, at $0.075 per query with no subscription.

**How many entities can I screen in one session?**
There is no hard session limit. Each tool call is independently priced at $0.075. You can set a maximum spending limit to cap total cost. Screening 100 entities costs $7.50.

**Is the data fetched live or from a cache?**
All data is fetched live at query time from each source's current public database. There is no internal caching — results reflect the current state of each database at the time of the query.

**Can I screen organizations and companies, not just individuals?**
Yes. All tools accept organization names as the `query` or `entity` input. OFAC and OpenSanctions both have substantial corporate entity coverage, and the fuzzy matching works equally well for company names.

**Is it legal to query these public law enforcement databases programmatically?**
All sources are public government databases or open-data projects designed for programmatic access. The OFAC SDN list is a public download, Interpol Red Notices are publicly searchable, and data.police.uk provides an open API. See [Apify's guide on web scraping legality](https://blog.apify.com/is-web-scraping-legal/).

**How long does a typical law enforcement intelligence check take?**
Most tools complete in 30-90 seconds. `map_threat_intelligence` with all 7 sources at `max_results: 25` takes 60-120 seconds (parallel execution, so the slowest source determines total time). `verify_identity_clearance` with 4 sources typically completes in 30-60 seconds.

**Can I schedule recurring entity monitoring with this server?**
Yes. Use Apify's built-in scheduling to run re-screening on any cadence via the Apify API, or combine with the [Website Change Monitor](https://apify.com/ryanclinton/website-change-monitor) to trigger re-screening when source pages change.

### Help us improve

If you encounter issues, you can help us debug faster by enabling run sharing in your Apify account:

1. Go to [Account Settings > Privacy](https://console.apify.com/account/privacy)
2. Enable **Share runs with public Actor creators**

This lets us see your run details when something goes wrong, so we can fix issues faster. Your data is only visible to the actor developer, not publicly.

### Support

Found a bug or have a feature request? Open an issue in the [Issues tab](https://console.apify.com/actors/law-enforcement-intelligence-mcp/issues) on this actor's page. For custom solutions or enterprise integrations, reach out through the Apify platform.

# Actor input Schema

## Actor input object example

```json
{}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/law-enforcement-intelligence-mcp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/law-enforcement-intelligence-mcp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call ryanclinton/law-enforcement-intelligence-mcp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/law-enforcement-intelligence-mcp",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Law Enforcement Intelligence MCP Server",
        "description": "Comprehensive threat intelligence and law enforcement screening powered by 7 specialized Apify actors. This MCP server builds threat network graphs with fuzzy name matching across Interpol Red Notices, FBI Most Wanted, OFAC sanctions, and OpenSanctions databases.",
        "version": "1.0",
        "x-build-id": "YKlRAQ8hJzQZ26lox"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ryanclinton~law-enforcement-intelligence-mcp/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ryanclinton-law-enforcement-intelligence-mcp",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/ryanclinton~law-enforcement-intelligence-mcp/runs": {
            "post": {
                "operationId": "runs-sync-ryanclinton-law-enforcement-intelligence-mcp",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/ryanclinton~law-enforcement-intelligence-mcp/run-sync": {
            "post": {
                "operationId": "run-sync-ryanclinton-law-enforcement-intelligence-mcp",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {}
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
