Koskamo

sanctions-screening-mcp-server

An MCP server that screens names and identifiers against eleven sanctions and export-control lists (OFAC, EU, UK, UN, BIS, State) and resolves GLEIF entities offline. It provides tools for fuzzy and strict matching, returning scored potential matches for human compliance review.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

sanctions-screening-mcp-server logo, by cyanheadsCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-06Published by cyanheads
MCP endpoint (Streamable HTTP)
https://sanctions-screening.caseyjhand.com/mcp
Vendor documentation

What its tools do

7 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

7 of 7 have a description · 7 of 7 declare behavior hints · 6 of 6 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Screen a person, company, vessel, or aircraft name against loaded sanctions watchlists
  • Resolve a legal entity to its LEI and trace accounting-consolidation relationships
  • Look up IMO numbers, SWIFT codes, or passport IDs against watchlists
  • Fetch full designation records by source list and entry ID

Source and maintenance

Community listingRegistry 0.6.0
Maintenance checked

Protocol and capabilities

Server
sanctions-screening-mcp-server 0.6.0
MCP protocol negotiated in check
2025-11-25
Tools
7 advertised
Resources
2 advertised
Resource templates
3 advertised
Prompts
1 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "logging": {},
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "subscribe": true,
    "listChanged": true
  },
  "extensions": {
    "io.modelcontextprotocol/skills": {
      "directoryRead": true
    }
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Screen names and identifiers against eleven OFAC, EU, UK, UN, BIS, and State sanctions and export-control lists offline over a keyless mirror. Use sanctions_screen_name or sanctions_screen_identifier; sanctions_resolve_entity → sanctions_get_entity → sanctions_trace_ownership resolves GLEIF identity and accounting-consolidation relationships. Drain trace pages before same-side boundary recovery. The sanctions-screening-guide skill covers identity confirmation, continuation and uncertainty. Results are a screening aid, never a compliance determination or clearance. Check sanctions_list_sources for configured lists, stored counts and successful local sync times, not upstream publication freshness. Verify candidates against official agency lists and Federal Register publications.

Tools

7 advertised

sanctions_screen_name — sanctions-screening-mcp-server: screen name
Advertised by the server during the last successful anonymous check.
Advertised read-only

Screen a name (person, company, vessel, aircraft) against loaded sanctions and export-control watchlists — OFAC SDN + Consolidated, EU, UK, UN, and the six BIS/State CSL lists — alias- and fuzzy-aware. Check sanctions_list_sources for coverage before interpreting an empty result; zero-record CSL lists are not loaded. Returns scored potential matches with the source list, sanctioning program, designation date, and the matched alias; an OFAC party both OFAC lists publish under one entry ID is one hit, its sources naming both lists. Strict mode (default) matches exact-normalized then all-tokens-present, then runs a fuzzy pass over each selected list strict finds nothing on: a full pass when strict finds nothing on any list, otherwise one that adds only candidates covering every word of the name other than legal forms, articles and other function words, and the jurisdiction codes uk, usa, uae, and rf, ranked after the strict hits. Fuzzy mode runs the fuzzy pass over every selected list. It adds Jaro-Winkler and phonetic matching and labels hits approximate with a raw 0–1 similarity score plus the count of query tokens the candidate covers, which orders candidates that tie on score; fuzzySources names the lists it searched. Results are paged: totalAvailable and hasMore report matches beyond the returned page, and nextOffset retrieves them. 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."

sanctions_screen_name input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "The name to screen (person, organization, vessel, or aircraft), in any script. It must contain at least one letter or digit, and at most 64 words and 1024 characters."
    },
    "limit": {
      "type": "integer",
      "default": 25,
      "maximum": 100,
      "minimum": 1,
      "description": "Maximum number of potential matches to return in one page."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Zero-based index of the first potential match to return. Re-call with the returned nextOffset to page through every match when hasMore is true; an offset past the end returns an empty page, not an error."
    },
    "sources": {
      "type": "array",
      "items": {
        "enum": [
          "ofac_sdn",
          "ofac_consolidated",
          "eu",
          "uk",
          "un",
          "bis_el",
          "bis_dpl",
          "bis_uvl",
          "bis_meu",
          "state_dtc",
          "state_acn"
        ],
        "type": "string"
      },
      "description": "Restrict to specific source lists. Omit to screen all loaded lists."
    },
    "minScore": {
      "type": "number",
      "maximum": 1,
      "minimum": 0,
      "description": "Score floor for approximate hits (0–1), applied uniformly to every fuzzy candidate regardless of how it was matched (Jaro-Winkler, token, or phonetic); a query token counts toward queryTokenCoverage only when its match clears it too. It governs every fuzzy pass: fuzzy mode, and in strict mode the pass over the lists strict found nothing on, so raising it can remove approximate hits from a strict screen as well. Exact and strong hits are unaffected. Defaults to the server's configured floor."
    },
    "matchMode": {
      "enum": [
        "strict",
        "fuzzy"
      ],
      "type": "string",
      "default": "strict",
      "description": "strict (default): exact-normalized then all-tokens-present, then a fuzzy pass over each selected list strict finds nothing on — a full pass when strict finds nothing on any list, otherwise adding only candidates that cover every word of the name other than legal forms, articles and other function words, and the jurisdiction codes uk, usa, uae, and rf. fuzzy: a scored Jaro-Winkler + phonetic pass over every selected list."
    },
    "entityType": {
      "enum": [
        "any",
        "person",
        "organization",
        "vessel",
        "aircraft"
      ],
      "type": "string",
      "default": "any",
      "description": "Restrict to one entity class, or \"any\" (default) to screen across all."
    }
  },
  "additionalProperties": false
}
sanctions_screen_name output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "hits",
        "caveat",
        "normalizedQuery",
        "matchModeUsed",
        "totalCount",
        "totalAvailable",
        "totalAvailableBasis",
        "hasMore"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "hits": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "source",
          "sourceLabel",
          "sourceEntryId",
          "sources",
          "entityType",
          "primaryName",
          "matchedName",
          "matchedNameType",
          "matchType"
        ],
        "properties": {
          "score": {
            "type": "number",
            "description": "Raw Jaro-Winkler similarity (0–1) for approximate hits only, measured on native or Russian-alphabet romanized comparison forms — not a confidence verdict or an official alias. Absent for exact/strong hits."
          },
          "source": {
            "enum": [
              "ofac_sdn",
              "ofac_consolidated",
              "eu",
              "uk",
              "un",
              "bis_el",
              "bis_dpl",
              "bis_uvl",
              "bis_meu",
              "state_dtc",
              "state_acn"
            ],
            "type": "string",
            "description": "The watchlist whose record this hit's fields come from — its provenance. For an OFAC party both OFAC lists publish, ofac_sdn unless the Consolidated record matched alone or better; sources names every list."
          },
          "program": {
            "type": "string",
            "description": "Sanctioning program / regime, when published by the source."
          },
          "sources": {
            "type": "array",
            "items": {
              "enum": [
                "ofac_sdn",
                "ofac_consolidated",
                "eu",
                "uk",
                "un",
                "bis_el",
                "bis_dpl",
                "bis_uvl",
                "bis_meu",
                "state_dtc",
                "state_acn"
              ],
              "type": "string"
            },
            "description": "Every screened list this candidate is on, in list order: one list, or ofac_sdn and ofac_consolidated together for an OFAC party both OFAC lists publish under one entry ID — one hit, not two. Read this, not source, for every list; the entry ID resolves in sanctions_get_designation under each."
          },
          "matchType": {
            "enum": [
              "exact",
              "strong",
              "approximate"
            ],
            "type": "string",
            "description": "exact = native normalized name equality; strong = all native query tokens present; approximate = fuzzy/phonetic, optionally comparing Russian-alphabet romanizations while retaining the published matchedName."
          },
          "entityType": {
            "enum": [
              "person",
              "organization",
              "vessel",
              "aircraft",
              "unknown"
            ],
            "type": "string",
            "description": "Entity classification as published by the source."
          },
          "matchedName": {
            "type": "string",
            "description": "The specific name or alias string that matched the query."
          },
          "primaryName": {
            "type": "string",
            "description": "Primary published name of the designated entity."
          },
          "sourceLabel": {
            "type": "string",
            "description": "Human-readable name of the source list."
          },
          "sourceEntryId": {
            "type": "string",
            "description": "The list's own entry ID — pass to sanctions_get_designation for the full record."
          },
          "designationDate": {
            "type": "string",
            "description": "The source's own designation date as YYYY-MM-DD; absent when unpublished. For an OFAC party both OFAC lists publish, the date of the source record: each OFAC file dates the party from its own lists, so the two often differ, and sanctions_get_designation under the other list returns that record's date."
          },
          "matchedNameType": {
            "enum": [
              "primary",
              "aka",
              "fka",
              "low-quality-aka"
            ],
            "type": "string",
            "description": "Provenance of the matched name: primary, a.k.a., f.k.a., or a low-quality a.k.a."
          },
          "referenceNumber": {
            "type": "string",
            "description": "The list's published reference number (UN, EU, UK OFSI Group ID); absent when the list publishes none for the entry."
          },
          "queryTokenCoverage": {
            "type": "object",
            "required": [
              "covered",
              "total"
            ],
            "properties": {
              "total": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Total tokens in the normalized query."
              },
              "covered": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Query tokens individually matched by one of this candidate's tokens at the applied score floor."
              }
            },
            "description": "How much of the query this candidate explains, as a literal token count — a second real measurement, never folded into score. It is the tie-break applied after score, because one shared exact token pins several candidates at the same score. Absent for exact/strong hits.",
            "additionalProperties": false
          }
        },
        "description": "One potential match — a candidate to verify, never a determination.",
        "additionalProperties": false
      },
      "description": "Potential matches, ranked by match type, then score, then how much of the query each candidate explains. Candidates tied on all three are ordered by source list, then entry ID — not by relevance."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "name_not_searchable",
                "name_too_long",
                "mirror_not_ready"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `name_not_searchable`: The name contains no letter or digit, so nothing in it can be matched. `name_too_long`: The name is longer than 64 words or 1024 characters. `mirror_not_ready`: The sanctions mirror has never completed an initial sync. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "caveat": {
      "type": "string",
      "description": "Decision-support caveat — this is a screening aid, not a compliance determination."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when no candidate matched — how to broaden, and what an empty result does NOT mean — when the requested offset sits past the end of the result set, or when the fuzzy pass reached its candidate bound and a more distinctive word would narrow it."
    },
    "hasMore": {
      "type": "boolean",
      "description": "True when the result set holds matches beyond this page — re-call with nextOffset. It describes pages only: false on the last page, whatever totalAvailableBasis says."
    },
    "nextOffset": {
      "type": "number",
      "description": "The offset to request next. Present only when hasMore is true."
    },
    "totalCount": {
      "type": "number",
      "description": "Number of potential matches returned in this page."
    },
    "fuzzySources": {
      "type": "array",
      "items": {
        "enum": [
          "ofac_sdn",
          "ofac_consolidated",
          "eu",
          "uk",
          "un",
          "bis_el",
          "bis_dpl",
          "bis_uvl",
          "bis_meu",
          "state_dtc",
          "state_acn"
        ],
        "type": "string"
      },
      "description": "The selected lists the fuzzy pass searched, in list order; absent when no fuzzy pass ran. Beside strict hits these are the lists strict found nothing on, and only their candidates covering every word of the name other than legal forms, articles and other function words, and the jurisdiction codes uk, usa, uae, and rf were added."
    },
    "matchModeUsed": {
      "type": "string",
      "description": "fuzzy when every selected list was fuzzy-searched (fuzzy mode, or a strict screen that found nothing on any list); strict otherwise, including a strict screen whose strict-empty lists were completed by a fuzzy pass."
    },
    "totalAvailable": {
      "type": "number",
      "description": "Potential matches in the result set across all pages, before limit and offset were applied — every one is reachable by paging. An OFAC party both OFAC lists publish counts once."
    },
    "normalizedQuery": {
      "type": "string",
      "description": "The name as the server folded it for matching."
    },
    "totalAvailableBasis": {
      "enum": [
        "exact",
        "lower_bound"
      ],
      "type": "string",
      "description": "How to read totalAvailable: exact = the complete strict match set, strict having found a match on every selected list; lower_bound = a fuzzy pass ran (fuzzySources is present), which scores only the candidates blocking pooled, so more matches may exist beyond the result set."
    }
  },
  "additionalProperties": false
}
sanctions_screen_name annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
sanctions_screen_identifier — sanctions-screening-mcp-server: screen identifier
Advertised by the server during the last successful anonymous check.
Advertised read-only

