sanctions-screening-mcp-server

v0.1.2 pre-1.0

Screen names against OFAC, EU, UK, and UN sanctions lists and resolve legal entities against GLEIF — offline, fuzzy-matched. A screening aid, not a compliance determination.

sanctions-screening.caseyjhand.com/mcp
claude mcp add --transport http sanctions-screening-mcp-server https://sanctions-screening.caseyjhand.com/mcp
codex mcp add sanctions-screening-mcp-server --url https://sanctions-screening.caseyjhand.com/mcp
{
  "mcpServers": {
    "sanctions-screening-mcp-server": {
      "url": "https://sanctions-screening.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http sanctions-screening-mcp-server https://sanctions-screening.caseyjhand.com/mcp
{
  "mcpServers": {
    "sanctions-screening-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://sanctions-screening.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "sanctions-screening-mcp-server": {
      "type": "http",
      "url": "https://sanctions-screening.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://sanctions-screening.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

6

sanctions_screen_name

Screen a name (person, company, vessel, aircraft) against all loaded sanctions watchlists at once — OFAC SDN + Consolidated, EU, UK, and UN — alias- and fuzzy-aware. Returns scored potential matches with the source list, sanctioning program, designation date, and the matched alias. Strict mode (default) matches exact-normalized then all-tokens-present; fuzzy mode (or auto when strict is empty) adds Jaro-Winkler and phonetic matching and labels hits approximate with a raw 0–1 similarity score. This is a screening AID for a human/compliance review, NOT a compliance determination: a hit means "review this candidate against the official source," and an empty result never means "cleared."

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "sanctions_screen_name",
    "arguments": {
      "name": "<name>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "The name to screen (person, organization, vessel, or aircraft)."
    },
    "entityType": {
      "default": "any",
      "description": "Restrict to one entity class, or \"any\" (default) to screen across all.",
      "type": "string",
      "enum": [
        "any",
        "person",
        "organization",
        "vessel",
        "aircraft"
      ]
    },
    "matchMode": {
      "default": "strict",
      "description": "strict (default): exact-normalized then all-tokens-present. fuzzy: also scored Jaro-Winkler + phonetic. Strict auto-falls-back to fuzzy when it finds nothing.",
      "type": "string",
      "enum": [
        "strict",
        "fuzzy"
      ]
    },
    "minScore": {
      "description": "Jaro-Winkler similarity floor for fuzzy hits (0–1). Applies to fuzzy mode only; defaults to the server's configured floor.",
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "sources": {
      "description": "Restrict to specific source lists. Omit to screen all loaded lists.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "ofac_sdn",
          "ofac_consolidated",
          "eu",
          "uk",
          "un"
        ]
      }
    },
    "limit": {
      "default": 25,
      "description": "Maximum number of potential matches to return.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": [
    "name",
    "entityType",
    "matchMode",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗

sanctions_get_designation

Fetch the full record for one sanctions designation by source list + entry ID — the drill-in after sanctions_screen_name surfaces a candidate. Returns all published aliases, identifiers (passport/national-ID/tax), addresses, dates and places of birth, nationalities, sanctioning program, legal basis, and designation date. The record reflects exactly what the source published; missing fields mean the source omitted them. This is a screening aid — the designation record supports a compliance review, it is not itself a determination.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "sanctions_get_designation",
    "arguments": {
      "source": "<source>",
      "entryId": "<entryId>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "ofac_sdn",
        "ofac_consolidated",
        "eu",
        "uk",
        "un"
      ],
      "description": "Which source list the entry belongs to."
    },
    "entryId": {
      "type": "string",
      "minLength": 1,
      "description": "The source list's own entry ID (the sourceEntryId from sanctions_screen_name)."
    }
  },
  "required": [
    "source",
    "entryId"
  ],
  "additionalProperties": false
}
view source ↗

sanctions_list_sources

List the sanctions watchlists (OFAC SDN + Consolidated, EU, UK, UN) and GLEIF datasets currently loaded in the local mirror, each with its record count, source URL, license, and the mirror's readiness and as-of timestamp. Use this for provenance and freshness on any result — results are only as current as the last mirror refresh, and a not-ready mirror means screening cannot run yet. Attribution: UK data is under the Open Government Licence v3.0; all sources are cited here.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "sanctions_list_sources",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
view source ↗

sanctions_resolve_entity

Resolve a company or organization name (with an optional ISO 3166-1 alpha-2 jurisdiction) to candidate GLEIF Legal Entity Identifiers (LEIs), ranked. This turns a free-text counterparty name into a stable global identifier that sanctions_get_entity and sanctions_trace_ownership key off. Strict mode (default) matches exact-normalized then all-tokens-present; fuzzy mode (or auto when strict is empty) adds Jaro-Winkler scoring labeled approximate with a raw 0–1 score. Returns potential matches to confirm against the GLEIF record — name resolution is a candidate ranking, not an authoritative identification.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "sanctions_resolve_entity",
    "arguments": {
      "name": "<name>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "The company / organization name to resolve to an LEI."
    },
    "jurisdiction": {
      "description": "Optional ISO 3166-1 alpha-2 jurisdiction filter (e.g. \"US\", \"GB\"). Empty string disables it.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "pattern": "^[A-Za-z]{2}$",
          "description": "ISO 3166-1 alpha-2 jurisdiction code (e.g. US, GB)."
        }
      ]
    },
    "matchMode": {
      "default": "strict",
      "description": "strict (default): exact then all-tokens-present. fuzzy: also scored Jaro-Winkler.",
      "type": "string",
      "enum": [
        "strict",
        "fuzzy"
      ]
    },
    "status": {
      "default": "issued",
      "description": "Registration status filter: issued (default), lapsed, or any.",
      "type": "string",
      "enum": [
        "any",
        "issued",
        "lapsed"
      ]
    },
    "minScore": {
      "description": "Jaro-Winkler floor for fuzzy hits (0–1); defaults to the server's configured floor.",
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "limit": {
      "default": 10,
      "description": "Maximum LEI candidates to return.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  },
  "required": [
    "name",
    "matchMode",
    "status",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗

sanctions_get_entity

Fetch the full GLEIF Level 1 record for one LEI: legal name, other/trading names, legal and headquarters addresses, registration status, jurisdiction, registration authority and ID, and last-update date — plus any sanctions hits screened against the same legal name across all loaded watchlists. The screening cross-reference is a screening AID: a hit is a candidate to verify against the official source, and no hit is not a clearance. LEI must be a 20-character GLEIF identifier (18 alphanumerics + 2 check digits).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "sanctions_get_entity",
    "arguments": {
      "lei": "<lei>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "lei": {
      "type": "string",
      "pattern": "^[A-Z0-9]{18}[0-9]{2}$",
      "description": "The 20-character GLEIF Legal Entity Identifier to look up."
    }
  },
  "required": [
    "lei"
  ],
  "additionalProperties": false
}
view source ↗

sanctions_trace_ownership

Trace the GLEIF Level 2 corporate-ownership graph for an LEI: direct and ultimate parents and/or children, traversed breadth-first to a bounded depth, with relationship type for each edge. Set screen_nodes to also screen every entity in the graph against all loaded watchlists — beneficial-ownership screening that resolves "is anyone in this ownership chain sanctioned." Each per-node screen is a screening AID: hits are candidates to verify, and an empty result for a node is not a clearance of that node. Requires a valid 20-character LEI (use sanctions_resolve_entity to obtain one).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "sanctions_trace_ownership",
    "arguments": {
      "lei": "<lei>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "lei": {
      "type": "string",
      "pattern": "^[A-Z0-9]{18}[0-9]{2}$",
      "description": "The 20-character GLEIF LEI at the root of the ownership graph."
    },
    "direction": {
      "default": "both",
      "description": "Walk parents (who owns it), children (what it owns), or both (default).",
      "type": "string",
      "enum": [
        "parents",
        "children",
        "both"
      ]
    },
    "depth": {
      "default": 3,
      "description": "Maximum traversal depth from the root entity (1–5).",
      "type": "integer",
      "minimum": 1,
      "maximum": 5
    },
    "screenNodes": {
      "default": false,
      "description": "When true, screen every node's legal name against all watchlists for beneficial-ownership screening.",
      "type": "boolean"
    }
  },
  "required": [
    "lei",
    "direction",
    "depth",
    "screenNodes"
  ],
  "additionalProperties": false
}
view source ↗

Resources

3

Fetch one sanctions designation by source list + entry ID — a read-only URI mirror of sanctions_get_designation. The record is what the source published; a screening aid, not a determination.

uri sanctions://designation/{source}/{entryId} mime application/json

Fetch one GLEIF Level 1 legal-entity record by LEI — a read-only URI mirror of sanctions_get_entity's entity payload. The sanctions cross-reference is available only via the tool.

uri sanctions://entity/{lei} mime application/json

List the sanctions watchlists and GLEIF datasets currently loaded in the local mirror, each with its record count and the mirror's as-of timestamp — a read-only URI mirror of sanctions_list_sources.

uri sanctions://sources mime application/json

Prompts

1

Structure a full counterparty due-diligence pass: resolve the name to an LEI, pull the ownership tree, screen the named entity and every beneficial owner against all sanctions lists, and summarize hits with provenance and the decision-support caveat.

  • namerequired — The counterparty name to vet (person or organization).
  • jurisdiction — Optional ISO 3166-1 alpha-2 jurisdiction to disambiguate the entity (e.g. "US").