Look up an identifier — a vessel IMO number, a SWIFT/BIC code, a digital-currency wallet address, a passport or national ID number, or any other identifier a list publishes — against all loaded sanctions watchlists at once: OFAC SDN + Consolidated, EU, UK, and UN. Exact match after normalization, with no fuzzy or partial matching and no score: spacing, letter case, and the separators - . / are ignored, an IMO number matches with or without its IMO prefix, a SWIFT/BIC code compares on its first eight characters so a branch code matches its institution, and a wallet address folds case only where its encoding is case-insensitive (hex, bech32, cashaddr — never base58). Returns every designation that publishes a matching identifier, one per designation — an OFAC party both OFAC lists publish under one entry ID is one hit, its sources naming both lists — with the identifiers that matched as published; sanctions_get_designation pulls the full record. 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" — an identifier a list prints only in free-text remarks, or bundled with other numbers in one field, does not match.

sanctions_screen_identifier input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "value"
  ],
  "properties": {
    "type": {
      "enum": [
        "any",
        "imo",
        "swift_bic",
        "digital_currency_address",
        "passport",
        "national_id"
      ],
      "type": "string",
      "default": "any",
      "description": "Restrict to one identifier category, matched on the label each list publishes, or \"any\" (default) to search every published identifier, including categories with no name here (MMSI, call signs, tail numbers, tax and registration numbers, email, websites)."
    },
    "value": {
      "type": "string",
      "minLength": 1,
      "description": "The identifier to look up, as you hold it (e.g. \"IMO 7406784\", \"DCBKKPPY\", a wallet address, a passport number). Must contain at least one character other than whitespace and - . /"
    },
    "sources": {
      "type": "array",
      "items": {
        "enum": [
          "ofac_sdn",
          "ofac_consolidated",
          "eu",
          "uk",
          "un",
          "bis_el",
          "bis_dpl",
          "bis_uvl",
          "bis_meu",
          "state_dtc",
          "state_acn"
        ],
        "type": "string"
      },
      "description": "Restrict to specific source lists. Omit to search all loaded lists."
    }
  },
  "additionalProperties": false
}
sanctions_screen_identifier output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "hits",
        "caveat",
        "totalCount"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "hits": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "source",
          "sourceLabel",
          "sourceEntryId",
          "sources",
          "primaryName",
          "entityType",
          "matchedIdentifiers"
        ],
        "properties": {
          "source": {
            "enum": [
              "ofac_sdn",
              "ofac_consolidated",
              "eu",
              "uk",
              "un",
              "bis_el",
              "bis_dpl",
              "bis_uvl",
              "bis_meu",
              "state_dtc",
              "state_acn"
            ],
            "type": "string",
            "description": "The watchlist whose record this hit's fields come from — its provenance. For an OFAC party both OFAC lists publish, ofac_sdn unless the Consolidated record matched alone; sources names every list."
          },
          "program": {
            "type": "string",
            "description": "Sanctioning program / regime, when published by the source."
          },
          "sources": {
            "type": "array",
            "items": {
              "enum": [
                "ofac_sdn",
                "ofac_consolidated",
                "eu",
                "uk",
                "un",
                "bis_el",
                "bis_dpl",
                "bis_uvl",
                "bis_meu",
                "state_dtc",
                "state_acn"
              ],
              "type": "string"
            },
            "description": "Every screened list this candidate is on, in list order: one list, or ofac_sdn and ofac_consolidated together for an OFAC party both OFAC lists publish under one entry ID — one hit, not two. Read this, not source, for every list; the entry ID resolves in sanctions_get_designation under each."
          },
          "entityType": {
            "enum": [
              "person",
              "organization",
              "vessel",
              "aircraft",
              "unknown"
            ],
            "type": "string",
            "description": "Entity classification as published by the source."
          },
          "primaryName": {
            "type": "string",
            "description": "Primary published name of the designated entity."
          },
          "sourceLabel": {
            "type": "string",
            "description": "Human-readable name of the source list."
          },
          "sourceEntryId": {
            "type": "string",
            "description": "The list's own entry ID — pass to sanctions_get_designation for the full record."
          },
          "matchedIdentifiers": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "value"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "description": "Identifier label as the list publishes it (e.g. Vessel Registration Identification, IMO Number, SWIFT BIC, Digital Currency Address - ETH, Passport)."
                },
                "value": {
                  "type": "string",
                  "description": "Identifier value exactly as published, letter case included."
                },
                "country": {
                  "type": "string",
                  "description": "Issuing country/authority, when published."
                }
              },
              "description": "One published identifier that matched the lookup.",
              "additionalProperties": false
            },
            "description": "Every identifier this designation publishes that matched, as published — several when the list prints one number more than one way."
          }
        },
        "description": "One designation that publishes a matching identifier — a candidate to verify.",
        "additionalProperties": false
      },
      "description": "Designations that publish a matching identifier, one per designation (an OFAC party on both OFAC lists once), ordered by source list then entry ID. Not paged — the most widely shared published identifiers map to about a dozen designations."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "identifier_not_searchable",
                "mirror_not_ready"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `identifier_not_searchable`: The value is left with nothing to compare once whitespace and the separators - . / are removed (or, for type imo, a bare IMO prefix). `mirror_not_ready`: The sanctions mirror has never completed an initial sync. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "caveat": {
      "type": "string",
      "description": "Decision-support caveat — this is a screening aid, not a compliance determination."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when no designation matched — what to try next, and what an empty result does NOT mean."
    },
    "totalCount": {
      "type": "number",
      "description": "Number of designations returned."
    }
  },
  "additionalProperties": false
}
sanctions_screen_identifier annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
sanctions_get_designation — sanctions-screening-mcp-server: get designation
Advertised by the server during the last successful anonymous check.
Advertised read-only

Fetch the full record for one sanctions designation by source list + entry ID or the list's published reference number — the drill-in after sanctions_screen_name or sanctions_screen_identifier surfaces a candidate, or the lookup for a reference a notice cites (UN QDe.004, EU EU.27.28, UK OFSI Group ID). Returns all published aliases, identifiers (passport, national ID, tax and registration numbers, SWIFT/BIC codes, digital-currency addresses, vessel call signs, aircraft tail and serial numbers, phone numbers, email addresses, websites), addresses, dates and places of birth at the precision the source published, nationalities, descriptive features (a vessel's flag, type, and tonnage; an aircraft's model and operator; a title or gender; sanctions notes), 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.

sanctions_get_designation input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "source",
    "entryId"
  ],
  "properties": {
    "source": {
      "enum": [
        "ofac_sdn",
        "ofac_consolidated",
        "eu",
        "uk",
        "un",
        "bis_el",
        "bis_dpl",
        "bis_uvl",
        "bis_meu",
        "state_dtc",
        "state_acn"
      ],
      "type": "string",
      "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), or the reference number the list publishes for the entry (UN QDe.004, EU EU.27.28, UK OFSI Group ID 14196). Matched trimmed and case-insensitive, entry ID first."
    }
  },
  "additionalProperties": false
}
sanctions_get_designation output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "source",
        "sourceLabel",
        "sourceEntryId",
        "entityType",
        "primaryName",
        "aliases",
        "identifiers",
        "addresses",
        "datesOfBirth",
        "nationalities",
        "features",
        "caveat"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "designation_not_found",
                "reference_ambiguous",
                "mirror_not_ready"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `designation_not_found`: No designation in the given source has that entry ID or reference number in the mirror. `reference_ambiguous`: The entry ID is a reference number more than one designation in the source publishes. `mirror_not_ready`: The sanctions mirror has never completed an initial sync. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "caveat": {
      "type": "string",
      "description": "Decision-support caveat — this is a screening aid, not a compliance determination."
    },
    "source": {
      "enum": [
        "ofac_sdn",
        "ofac_consolidated",
        "eu",
        "uk",
        "un",
        "bis_el",
        "bis_dpl",
        "bis_uvl",
        "bis_meu",
        "state_dtc",
        "state_acn"
      ],
      "type": "string",
      "description": "Source list the entry belongs to."
    },
    "aliases": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "nameType"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Alias as published."
          },
          "nameType": {
            "enum": [
              "primary",
              "aka",
              "fka",
              "low-quality-aka"
            ],
            "type": "string",
            "description": "Alias provenance: a.k.a., f.k.a., or a low-quality a.k.a."
          }
        },
        "description": "One published alias.",
        "additionalProperties": false
      },
      "description": "All published aliases / name variants."
    },
    "program": {
      "type": "string",
      "description": "Sanctioning program / regime, when published."
    },
    "remarks": {
      "type": "string",
      "description": "Free-form remarks published by the source, when present."
    },
    "features": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "The source's own label for the value, verbatim (e.g. Vessel Flag, VESSEL TYPE, Secondary sanctions risk:, CurrentBelievedFlagOfShip)."
          },
          "circa": {
            "type": "boolean",
            "const": true,
            "description": "Present when the source flags a date value as approximate."
          },
          "value": {
            "type": "string",
            "description": "The value as published; a date is ISO 8601 at the precision the source published."
          }
        },
        "description": "One published descriptive value.",
        "additionalProperties": false
      },
      "description": "Values the source publishes to describe the party rather than identify it, in published order: OFAC's vessel flag, type, and tonnage, aircraft model and operator, title, gender, and sanctions notes; the UK list's ship details. Empty when the source publishes none. Screening never matches on them."
    },
    "addresses": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "full"
        ],
        "properties": {
          "full": {
            "type": "string",
            "description": "Single-line rendering of the address."
          },
          "country": {
            "type": "string",
            "description": "Country, when published."
          }
        },
        "description": "One published address.",
        "additionalProperties": false
      },
      "description": "Published addresses."
    },
    "entityType": {
      "enum": [
        "person",
        "organization",
        "vessel",
        "aircraft",
        "unknown"
      ],
      "type": "string",
      "description": "Entity classification as published."
    },
    "legalBasis": {
      "type": "string",
      "description": "Statutory / regulatory basis as the list publishes it — OFAC's legal-basis references, the EU regulation title, the UK regime's regulations — several joined with '; '. Absent when unpublished; the UN list publishes none."
    },
    "identifiers": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Identifier category as the source labels it (e.g. Passport, National ID, SWIFT/BIC, Digital Currency Address - XBT, Phone Number, Website)."
          },
          "value": {
            "type": "string",
            "description": "Identifier value exactly as published, letter case included."
          },
          "country": {
            "type": "string",
            "description": "Issuing country/authority, when published."
          }
        },
        "description": "One structured identifier.",
        "additionalProperties": false
      },
      "description": "Published identifiers: identity documents (passport, national ID, tax, registration) and, where the source publishes them, SWIFT/BIC codes, digital-currency addresses, vessel call signs, aircraft tail and serial numbers, phone numbers, email addresses, and websites."
    },
    "primaryName": {
      "type": "string",
      "description": "Primary published name."
    },
    "sourceLabel": {
      "type": "string",
      "description": "Human-readable name of the source list."
    },
    "datesOfBirth": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "Date of birth in ISO 8601 at the precision the source published: YYYY-MM-DD, YYYY-MM, or YYYY. A range is an interval whose ends keep their own precision (1955/1957); an open end is .. (../1980). A value with no ISO form is kept as published."
          },
          "circa": {
            "type": "boolean",
            "const": true,
            "description": "Present when the source flags the date as approximate; never without date."
          },
          "place": {
            "type": "string",
            "description": "Place of birth, when published."
          }
        },
        "description": "One date/place of birth.",
        "additionalProperties": false
      },
      "description": "Published dates and places of birth (persons)."
    },
    "nationalities": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Published nationalities / citizenships."
    },
    "sourceEntryId": {
      "type": "string",
      "description": "The source list's own entry ID."
    },
    "designationDate": {
      "type": "string",
      "description": "The source's own designation date as YYYY-MM-DD; absent when unpublished. An OFAC party is dated from its entries on the lists that file publishes, so its ofac_sdn and ofac_consolidated records can differ."
    },
    "referenceNumber": {
      "type": "string",
      "description": "The list's published reference number (UN, EU, UK OFSI Group ID); absent when the list publishes none for the entry. OFAC publishes none — its entry ID is its published number."
    }
  },
  "additionalProperties": false
}
sanctions_get_designation annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
sanctions_list_sources — sanctions-screening-mcp-server: list sources
Advertised by the server during the last successful anonymous check.
Advertised read-only

List supported watchlists (OFAC SDN + Consolidated, EU, UK, UN, BIS Entity/Denied Persons/Unverified/Military End User, State ITAR Debarred/Nonproliferation) and GLEIF datasets with current mirrored counts, source URLs, licenses, readiness, and as-of timestamps. coverageNotice names unloaded CSL lists and how to refresh them; prior mirror readiness does not establish coverage of newly added lists. For GLEIF, reports Level 2 ownership relationships, reporting-exception coverage, and alternate-name index readiness. Use this for provenance, freshness, and coverage on any result. Attribution: UK data is under the Open Government Licence v3.0; BIS and State CSL data is supplied by the International Trade Administration under its published terms. This product uses the International Trade Administration’s Data API but is not endorsed or certified by the International Trade Administration.

sanctions_list_sources input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {},
  "additionalProperties": false
}
sanctions_list_sources output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "sanctionsReady",
        "leiReady",
        "reportingExceptionsLoaded",
        "alternateNamesIndexed",
        "sources"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "Machine-readable failure mode."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "leiAsOf": {
      "type": "string",
      "description": "ISO 8601 timestamp of the last completed GLEIF sync, when available."
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "code",
          "label",
          "recordCount",
          "url",
          "license"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "Upstream URL the mirror harvests this source from, as configured — for gleif, the golden-copy API base."
          },
          "code": {
            "type": "string",
            "description": "Source code (ofac_sdn, eu, …, or gleif)."
          },
          "label": {
            "type": "string",
            "description": "Human-readable source name."
          },
          "license": {
            "type": "string",
            "description": "Redistribution license / terms for this source."
          },
          "recordCount": {
            "type": "number",
            "description": "Records currently loaded for this source — for gleif, Level 1 entity records."
          },
          "relationshipCount": {
            "type": "number",
            "description": "GLEIF Level 2 ownership relationships loaded (gleif only)."
          },
          "reportingExceptionCount": {
            "type": "number",
            "description": "GLEIF reporting-exception records loaded (gleif only). Absent when the dataset has never been loaded — never read as zero."
          }
        },
        "description": "One supported source with current mirrored count, provenance, and license; zero-record CSL lists are not loaded.",
        "additionalProperties": false
      },
      "description": "All supported sources, sanctions lists then the GLEIF dataset. Check coverageNotice for unloaded CSL lists."
    },
    "leiReady": {
      "type": "boolean",
      "description": "True once the GLEIF (LEI) mirror has completed at least one full sync."
    },
    "sanctionsAsOf": {
      "type": "string",
      "description": "ISO 8601 timestamp of the last completed sanctions sync, when available."
    },
    "coverageNotice": {
      "type": "string",
      "description": "Unloaded CSL list codes and refresh guidance. Present when any CSL list has zero mirrored records; prior sanctions readiness does not establish coverage of newly added lists."
    },
    "sanctionsReady": {
      "type": "boolean",
      "description": "True once the sanctions mirror has completed at least one full sync."
    },
    "alternateNamesIndexed": {
      "type": "boolean",
      "description": "Whether the GLEIF alternate-name index — trading, previous, alternative-language, and transliterated names — is built. When false, sanctions_resolve_entity searches legal names only until mirror:init reloads the GLEIF golden copy. True on a GLEIF mirror that has never loaded (leiReady false): its empty index is complete, and the first load builds it with the entities."
    },
    "reportingExceptionsLoaded": {
      "type": "boolean",
      "description": "Whether GLEIF reporting exceptions are loaded. When false, sanctions_trace_ownership reads a parent level with no published relationship as unknown."
    }
  },
  "additionalProperties": false
}
sanctions_list_sources annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
sanctions_resolve_entity — sanctions-screening-mcp-server: resolve entity
Advertised by the server during the last successful anonymous check.
Advertised read-only

Resolve a company or organization name (with an optional jurisdiction: a country code, which includes its subdivisions, or an ISO 3166-2 subdivision code) 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. Every name GLEIF publishes takes part: the legal name, previous legal names, trading names, alternative-language legal names, and ASCII transliterations of a legal name in another script — each candidate reports the name it matched on and that name's type, one candidate per LEI. 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 plus the count of query tokens the matched name covers, which orders candidates that tie on score. Results are paged: totalAvailable and hasMore report candidates beyond the returned page, and nextOffset retrieves them. Returns potential matches to confirm against the GLEIF record — name resolution is a candidate ranking, not an authoritative identification.

sanctions_resolve_entity input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "The company / organization name to resolve to an LEI, in any script. It must contain at least one letter or digit, and at most 64 words and 1024 characters."
    },
    "limit": {
      "type": "integer",
      "default": 10,
      "maximum": 50,
      "minimum": 1,
      "description": "Maximum LEI candidates to return in one page."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Zero-based index of the first LEI candidate to return. Re-call with the returned nextOffset to page through every candidate when hasMore is true; an offset past the end returns an empty page, not an error."
    },
    "status": {
      "enum": [
        "any",
        "issued",
        "lapsed"
      ],
      "type": "string",
      "default": "issued",
      "description": "Registration status filter. issued (default) matches ISSUED; lapsed matches exactly LAPSED; any applies no filter and is the only value that reaches the other states (RETIRED, DUPLICATE, ANNULLED, PENDING_TRANSFER, PENDING_ARCHIVAL, MERGED) — each candidate's status field names its state."
    },
    "minScore": {
      "type": "number",
      "maximum": 1,
      "minimum": 0,
      "description": "Jaro-Winkler floor for fuzzy hits (0–1); defaults to the server's configured floor."
    },
    "matchMode": {
      "enum": [
        "strict",
        "fuzzy"
      ],
      "type": "string",
      "default": "strict",
      "description": "strict (default): exact then all-tokens-present. fuzzy: also scored Jaro-Winkler."
    },
    "jurisdiction": {
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "pattern": "^[A-Za-z]{2}(-[A-Za-z0-9]{1,3})?$",
          "description": "ISO 3166-1 alpha-2 country code (e.g. US) or ISO 3166-2 subdivision code (e.g. US-DE), case-insensitive."
        }
      ],
      "description": "Optional legal-jurisdiction filter. A country code (\"US\") matches that country and every subdivision under it (US-DE, US-CA); a subdivision code (\"US-DE\") matches exactly. Case-insensitive. Empty string disables it."
    }
  },
  "additionalProperties": false
}
sanctions_resolve_entity output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "matches",
        "normalizedQuery",
        "matchModeUsed",
        "totalCount",
        "totalAvailable",
        "totalAvailableBasis",
        "hasMore"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "name_not_searchable",
                "name_too_long",
                "mirror_not_ready"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `name_not_searchable`: The name contains no letter or digit, so nothing in it can be matched. `name_too_long`: The name is longer than 64 words or 1024 characters. `mirror_not_ready`: The GLEIF (LEI) mirror has never completed an initial sync. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Guidance when no LEI matched and how to broaden, when the requested offset sits past the end of the result set, when a bound cut the candidate set and how to narrow the name, or when the mirror has not indexed GLEIF's other and transliterated names yet, so only legal names were searched."
    },
    "hasMore": {
      "type": "boolean",
      "description": "True when the result set holds candidates beyond this page — re-call with nextOffset. It describes pages only: false on the last page, whatever totalAvailableBasis says."
    },
    "matches": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "lei",
          "legalName",
          "matchedName",
          "matchedNameType",
          "matchType"
        ],
        "properties": {
          "lei": {
            "type": "string",
            "description": "20-character GLEIF Legal Entity Identifier."
          },
          "score": {
            "type": "number",
            "description": "Raw Jaro-Winkler similarity (0–1) for approximate hits only — a real measurement."
          },
          "status": {
            "type": "string",
            "description": "Registration status (e.g. ISSUED, LAPSED)."
          },
          "legalName": {
            "type": "string",
            "description": "Registered legal name of the entity."
          },
          "matchType": {
            "enum": [
              "exact",
              "strong",
              "approximate"
            ],
            "type": "string",
            "description": "exact = normalized equality; strong = all tokens present; approximate = fuzzy."
          },
          "matchedName": {
            "type": "string",
            "description": "The name that matched the query — the legal name or one of the other or transliterated names GLEIF publishes for the entity."
          },
          "jurisdiction": {
            "type": "string",
            "description": "Legal jurisdiction (ISO code), when published."
          },
          "matchedNameType": {
            "type": "string",
            "description": "Type of matchedName: LEGAL_NAME, PREVIOUS_LEGAL_NAME (a former legal name, not the current one), TRADING_OR_OPERATING_NAME, ALTERNATIVE_LANGUAGE_LEGAL_NAME, PREFERRED_ASCII_TRANSLITERATED_LEGAL_NAME, AUTO_ASCII_TRANSLITERATED_LEGAL_NAME, or UNKNOWN for a name the mirror stored without GLEIF's type."
          },
          "queryTokenCoverage": {
            "type": "object",
            "required": [
              "covered",
              "total"
            ],
            "properties": {
              "total": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Total tokens in the normalized query."
              },
              "covered": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Query tokens individually matched by one of the matched name's tokens at the applied score floor."
              }
            },
            "description": "How much of the query the matched name explains, as a literal token count — a second real measurement, never folded into score. It is the tie-break applied after score, because one shared exact token pins several candidates at the same score. Absent for exact/strong matches.",
            "additionalProperties": false
          }
        },
        "description": "One LEI candidate — confirm against the GLEIF record before relying on it.",
        "additionalProperties": false
      },
      "description": "LEI candidates, ranked by match type, then score, then how much of the query each matched name explains."
    },
    "nextOffset": {
      "type": "number",
      "description": "The offset to request next. Present only when hasMore is true."
    },
    "totalCount": {
      "type": "number",
      "description": "Number of LEI candidates returned in this page."
    },
    "matchModeUsed": {
      "type": "string",
      "description": "The match mode actually applied (strict may upgrade to fuzzy)."
    },
    "totalAvailable": {
      "type": "number",
      "description": "LEI candidates in the result set across all pages, before limit and offset were applied — every one is reachable by paging."
    },
    "normalizedQuery": {
      "type": "string",
      "description": "The name as the server folded it for matching."
    },
    "totalAvailableBasis": {
      "enum": [
        "exact",
        "lower_bound"
      ],
      "type": "string",
      "description": "How to read totalAvailable: exact = the complete strict candidate set; lower_bound = a fuzzy pass ran, which scores only the candidates blocking pooled, or the strict scan stopped at its 2,000-name bound, so more candidates may exist beyond the result set."
    }
  },
  "additionalProperties": false
}
sanctions_resolve_entity annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
sanctions_get_entity — sanctions-screening-mcp-server: get entity
Advertised by the server during the last successful anonymous check.
Advertised read-only

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 a sanctions cross-reference against all loaded watchlists. The cross-reference screens the legal name and every other and transliterated name strict (exact, then all tokens present — never fuzzy, unlike sanctions_screen_name), and looks up the LEI and the registration number as exact non-document identifiers, the registration number matching only an identifier published for the country of the entity's legal jurisdiction. Hits merge to one per designation, an OFAC party both OFAC lists publish to one hit whose sources names both: matchedOn names every input that produced each, and a hit only an identifier produced carries matchedIdentifiers and no matchedName. 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. screeningStatus says whether that cross-reference actually ran — an empty sanctionsHits under not_ready means the sanctions mirror was unavailable, not that nothing matched. sanctionsScreen says whether the hit list is the whole set: it reports how many potential matches existed before the cap, so a capped cross-reference is distinguishable from a complete one. LEI must be a 20-character GLEIF identifier (18 alphanumerics + 2 check digits).

sanctions_get_entity input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "lei"
  ],
  "properties": {
    "lei": {
      "type": "string",
      "pattern": "^[A-Z0-9]{18}[0-9]{2}$",
      "description": "The 20-character GLEIF Legal Entity Identifier to look up."
    }
  },
  "additionalProperties": false
}
sanctions_get_entity output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "lei",
        "legalName",
        "otherNames",
        "alternateNames",
        "sanctionsHits",
        "screeningStatus",
        "caveat"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "lei": {
      "type": "string",
      "description": "The 20-character GLEIF Legal Entity Identifier."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "lei_not_found",
                "invalid_lei_checksum",
                "mirror_not_ready"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `lei_not_found`: No GLEIF entity in the mirror carries the LEI, and its check digits are valid. `invalid_lei_checksum`: No GLEIF entity in the mirror carries the LEI, and its ISO 17442 check digits fail. `mirror_not_ready`: The GLEIF (LEI) mirror has never completed an initial sync. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "caveat": {
      "type": "string",
      "description": "Decision-support caveat — the screening cross-reference is an aid, not a determination."
    },
    "status": {
      "type": "string",
      "description": "Registration status (e.g. ISSUED, LAPSED)."
    },
    "legalName": {
      "type": "string",
      "description": "Registered legal name."
    },
    "lastUpdate": {
      "type": "string",
      "description": "ISO 8601 last-update timestamp from the LEI record."
    },
    "otherNames": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Other names published in the LEI record (trading, previous, and alternative-language legal names), as plain strings."
    },
    "jurisdiction": {
      "type": "string",
      "description": "Legal jurisdiction (ISO code), when published."
    },
    "legalAddress": {
      "type": "string",
      "description": "Single-line legal address, when published."
    },
    "sanctionsHits": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "source",
          "sourceLabel",
          "sourceEntryId",
          "sources",
          "primaryName",
          "matchedOn"
        ],
        "properties": {
          "score": {
            "type": "number",
            "description": "Never set by this cross-reference: only an approximate (fuzzy) match carries a raw Jaro-Winkler score, and the cross-reference screens strict."
          },
          "source": {
            "enum": [
              "ofac_sdn",
              "ofac_consolidated",
              "eu",
              "uk",
              "un",
              "bis_el",
              "bis_dpl",
              "bis_uvl",
              "bis_meu",
              "state_dtc",
              "state_acn"
            ],
            "type": "string",
            "description": "Watchlist whose record this hit is attributed to: primaryName comes from it. For an OFAC party both OFAC lists publish, ofac_sdn unless the Consolidated record matched alone or better, and matchedName, matchedIdentifiers, and matchedOn cover what either record matched; sources names every list."
          },
          "sources": {
            "type": "array",
            "items": {
              "enum": [
                "ofac_sdn",
                "ofac_consolidated",
                "eu",
                "uk",
                "un",
                "bis_el",
                "bis_dpl",
                "bis_uvl",
                "bis_meu",
                "state_dtc",
                "state_acn"
              ],
              "type": "string"
            },
            "description": "Every screened list this candidate is on, in list order: one list, or ofac_sdn and ofac_consolidated together for an OFAC party both OFAC lists publish under one entry ID — one hit, not two. Read this, not source, for every list; the entry ID resolves in sanctions_get_designation under each."
          },
          "matchType": {
            "enum": [
              "exact",
              "strong",
              "approximate"
            ],
            "type": "string",
            "description": "Match classification of matchedName: exact or strong, never approximate (the cross-reference screens strict, never fuzzy). Absent when only an identifier produced the hit."
          },
          "matchedOn": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "input",
                "value"
              ],
              "properties": {
                "input": {
                  "enum": [
                    "legal_name",
                    "other_name",
                    "lei",
                    "registration_number"
                  ],
                  "type": "string",
                  "description": "Which value: legal_name, or other_name (an other or transliterated name), each screened as a name, strict; lei, or registration_number (the ID at the registration authority), each looked up as a non-document identifier."
                },
                "value": {
                  "type": "string",
                  "description": "The value as GLEIF publishes it."
                },
                "nameType": {
                  "type": "string",
                  "description": "GLEIF's type for an other_name (e.g. TRADING_OR_OPERATING_NAME, AUTO_ASCII_TRANSLITERATED_LEGAL_NAME), or UNKNOWN for a name the mirror stored without one. Present on other_name only."
                }
              },
              "description": "One value of the entity the cross-reference screened.",
              "additionalProperties": false
            },
            "description": "Every input of the entity that produced this hit — its legal name, an other or transliterated name, its LEI, or its registration number — in screening order."
          },
          "matchedName": {
            "type": "string",
            "description": "The designation's name or alias that matched one of the entity's screened names — the strongest match. Absent when only an identifier produced the hit."
          },
          "primaryName": {
            "type": "string",
            "description": "Primary published name of the designation."
          },
          "sourceLabel": {
            "type": "string",
            "description": "Human-readable source list name."
          },
          "sourceEntryId": {
            "type": "string",
            "description": "Source entry ID — pass to sanctions_get_designation."
          },
          "matchedIdentifiers": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "value"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "description": "Identifier label as the list publishes it (e.g. Legal Entity Number, Registration Number)."
                },
                "value": {
                  "type": "string",
                  "description": "The identifier value, as published."
                },
                "country": {
                  "type": "string",
                  "description": "Issuing country as published, when published."
                }
              },
              "description": "An identifier the designation publishes that equals the entity's LEI, or its registration number published for the country of its legal jurisdiction.",
              "additionalProperties": false
            },
            "description": "Every identifier the designation publishes that equals the entity's LEI or its country-matched registration number, as published. Present only when an identifier produced the hit."
          }
        },
        "description": "A potential watchlist match on one or more of the entity's names or identifiers — verify, do not assume.",
        "additionalProperties": false
      },
      "description": "Sanctions screening cross-reference of the entity, one hit per designation (an OFAC party both OFAC lists publish once): exact name and identifier matches first, then strong name matches."
    },
    "alternateNames": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "The name as published."
          },
          "type": {
            "type": "string",
            "description": "GLEIF name type: PREVIOUS_LEGAL_NAME (a former legal name, not the current one), TRADING_OR_OPERATING_NAME, ALTERNATIVE_LANGUAGE_LEGAL_NAME, PREFERRED_ASCII_TRANSLITERATED_LEGAL_NAME, AUTO_ASCII_TRANSLITERATED_LEGAL_NAME, or UNKNOWN for a name the mirror stored without GLEIF's type."
          }
        },
        "description": "One name GLEIF publishes beside the legal name.",
        "additionalProperties": false
      },
      "description": "Every other and transliterated name with its type, in the order published — the typed view of otherNames plus the ASCII transliterations of a legal name in another script."
    },
    "sanctionsScreen": {
      "type": "object",
      "required": [
        "totalAvailable",
        "totalAvailableBasis",
        "hasMore",
        "screenedInputs"
      ],
      "properties": {
        "hasMore": {
          "type": "boolean",
          "description": "True when the potential matches were capped — re-screen the entity's names with sanctions_screen_name and look up its LEI and registration number with sanctions_screen_identifier to see the rest."
        },
        "screenedInputs": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "input",
              "value"
            ],
            "properties": {
              "input": {
                "enum": [
                  "legal_name",
                  "other_name",
                  "lei",
                  "registration_number"
                ],
                "type": "string",
                "description": "Which value: legal_name, or other_name (an other or transliterated name), each screened as a name, strict; lei, or registration_number (the ID at the registration authority), each looked up as a non-document identifier."
              },
              "value": {
                "type": "string",
                "description": "The value as GLEIF publishes it."
              },
              "nameType": {
                "type": "string",
                "description": "GLEIF's type for an other_name (e.g. TRADING_OR_OPERATING_NAME, AUTO_ASCII_TRANSLITERATED_LEGAL_NAME), or UNKNOWN for a name the mirror stored without one. Present on other_name only."
              }
            },
            "description": "One value of the entity the cross-reference screened.",
            "additionalProperties": false
          },
          "description": "What the cross-reference screened beyond the legal name and the LEI, which it always screens: every other and transliterated name, then the registration number when the entity publishes one (a not-available placeholder such as N/A is none) and a legal jurisdiction to match it by. Empty when there is nothing beyond those two."
        },
        "totalAvailable": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Distinct designations the cross-reference found across every screened name and identifier, an OFAC party both OFAC lists publish counted once, before the cap was applied."
        },
        "totalAvailableBasis": {
          "enum": [
            "exact",
            "lower_bound"
          ],
          "type": "string",
          "description": "How to read totalAvailable. Always exact here: every name is screened strict, never fuzzy, and a strict screen counts every designation it reaches, so totalAvailable is the whole set across the screened names and identifiers."
        }
      },
      "description": "Disclosure for the cross-reference: how many potential matches existed before the cap, whether sanctionsHits is the complete set, and what was screened. Present only when screeningStatus is 'screened'.",
      "additionalProperties": false
    },
    "screeningStatus": {
      "enum": [
        "screened",
        "not_ready"
      ],
      "type": "string",
      "description": "Whether the cross-reference ran: screened = the entity's names and identifiers were screened against every loaded watchlist; not_ready = the sanctions mirror has never synced, so no screening ran and the empty sanctionsHits says nothing about this entity. Read sanctionsHits only when this is 'screened'."
    },
    "headquartersAddress": {
      "type": "string",
      "description": "Single-line headquarters address, when published."
    },
    "registrationAuthorityId": {
      "type": "string",
      "description": "Registration authority (RA) code, when published."
    },
    "registrationAuthorityEntityId": {
      "type": "string",
      "description": "The entity's ID at its registration authority, when published."
    }
  },
  "additionalProperties": false
}
sanctions_get_entity annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
sanctions_trace_ownership — sanctions-screening-mcp-server: trace ownership
Advertised by the server during the last successful anonymous check.
Advertised read-only

Trace a paged GLEIF Level 2 ownership segment from a 20-character LEI (use sanctions_resolve_entity to obtain one). Direction both walks parents and children separately from the root, never sideways into siblings or co-parents; parents-side placement wins cycles. Ultimate-parent edges are shortcuts, never walked hops; ultimate-only nodes are flagged reachedVia: ultimate. Drain nextCursor with the same query, then re-root each boundary with its LEI, same-side direction and depth, including at depth five; deduplicate branch roots and edges across segments. Pages emit nodes, then edges, then boundaries, up to limit records (50 default, 100 maximum), stopping after an intact record reaches the soft 64-KiB target. Edges reference nodes across assembled pages. Cursors bind query and topology; changed topology requires restarting without a cursor. Entity and screening values read current mirrors, not an immutable snapshot. Set screenNodes to cross-reference only this page of nodes as sanctions_get_entity does: legal, other and transliterated names strict (exact then all tokens present, never fuzzy), LEI and country-matched registration number as exact non-document identifiers, with merged designation hits and matchedOn inputs. A node missing Level 1 is screened by LEI alone. Every hit is a candidate to verify; no hit is a clearance. Each eligible node retains direct and ultimate parentStatus: relationship, reporting exception and its reasons, none, or unknown when exceptions are not loaded. Read hasMore and truncationReasons separately from segment-wide missingEntityCount and page-local missingEntityLeis, screening counts and per-node ten-hit cap disclosures. A screening aid, not a compliance determination; a finished segment never proves full beneficial ownership.

sanctions_trace_ownership input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "lei"
  ],
  "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."
    },
    "depth": {
      "type": "integer",
      "default": 3,
      "maximum": 5,
      "minimum": 1,
      "description": "Maximum traversal depth from the root entity (1–5), on each side of a both walk. Ultimate-parent edges do not count as hops."
    },
    "limit": {
      "type": "integer",
      "default": 50,
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Maximum records across nodes, edges and boundaries per page (default 50, requests above 100 clamp with notice)."
    },
    "cursor": {
      "type": "string",
      "description": "nextCursor from the preceding page, with the same query parameters. Omit to start a new segment."
    },
    "direction": {
      "enum": [
        "parents",
        "children",
        "both"
      ],
      "type": "string",
      "default": "both",
      "description": "Walk parents (who owns it), children (what it owns), or both (default): a parents walk plus a children walk from the root, each to depth, never into siblings or co-parents."
    },
    "screenNodes": {
      "type": "boolean",
      "default": false,
      "description": "When true, cross-reference every returned node on this page against all watchlists: legal, other and transliterated names strict, LEI and country-matched registration number as identifiers. A node missing Level 1 has only its LEI lookup. Edge/boundary-only pages screen zero nodes."
    }
  },
  "additionalProperties": false
}
sanctions_trace_ownership output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "rootLei",
        "nodes",
        "edges",
        "boundaries",
        "totalAvailable",
        "totalAvailableBasis",
        "hasMore",
        "truncationReasons",
        "missingEntityCount",
        "byteTargetExceeded",
        "complete",
        "truncated",
        "reportingExceptionsLoaded",
        "missingEntityLeis",
        "screeningStatus",
        "screenedNodeCount",
        "flaggedNodeCount",
        "caveat"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "edges": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "childLei",
          "parentLei",
          "relationshipType"
        ],
        "properties": {
          "childLei": {
            "type": "string",
            "description": "LEI of the owned (child) entity."
          },
          "parentLei": {
            "type": "string",
            "description": "LEI of the owning (parent) entity."
          },
          "relationshipType": {
            "type": "string",
            "description": "GLEIF relationship type (e.g. IS_DIRECTLY_CONSOLIDATED_BY)."
          },
          "relationshipStatus": {
            "type": "string",
            "description": "Relationship status, when published."
          }
        },
        "description": "One directed ownership edge (child is consolidated by parent).",
        "additionalProperties": false
      },
      "description": "This page of directed edges. Endpoints refer to nodes in the assembled segment across pages, not necessarily this page."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "invalid_cursor",
                "stale_cursor",
                "lei_not_found",
                "invalid_lei_checksum",
                "mirror_not_ready"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `invalid_cursor`: The cursor is corrupt, outside the stream, or belongs to different query parameters. `stale_cursor`: The recomputed segment topology differs from the cursor topology. `lei_not_found`: No GLEIF entity in the mirror carries the root LEI, and its check digits are valid. `invalid_lei_checksum`: No GLEIF entity in the mirror carries the root LEI, and its ISO 17442 check digits fail. `mirror_not_ready`: The GLEIF (LEI) mirror has never completed an initial sync. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "nodes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "lei",
          "legalName",
          "depth",
          "role"
        ],
        "properties": {
          "lei": {
            "type": "string",
            "description": "The node's LEI."
          },
          "role": {
            "enum": [
              "root",
              "parent",
              "child"
            ],
            "type": "string",
            "description": "root = the traced entity; parent = an ancestor, reached by walking parents; child = a descendant, reached by walking children. On a both walk, the side that reached the node — siblings and co-parents are never walked."
          },
          "depth": {
            "type": "number",
            "description": "Breadth-first depth from the root (root = 0), counted over every relationship type except IS_ULTIMATELY_CONSOLIDATED_BY. On a node flagged reachedVia: ultimate it counts that one ultimate hop instead, so it can be shallower than the direct chain to the node."
          },
          "status": {
            "type": "string",
            "description": "GLEIF registration status, when known."
          },
          "legalName": {
            "type": "string",
            "description": "The node's legal name (the LEI itself if not hydrated)."
          },
          "reachedVia": {
            "enum": [
              "ultimate"
            ],
            "type": "string",
            "description": "Present (ultimate) when only an IS_ULTIMATELY_CONSOLIDATED_BY edge reaches this node within the depth. That edge is a shortcut to the top of the group, not a hop, so the node is a leaf: its own parents (on the parents side) or children (on the children side) are never walked, and truncated is true when any of them is not in this graph. A higher depth places it by direct links only when a direct chain from the root reaches it; where that chain is broken (a parent reported by exception, or not at all), no depth does."
          },
          "jurisdiction": {
            "type": "string",
            "description": "Jurisdiction (ISO code), when known."
          },
          "parentStatus": {
            "type": "object",
            "required": [
              "direct",
              "ultimate"
            ],
            "properties": {
              "direct": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "enum": [
                      "relationship",
                      "exception",
                      "none",
                      "unknown"
                    ],
                    "type": "string",
                    "description": "relationship = a Level 2 relationship at this level is published — it is in edges when that parent is also a node of this graph (a flagged leaf's parents and a children-side node's other parents are read for this status, never walked); exception = the entity filed a GLEIF reporting exception instead of naming this parent; none = GLEIF publishes neither; unknown = no relationship is published and reporting exceptions are not loaded in the mirror, so whether one was filed is unknown."
                  },
                  "exceptionReasons": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Every reason given in the reporting exception (e.g. NATURAL_PERSONS, NON_CONSOLIDATING, NO_KNOWN_PERSON). Present only when status is exception."
                  }
                },
                "description": "What GLEIF publishes about the direct parent.",
                "additionalProperties": false
              },
              "ultimate": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "enum": [
                      "relationship",
                      "exception",
                      "none",
                      "unknown"
                    ],
                    "type": "string",
                    "description": "relationship = a Level 2 relationship at this level is published — it is in edges when that parent is also a node of this graph (a flagged leaf's parents and a children-side node's other parents are read for this status, never walked); exception = the entity filed a GLEIF reporting exception instead of naming this parent; none = GLEIF publishes neither; unknown = no relationship is published and reporting exceptions are not loaded in the mirror, so whether one was filed is unknown."
                  },
                  "exceptionReasons": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Every reason given in the reporting exception (e.g. NATURAL_PERSONS, NON_CONSOLIDATING, NO_KNOWN_PERSON). Present only when status is exception."
                  }
                },
                "description": "What GLEIF publishes about the ultimate parent.",
                "additionalProperties": false
              }
            },
            "description": "What GLEIF publishes about this node's direct and ultimate accounting-consolidation parents. Present only on nodes whose parents the traversal read — every node short of the depth limit when direction is parents or both; absent on a children walk.",
            "additionalProperties": false
          },
          "sanctionsHits": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "source",
                "sourceLabel",
                "sourceEntryId",
                "sources",
                "primaryName",
                "matchedOn"
              ],
              "properties": {
                "score": {
                  "type": "number",
                  "description": "Never set by this cross-reference: only an approximate (fuzzy) match carries a raw Jaro-Winkler score, and the cross-reference screens strict."
                },
                "source": {
                  "enum": [
                    "ofac_sdn",
                    "ofac_consolidated",
                    "eu",
                    "uk",
                    "un",
                    "bis_el",
                    "bis_dpl",
                    "bis_uvl",
                    "bis_meu",
                    "state_dtc",
                    "state_acn"
                  ],
                  "type": "string",
                  "description": "Watchlist whose record this hit is attributed to: primaryName comes from it. For an OFAC party both OFAC lists publish, ofac_sdn unless the Consolidated record matched alone or better, and matchedName, matchedIdentifiers, and matchedOn cover what either record matched; sources names every list."
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "enum": [
                      "ofac_sdn",
                      "ofac_consolidated",
                      "eu",
                      "uk",
                      "un",
                      "bis_el",
                      "bis_dpl",
                      "bis_uvl",
                      "bis_meu",
                      "state_dtc",
                      "state_acn"
                    ],
                    "type": "string"
                  },
                  "description": "Every screened list this candidate is on, in list order: one list, or ofac_sdn and ofac_consolidated together for an OFAC party both OFAC lists publish under one entry ID — one hit, not two. Read this, not source, for every list; the entry ID resolves in sanctions_get_designation under each."
                },
                "matchType": {
                  "enum": [
                    "exact",
                    "strong",
                    "approximate"
                  ],
                  "type": "string",
                  "description": "Match classification of matchedName: exact or strong, never approximate (the cross-reference screens strict, never fuzzy). Absent when only an identifier produced the hit."
                },
                "matchedOn": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "input",
                      "value"
                    ],
                    "properties": {
                      "input": {
                        "enum": [
                          "legal_name",
                          "other_name",
                          "lei",
                          "registration_number"
                        ],
                        "type": "string",
                        "description": "Which value: legal_name, or other_name (an other or transliterated name), each screened as a name, strict; lei, or registration_number (the ID at the registration authority), each looked up as a non-document identifier."
                      },
                      "value": {
                        "type": "string",
                        "description": "The value as GLEIF publishes it."
                      },
                      "nameType": {
                        "type": "string",
                        "description": "GLEIF's type for an other_name (e.g. TRADING_OR_OPERATING_NAME, AUTO_ASCII_TRANSLITERATED_LEGAL_NAME), or UNKNOWN for a name the mirror stored without one. Present on other_name only."
                      }
                    },
                    "description": "One value of the entity the cross-reference screened.",
                    "additionalProperties": false
                  },
                  "description": "Every input of this node that produced the hit — its legal name, an other or transliterated name, its LEI, or its registration number — in screening order. Only its LEI on a node in missingEntityLeis."
                },
                "matchedName": {
                  "type": "string",
                  "description": "The designation's name or alias that matched one of this node's screened names — the strongest match. Absent when only an identifier produced the hit."
                },
                "primaryName": {
                  "type": "string",
                  "description": "Primary published name of the designation."
                },
                "sourceLabel": {
                  "type": "string",
                  "description": "Human-readable source list name."
                },
                "sourceEntryId": {
                  "type": "string",
                  "description": "Source entry ID — pass to sanctions_get_designation."
                },
                "matchedIdentifiers": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "type",
                      "value"
                    ],
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "Identifier label as the list publishes it (e.g. Legal Entity Number, Registration Number)."
                      },
                      "value": {
                        "type": "string",
                        "description": "The identifier value, as published."
                      },
                      "country": {
                        "type": "string",
                        "description": "Issuing country as published, when published."
                      }
                    },
                    "description": "An identifier the designation publishes that equals the entity's LEI, or its registration number published for the country of its legal jurisdiction.",
                    "additionalProperties": false
                  },
                  "description": "Every identifier the designation publishes that equals this node's LEI or its country-matched registration number, as published. Present only when an identifier produced the hit."
                }
              },
              "description": "A potential watchlist match on this node — verify, do not assume.",
              "additionalProperties": false
            },
            "description": "Per-node cross-reference results, one hit per designation (an OFAC party both OFAC lists publish once) — exact name and identifier matches first, then strong name matches. Present only when screenNodes is true."
          },
          "sanctionsScreen": {
            "type": "object",
            "required": [
              "totalAvailable",
              "totalAvailableBasis",
              "hasMore",
              "screenedInputs"
            ],
            "properties": {
              "hasMore": {
                "type": "boolean",
                "description": "True when this node's potential matches were capped — re-screen its names with sanctions_screen_name and look up its LEI and registration number with sanctions_screen_identifier to see the rest. A node in missingEntityLeis has no names: look up its LEI."
              },
              "screenedInputs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "input",
                    "value"
                  ],
                  "properties": {
                    "input": {
                      "enum": [
                        "legal_name",
                        "other_name",
                        "lei",
                        "registration_number"
                      ],
                      "type": "string",
                      "description": "Which value: legal_name, or other_name (an other or transliterated name), each screened as a name, strict; lei, or registration_number (the ID at the registration authority), each looked up as a non-document identifier."
                    },
                    "value": {
                      "type": "string",
                      "description": "The value as GLEIF publishes it."
                    },
                    "nameType": {
                      "type": "string",
                      "description": "GLEIF's type for an other_name (e.g. TRADING_OR_OPERATING_NAME, AUTO_ASCII_TRANSLITERATED_LEGAL_NAME), or UNKNOWN for a name the mirror stored without one. Present on other_name only."
                    }
                  },
                  "description": "One value of the entity the cross-reference screened.",
                  "additionalProperties": false
                },
                "description": "What the cross-reference screened beyond the legal name and the LEI, which it screens on every node with a Level 1 record: every other and transliterated name, then the registration number when the node publishes one (a not-available placeholder such as N/A is none) and a legal jurisdiction to match it by. Empty when there is nothing beyond those two, and always on a node in missingEntityLeis, which has no name and is looked up by its LEI alone."
              },
              "totalAvailable": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Distinct designations this node's cross-reference found across every screened name and identifier, an OFAC party both OFAC lists publish counted once, before the per-node cap was applied."
              },
              "totalAvailableBasis": {
                "enum": [
                  "exact",
                  "lower_bound"
                ],
                "type": "string",
                "description": "How to read totalAvailable. Always exact here: every name is screened strict, never fuzzy, and a strict screen counts every designation it reaches, so totalAvailable is the whole set across this node's screened names and identifiers."
              }
            },
            "description": "Disclosure for this node's cross-reference: how many potential matches existed before the per-node cap, whether sanctionsHits is the complete set, and what was screened. Present only when the node was screened.",
            "additionalProperties": false
          }
        },
        "description": "One entity in the ownership graph.",
        "additionalProperties": false
      },
      "description": "This page of entities, ordered by depth then LEI. The root appears once, on the initial page."
    },
    "caveat": {
      "type": "string",
      "description": "Decision-support caveat — node screening is an aid, not a determination."
    },
    "notice": {
      "type": "string",
      "description": "Input normalization notice when limit was clamped."
    },
    "hasMore": {
      "type": "boolean",
      "description": "More records remain in this segment; false does not imply complete ownership."
    },
    "rootLei": {
      "type": "string",
      "description": "The LEI the traversal started from."
    },
    "complete": {
      "type": "boolean",
      "description": "True only on the last page when no depth or ultimate-leaf boundary remains and every node in the entire segment has a Level 1 record (missingEntityCount is zero). It does not say every parent is known: read each node's parentStatus. A finished segment is never proof of full beneficial ownership."
    },
    "truncated": {
      "type": "boolean",
      "description": "True while this segment has more pages or has omitted depth-limit or ultimate-leaf branches; read truncationReasons. Drain nextCursor pages, then trace each boundary with its LEI, same-side direction and depth, including at depth five. An ultimate edge counts as a boundary only when its far node is absent. Siblings and co-parents are never walked and never count."
    },
    "boundaries": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "lei",
          "direction",
          "reason",
          "depth"
        ],
        "properties": {
          "lei": {
            "type": "string",
            "description": "Re-root this LEI to retrieve the omitted branch."
          },
          "depth": {
            "type": "integer",
            "maximum": 5,
            "minimum": 1,
            "description": "Depth to pass to the new trace; its root restarts at depth zero."
          },
          "reason": {
            "enum": [
              "depth_limit",
              "ultimate_leaf"
            ],
            "type": "string",
            "description": "Why the original segment stopped this branch."
          },
          "direction": {
            "enum": [
              "parents",
              "children"
            ],
            "type": "string",
            "description": "Walk only this side in the new segment."
          }
        },
        "description": "One omitted same-side branch, with executable inputs for a new trace segment.",
        "additionalProperties": false
      },
      "description": "This page of omitted branch roots; trace each LEI with its direction and depth after draining this segment."
    },
    "nextCursor": {
      "type": "string",
      "description": "Continue this segment with the same query and this cursor; absent on its last page."
    },
    "totalAvailable": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Exact number of stream records in this segment: nodes plus edges plus boundaries."
    },
    "screeningStatus": {
      "enum": [
        "screened",
        "not_requested",
        "not_ready"
      ],
      "type": "string",
      "description": "Screening status for this page: screened = every returned node was screened (an edge-only page screens zero nodes); not_requested = screenNodes was false; not_ready = screening was requested but the sanctions mirror has never synced, so NO node was screened and an absence of hits says nothing about any node."
    },
    "flaggedNodeCount": {
      "type": "number",
      "description": "How many screened nodes on this page had at least one potential watchlist match."
    },
    "missingEntityLeis": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "This page of nodes absent from Level 1; missingEntityCount covers the whole segment. Their nodes carry the LEI in place of a legal name and no jurisdiction/status — never read that LEI as a legal name. A per-node screen is the LEI looked up as an identifier, nothing else: screenedInputs is empty and every hit is matchedOn their lei."
    },
    "screenedNodeCount": {
      "type": "number",
      "description": "How many nodes on this page were screened (zero on edge/boundary-only pages)."
    },
    "truncationReasons": {
      "type": "array",
      "items": {
        "enum": [
          "page_limit",
          "depth_limit",
          "ultimate_leaf"
        ],
        "type": "string"
      },
      "description": "Independent reasons the current response is partial: remaining pages or omitted branches."
    },
    "byteTargetExceeded": {
      "type": "boolean",
      "description": "Serialized structuredContent plus content exceeds the soft 64-KiB target; indivisible records are retained intact."
    },
    "missingEntityCount": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Number of nodes absent from Level 1 across the entire segment, including earlier and later pages."
    },
    "totalAvailableBasis": {
      "type": "string",
      "const": "exact",
      "description": "The entire segment topology was enumerated to count its records."
    },
    "reportingExceptionsLoaded": {
      "type": "boolean",
      "description": "Whether GLEIF reporting exceptions are loaded in the mirror. When false, a node's parent level with no published relationship reads unknown rather than exception or none."
    }
  },
  "additionalProperties": false
}
sanctions_trace_ownership annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}

Prompts

1 advertised

sanctions_vet_counterparty — sanctions-screening-mcp-server: vet counterparty

Advertised by the server during the last successful anonymous check.

Structure a full counterparty due-diligence pass: resolve the name to an LEI, pull its GLEIF ownership graph, screen the named entity and every parent and subsidiary in that graph against all sanctions lists, and summarize hits with provenance and the decision-support caveat.

name
The counterparty name to vet (person or organization). (required)
jurisdiction
Optional jurisdiction to disambiguate the entity: an ISO 3166-1 alpha-2 country code, which also matches every subdivision under it ("US" matches US-DE and US-CA), or an ISO 3166-2 subdivision code ("US-DE").

Resources

2 advertised

sanctions-screening-mcp-server: sources — sanctions-screening-mcp-server: sources

Advertised by the server during the last successful anonymous check.

List the sanctions watchlists and GLEIF datasets loaded in the local mirror, each with its record count, source URL, and license, plus each mirror's readiness and as-of timestamp, the GLEIF Level 2 relationship count, whether GLEIF reporting exceptions are loaded and how many, and whether the GLEIF alternate-name index is built — the sanctions_list_sources payload, unchanged, as a read-only URI.

sanctions-screening-mcp-server: sources URI
sanctions://sources

MIME type: application/json

sanctions-screening-guide

Advertised by the server during the last successful anonymous check.

Investigate ambiguous counterparties with sanctions_* tools, recover incomplete ownership and screening results, and compare designation evidence without inventing identity or coverage. Use for counterparty due diligence, ownership-chain screening, or reviewing a possible sanctions or export-control match.

sanctions-screening-guide URI
skill://sanctions-screening-guide/SKILL.md

MIME type: text/markdown

sanctions-screening-mcp-server: designation — sanctions-screening-mcp-server: designation

Advertised by the server during the last successful anonymous check.

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

sanctions-screening-mcp-server: designation URI template
sanctions://designation/{source}/{entryId}

MIME type: application/json

sanctions-screening-mcp-server: entity — sanctions-screening-mcp-server: entity

Advertised by the server during the last successful anonymous check.

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.

sanctions-screening-mcp-server: entity URI template
sanctions://entity/{lei}

MIME type: application/json

io.modelcontextprotocol/skills

Advertised by the server during the last successful anonymous check.

io.modelcontextprotocol/skills URI template
skill://{+path}

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
593 ms
95th percentile latency
593 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 593 ms · metadata changed · 7 tool(s), 2 resource(s), 3 resource template(s), 1 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http sanctions-screening-mcp-server https://sanctions-screening.caseyjhand.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add sanctions-screening-mcp-server --url https://sanctions-screening.caseyjhand.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable sanctions-screening-mcp-server in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "sanctions-screening-mcp-server": {
      "url": "https://sanctions-screening.caseyjhand.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "sanctions-screening-mcp-server": {
      "type": "streamableHttp",
      "url": "https://sanctions-screening.caseyjhand.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start sanctions-screening-mcp-server and inspect its tools.
VS Code configuration
{
  "servers": {
    "sanctions-screening-mcp-server": {
      "type": "http",
      "url": "https://sanctions-screening.caseyjhand.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http sanctions-screening-mcp-server https://sanctions-screening.caseyjhand.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://sanctions-screening.caseyjhand.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "sanctions-screening-mcp-server": {
      "serverUrl": "https://sanctions-screening.caseyjhand.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like sanctions-screening-mcp-server from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.