sanctions-screening-mcp-server
Server Details
Screen names against OFAC, EU, UK, UN sanctions lists; resolve entities via GLEIF. Screening aid.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- cyanheads/sanctions-screening-mcp-server
- GitHub Stars
- 1
- Server Listing
- @cyanheads/sanctions-screening-mcp-server
Available Tools
6 toolssanctions_get_designationsanctions-screening-mcp-server: get designationARead-onlyIdempotentInspect
Fetch the full record for one sanctions designation by source list + entry ID — the drill-in after sanctions_screen_name surfaces a candidate. Returns all published aliases, identifiers (passport/national-ID/tax), addresses, dates and places of birth, nationalities, sanctioning program, legal basis, and designation date. The record reflects exactly what the source published; missing fields mean the source omitted them. This is a screening aid — the designation record supports a compliance review, it is not itself a determination.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Which source list the entry belongs to. | |
| entryId | Yes | The source list's own entry ID (the sourceEntryId from sanctions_screen_name). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| caveat | No | Decision-support caveat — this is a screening aid, not a compliance determination. |
| source | No | Source list the entry belongs to. |
| aliases | No | All published aliases / name variants. |
| program | No | Sanctioning program / regime, when published. |
| remarks | No | Free-form remarks published by the source, when present. |
| addresses | No | Published addresses. |
| entityType | No | Entity classification as published. |
| legalBasis | No | Statutory / regulatory basis, when published. |
| identifiers | No | Published identifiers (passport, national ID, tax, registration, …). |
| primaryName | No | Primary published name. |
| sourceLabel | No | Human-readable name of the source list. |
| datesOfBirth | No | Published dates and places of birth (persons). |
| nationalities | No | Published nationalities / citizenships. |
| sourceEntryId | No | The source list's own entry ID. |
| designationDate | No | Designation date, when published. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is clear. The description adds valuable context about data fidelity ('The record reflects exactly what the source published; missing fields mean the source omitted them') and the tool's non-determinative nature. These go beyond the annotations and clarify potential pitfalls, though some nuance like pagination or error handling is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a compact three-sentence block with the purpose front-loaded, followed by return contents and a behavioral warning. Every sentence earns its place; there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return format details are covered there. The description covers the workflow trigger, what fields are returned, data fidelity expectations, and the tool's role as a screening aid. For a two-parameter read-only fetch, this is fully adequate; nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are documented in the schema. The description adds a key pointer: entryId is 'the sourceEntryId from sanctions_screen_name,' which establishes the expected provenance and reduces misuse risk. This is meaningful added value over the schema alone, but does not fully elaborate on edge cases like invalid source values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'fetch' and the resource 'full record for one sanctions designation by source list + entry ID', immediately distinguishing it from the screening tool it complements. It also explicitly positions it as the drill-in after sanctions_screen_name, which differentiates it from siblings like sanctions_get_entity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the preceding step ('the drill-in after sanctions_screen_name surfaces a candidate') and the alternative workflow, making the usage context unambiguous. It also adds a critical boundary: 'it is not itself a determination,' guiding the agent on when to rely on this tool vs. making a final compliance decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sanctions_get_entitysanctions-screening-mcp-server: get entityARead-onlyIdempotentInspect
Fetch the full GLEIF Level 1 record for one LEI: legal name, other/trading names, legal and headquarters addresses, registration status, jurisdiction, registration authority and ID, and last-update date — plus any sanctions hits screened against the same legal name across all loaded watchlists. The screening cross-reference is a screening AID: a hit is a candidate to verify against the official source, and no hit is not a clearance. 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).
| Name | Required | Description | Default |
|---|---|---|---|
| lei | Yes | The 20-character GLEIF Legal Entity Identifier to look up. |
Output Schema
| Name | Required | Description |
|---|---|---|
| lei | No | The 20-character GLEIF Legal Entity Identifier. |
| error | No | Present when the call failed. Absent on success. |
| caveat | No | Decision-support caveat — the screening cross-reference is an aid, not a determination. |
| status | No | Registration status (e.g. ISSUED, LAPSED). |
| legalName | No | Registered legal name. |
| lastUpdate | No | ISO 8601 last-update timestamp from the LEI record. |
| otherNames | No | Other / trading names published in the LEI record. |
| jurisdiction | No | Legal jurisdiction (ISO code), when published. |
| legalAddress | No | Single-line legal address, when published. |
| sanctionsHits | No | Sanctions screening cross-reference on the entity's legal name. |
| sanctionsScreen | No | Disclosure for the cross-reference screen: how many potential matches existed before the cap, and whether sanctionsHits is the complete set. Present only when screeningStatus is 'screened'. |
| screeningStatus | No | Whether the cross-reference ran: screened = the legal name was 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 | No | Single-line headquarters address, when published. |
| registrationAuthorityId | No | Registration authority (RA) code, when published. |
| registrationAuthorityEntityId | No | The entity's ID at its registration authority, when published. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint and idempotentHint annotations by explaining the screening semantics: hits are candidates, no hit is not clearance, screeningStatus indicates whether the cross-reference ran, and sanctionsScreen distinguishes capped from complete results. It also clarifies that empty sanctionsHits under not_ready means mirror unavailability. This is rich, non-obvious behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though relatively long, every sentence earns its place: the main fetch is stated first, followed by necessary caveats about screening reliability and cap behavior. There is zero filler and the structure front-loads the primary purpose before diving into nuances.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single required parameter, a fully described input schema, and an output schema, the description covers all essential operational details. It explains edge cases (mirror unavailable, capped results) that affect interpretation, leaving no ambiguity for an agent deciding how to call and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with the pattern and description already in the input schema. The description adds a minor clarification of LEI format (18 alphanumerics + 2 check digits) which is redundant with the pattern. The added value over the schema is minimal, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Fetch the full GLEIF Level 1 record for one LEI' and enumerates the exact fields (legal name, addresses, registration status, etc.), making the verb and resource unambiguous. It differentiates itself from sibling tools like sanctions_get_designation (designations) and sanctions_screen_name (name-based screening) by centering on a single LEI lookup plus screening.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies usage when an LEI is available and a full record with screening is needed, but it does not explicitly state when not to use it or name alternatives for name-based lookups (e.g., sanctions_resolve_entity, sanctions_screen_name). The context is clear enough for an agent to infer, though explicit exclusions are missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sanctions_list_sourcessanctions-screening-mcp-server: list sourcesARead-onlyIdempotentInspect
List the sanctions watchlists (OFAC SDN + Consolidated, EU, UK, UN) and GLEIF datasets currently loaded in the local mirror, each with its record count, source URL, license, and the mirror's readiness and as-of timestamp. Use this for provenance and freshness on any result — results are only as current as the last mirror refresh, and a not-ready mirror means screening cannot run yet. Attribution: UK data is under the Open Government Licence v3.0; all sources are cited here.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| leiAsOf | No | ISO 8601 timestamp of the last completed GLEIF sync, when available. |
| sources | No | All loaded sources, sanctions lists then the GLEIF dataset. |
| leiReady | No | True once the GLEIF (LEI) mirror has completed at least one full sync. |
| sanctionsAsOf | No | ISO 8601 timestamp of the last completed sanctions sync, when available. |
| sanctionsReady | No | True once the sanctions mirror has completed at least one full sync. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description adds meaningful behavioral context: it discloses the tool's dependence on mirror freshness and readiness, and states that screening cannot run on a not-ready mirror. It also reveals the data provenance (URLs and licenses), which is not covered by annotations. No contradiction with annotations, but the freshness caveat is the main added behavioral insight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a compact two-sentence block (plus an attribution sentence) with zero fluff. The purpose is front-loaded in the first sentence, usage guidance in the second, and licensing attribution appended at the end. Every sentence earns its place, and the structure leads with the most critical information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless tool with an output schema and read-only/idempotent annotations, the description fully covers what an agent needs: it lists the data sources, the fields returned, the readiness/freshness caveat, and licensing. The output schema handles return format details, so the description is complete for safe and correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool accepts no parameters (input schema is empty), so there are no parameter semantics to explain. Per the rubric, a baseline of 4 is appropriate; the description correctly omits parameter details because none exist. Nothing more could be added.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (list) and resource (sanctions watchlists and GLEIF datasets), enumerates the exact datasets (OFAC SDN + Consolidated, EU, UK, UN) and the fields returned (record count, source URL, license, readiness, as-of timestamp). It clearly distinguishes itself from sibling tools that perform entity lookups, screening, or tracing, leaving no ambiguity about its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly directs agents to use this tool 'for provenance and freshness on any result' and explains the practical implication that 'results are only as current as the last mirror refresh' and 'a not-ready mirror means screening cannot run yet.' This gives clear when-to-use context and implies this should be checked before relying on screening results, while implicitly contrasting with the operational sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sanctions_resolve_entitysanctions-screening-mcp-server: resolve entityARead-onlyIdempotentInspect
Resolve a company or organization name (with an optional ISO 3166-1 alpha-2 jurisdiction) to candidate GLEIF Legal Entity Identifiers (LEIs), ranked. This turns a free-text counterparty name into a stable global identifier that sanctions_get_entity and sanctions_trace_ownership key off. Strict mode (default) matches exact-normalized then all-tokens-present; fuzzy mode (or auto when strict is empty) adds Jaro-Winkler scoring labeled approximate with a raw 0–1 score 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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The company / organization name to resolve to an LEI. | |
| limit | No | Maximum LEI candidates to return in one page. | |
| offset | No | 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 | No | Registration status filter: issued (default), lapsed, or any. | issued |
| minScore | No | Jaro-Winkler floor for fuzzy hits (0–1); defaults to the server's configured floor. | |
| matchMode | No | strict (default): exact then all-tokens-present. fuzzy: also scored Jaro-Winkler. | strict |
| jurisdiction | No | Optional ISO 3166-1 alpha-2 jurisdiction filter (e.g. "US", "GB"). Empty string disables it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance when no LEI matched and how to broaden, or when the requested offset sits past the end of the result set. |
| hasMore | No | True when LEI candidates remain beyond this page — re-call with nextOffset. |
| matches | No | LEI candidates, ranked by match type, then score, then how much of the query each matched name explains. |
| nextOffset | No | The offset to request next. Present only when hasMore is true. |
| totalCount | No | Number of LEI candidates returned in this page. |
| matchModeUsed | No | The match mode actually applied (strict may upgrade to fuzzy). |
| totalAvailable | No | LEI candidates available across all pages, before limit and offset were applied. |
| normalizedQuery | No | The name as the server folded it for matching. |
| totalAvailableBasis | No | How to read totalAvailable: exact = the complete strict candidate set; lower_bound = a bounded scan produced it (every fuzzy pass, and any strict pass that hit the raw-row scan cap), so more may exist. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered; the description adds substantial behavioral context beyond this: match-mode mechanics (exact-normalized → all-tokens-present → Jaro-Winkler), the raw 0–1 score semantics and token-coverage ordering, paging behavior via totalAvailable/hasMore/nextOffset, and the critical caveat that results are candidates to confirm rather than authoritative. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
At roughly 120 words it is long, but every sentence earns its place for a 7-parameter tool with multiple matching modes and paging. The core purpose is front-loaded in the opening sentence, and the matching-mode detail, paging mechanics, and confirmation caveat each carry distinct information. Slightly dense, but justified by complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, 7-param tool with an output schema, the description is remarkably complete: it covers purpose, both match modes plus the auto fallback, scoring semantics, paging, and the non-authoritative nature of results. Since an output schema exists, return-value documentation is already handled. The only minor absence is explicit guidance on when to prefer this over sanctions_screen_name, which does not meaningfully detract.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine value on top: it defines the 'auto' behavior not present as an enum value in the schema ('fuzzy mode (or auto when strict is empty)'), clarifies what minScore means ('Jaro-Winkler floor for fuzzy hits'), explains the matchMode semantics beyond the enum labels, and ties offset to the returned nextOffset/hasMore paging contract.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Resolve'), resource (company/organization name), and output (candidate GLEIF LEIs), plus an optional jurisdiction qualifier. It also positions itself relative to siblings by naming sanctions_get_entity and sanctions_trace_ownership as the consumers of its output, and its candidacy caveat ('name resolution is a candidate ranking, not an authoritative identification') clearly distinguishes it from look-up tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context: this is the resolution step that produces the stable identifiers get_entity and trace_ownership key off, and it warns results must be confirmed, not trusted. It explains strict vs fuzzy mode behavior including the 'auto when strict is empty' fallback. It does not, however, give explicit exclusions versus siblings like sanctions_screen_name, so an agent must infer when resolution rather than screening is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sanctions_screen_namesanctions-screening-mcp-server: screen nameARead-onlyIdempotentInspect
Screen a name (person, company, vessel, aircraft) against all loaded sanctions watchlists at once — OFAC SDN + Consolidated, EU, UK, and UN — alias- and fuzzy-aware. Returns scored potential matches with the source list, sanctioning program, designation date, and the matched alias. Strict mode (default) matches exact-normalized then all-tokens-present; fuzzy mode (or auto when strict is empty) adds Jaro-Winkler and phonetic matching and labels hits approximate with a raw 0–1 similarity score plus the count of query tokens the candidate covers, which orders candidates that tie on score. 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."
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name to screen (person, organization, vessel, or aircraft). | |
| limit | No | Maximum number of potential matches to return in one page. | |
| offset | No | 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 | No | Restrict to specific source lists. Omit to screen all loaded lists. | |
| minScore | No | Score floor for fuzzy hits (0–1), applied uniformly to every fuzzy candidate regardless of how it was matched (Jaro-Winkler, token, or phonetic). No hit below this score is returned. Applies to fuzzy mode only; defaults to the server's configured floor. | |
| matchMode | No | strict (default): exact-normalized then all-tokens-present. fuzzy: also scored Jaro-Winkler + phonetic. Strict auto-falls-back to fuzzy when it finds nothing. | strict |
| entityType | No | Restrict to one entity class, or "any" (default) to screen across all. | any |
Output Schema
| Name | Required | Description |
|---|---|---|
| hits | No | Potential matches, ranked by match type, then score, then how much of the query each candidate explains. |
| error | No | Present when the call failed. Absent on success. |
| caveat | No | Decision-support caveat — this is a screening aid, not a compliance determination. |
| notice | No | Guidance when no candidate matched — how to broaden, and what an empty result does NOT mean — or when the requested offset sits past the end of the result set. |
| hasMore | No | True when potential matches remain beyond this page — re-call with nextOffset. |
| nextOffset | No | The offset to request next. Present only when hasMore is true. |
| totalCount | No | Number of potential matches returned in this page. |
| matchModeUsed | No | The match mode actually applied (strict may auto-upgrade to fuzzy on empty). |
| totalAvailable | No | Potential matches available across all pages, before limit and offset were applied. |
| normalizedQuery | No | The name as the server folded it for matching. |
| totalAvailableBasis | No | How to read totalAvailable: exact = the complete strict match set; lower_bound = a bounded scan produced it (every fuzzy pass, and any strict pass that hit the raw-row scan cap), so more may exist. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=false, idempotentHint=true, but the description goes far beyond. It discloses the automatic fallback from strict to fuzzy, the scoring mechanism (Jaro-Winkler, phonetic), the label 'approximate' with raw scores, pagination behavior (totalAvailable, hasMore, nextOffset), and the critical caveat that an empty result does not mean 'cleared'. This is substantial behavioral context that an agent needs to interpret results correctly, and it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than minimal but deliberately packed with necessary detail. It is front-loaded with the core purpose and immediately states the output. Each sentence contributes: mode mechanics, pagination, and the essential compliance caveat. No fluff, and the structure progresses logically from function to modes to pagination to disclaimer.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (7 parameters, two modes, pagination, scoring), the description covers all critical aspects: input types, source restrictions, entity type filtering, score floors, match mode behavior, pagination instructions, and result interpretation. An output schema exists to describe return structure, so the description does not need to repeat that. An agent has enough information to call this tool correctly and understand its results, including the important 'not cleared' caveat.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all parameters described in JSON Schema), so the baseline is 3. The description adds meaningful semantics: it explains the strict mode's exact-normalized and all-tokens-present logic, the fuzzy mode's scoring and approximation labeling, the behavior of minScore (fuzzy only), and the pagination semantics of offset/nextOffset. These details enhance understanding beyond the raw schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Screen a name (person, company, vessel, aircraft) against all loaded sanctions watchlists at once.' It names the exact lists (OFAC SDN + Consolidated, EU, UK, UN) and the output (scored potential matches). This clearly differentiates it from the sibling tools, which focus on getting designations, entities, sources, resolving, or tracing ownership.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool: for screening names across multiple watchlists with fuzzy and strict matching, and it provides context on the strict/fuzzy modes and automatic fallback. It also gives important guidance on interpretation ('screening AID', not a compliance determination). It does not explicitly name alternative sibling tools but the context of screening is distinct from the getter/resolver siblings, making usage clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sanctions_trace_ownershipsanctions-screening-mcp-server: trace ownershipARead-onlyIdempotentInspect
Trace the GLEIF Level 2 corporate-ownership graph for an LEI: direct and ultimate parents and/or children, traversed breadth-first to a bounded depth, with relationship type for each edge. Set screenNodes to also screen every entity in the graph against all loaded watchlists — beneficial-ownership screening that resolves "is anyone in this ownership chain sanctioned." Each per-node screen is a screening AID: hits are candidates to verify, and an empty result for a node is not a clearance of that node. The response says what it could not do: complete/truncated/missingEntityLeis report whether the graph is the full known picture, screeningStatus reports whether the cross-reference actually ran, and each screened node reports whether its own hit list was capped. Requires a valid 20-character LEI (use sanctions_resolve_entity to obtain one).
| Name | Required | Description | Default |
|---|---|---|---|
| lei | Yes | The 20-character GLEIF LEI at the root of the ownership graph. | |
| depth | No | Maximum traversal depth from the root entity (1–5). | |
| direction | No | Walk parents (who owns it), children (what it owns), or both (default). | both |
| screenNodes | No | When true, screen every node's legal name against all watchlists for beneficial-ownership screening. |
Output Schema
| Name | Required | Description |
|---|---|---|
| edges | No | Directed ownership edges between the nodes. |
| error | No | Present when the call failed. Absent on success. |
| nodes | No | All entities reached in the traversal, including the root. |
| caveat | No | Decision-support caveat — node screening is an aid, not a determination. |
| rootLei | No | The LEI the traversal started from. |
| complete | No | True only when this is the full known ownership picture: nothing was cut off by the requested depth AND every node resolved to a GLEIF Level 1 record. False means the graph below is a partial view — read truncated and missingEntityLeis for which. |
| truncated | No | True when further ownership relationships exist beyond the requested depth — re-run with a higher depth to see them. False means the traversal reached the edge of the loaded relationship corpus. |
| screeningStatus | No | Whether the per-node cross-reference ran: screened = every node was screened; not_requested = screenNodes was false; not_ready = screening was requested but the sanctions mirror has never synced, so NO node was screened and the absence of hits says nothing about any node. |
| flaggedNodeCount | No | How many screened nodes had at least one potential watchlist match. |
| missingEntityLeis | No | LEIs published in the relationship corpus but absent from the GLEIF Level 1 entity mirror. Their nodes carry the LEI in place of a legal name and no jurisdiction/status — never read that LEI as a legal name, and note any per-node screen for them ran against the LEI string. |
| screenedNodeCount | No | How many nodes were screened (0 when screenNodes is false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations (readOnlyHint, idempotentHint, openWorldHint) by explaining the incomplete-data semantics: it warns that 'complete/truncated/missingEntityLeis' report whether the graph is the full known picture, and 'screeningStatus' indicates whether the cross-reference actually ran. It also clarifies that an empty result for a node is not a clearance. These are critical behavioral caveats not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly long but each sentence carries significant meaning, covering the core purpose, screening behavior, response caveats, and LEI requirement. It is front-loaded with the primary action and then layers additional context. While not as terse as some descriptions, it avoids fluff and justifies its length with essential details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (graph traversal, depth/direction, optional screening) and the existence of an output schema (which covers return values), the description is remarkably complete. It covers traversal semantics, screening semantics, incomplete-graph reporting, and the prerequisite for a valid LEI. It also names the sibling tool for LEI resolution. Nothing critical for an agent to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage of all four parameters with descriptions. The description adds semantic depth beyond the schema, particularly for screenNodes: it explains that each node screen is a screening AID, hits are candidates to verify, and empty results are not clearances. It also clarifies the meaning of depth and direction in the context of the ownership graph. This adds value beyond the schema's basic parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: tracing the GLEIF Level 2 ownership graph for an LEI, including parents/children, depth, and relationship types. It distinguishes itself from siblings like sanctions_resolve_entity (which resolves LEIs) and sanctions_screen_name (which screens a single name) by focusing on graph traversal and optional beneficial-ownership screening. The verb 'trace' plus a specific resource makes the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the screening feature (screenNodes=true) and explicitly mentions using sanctions_resolve_entity to obtain a valid LEI, giving a dependency. However, it does not explicitly state when NOT to use this tool versus alternatives (e.g., using sanctions_screen_name for single-entity screening). The guidance is strong but not fully prescriptive about exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
- Changed
sanctions_get_designation6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "source", + "sourceLabel", + "sourceEntryId", + "entityType", + "primaryName", + "aliases", + "identifiers", + "addresses", + "datesOfBirth", + "nationalities", + "caveat" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `designation_not_found`: No designation exists for the given source + entry ID in the mirror. `mirror_not_ready`: The sanctions mirror has never completed an initial sync. Other values are possible when a failure originates below the handler.", + "examples": [ + "designation_not_found", + "mirror_not_ready" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "source", - "sourceLabel", - "sourceEntryId", - "entityType", - "primaryName", - "aliases", - "identifiers", - "addresses", - "datesOfBirth", - "nationalities", - "caveat" -]
- Changed
sanctions_get_entity6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "lei", + "legalName", + "otherNames", + "sanctionsHits", + "screeningStatus", + "caveat" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `lei_not_found`: No GLEIF entity exists for the given LEI in the mirror. `mirror_not_ready`: The GLEIF (LEI) mirror has never completed an initial sync. Other values are possible when a failure originates below the handler.", + "examples": [ + "lei_not_found", + "mirror_not_ready" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "lei", - "legalName", - "otherNames", - "sanctionsHits", - "screeningStatus", - "caveat" -]
- Changed
sanctions_list_sources6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "sanctionsReady", + "leiReady", + "sources" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode.", + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "sanctionsReady", - "leiReady", - "sources" -]
- Changed
sanctions_resolve_entity6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "matches", + "normalizedQuery", + "matchModeUsed", + "totalCount", + "totalAvailable", + "totalAvailableBasis", + "hasMore" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `mirror_not_ready`: The GLEIF (LEI) mirror has never completed an initial sync. Other values are possible when a failure originates below the handler.", + "examples": [ + "mirror_not_ready" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "matches", - "normalizedQuery", - "matchModeUsed", - "totalCount", - "totalAvailable", - "totalAvailableBasis", - "hasMore" -]
- Changed
sanctions_screen_name6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "hits", + "caveat", + "normalizedQuery", + "matchModeUsed", + "totalCount", + "totalAvailable", + "totalAvailableBasis", + "hasMore" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `mirror_not_ready`: The sanctions mirror has never completed an initial sync. Other values are possible when a failure originates below the handler.", + "examples": [ + "mirror_not_ready" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "hits", - "caveat", - "normalizedQuery", - "matchModeUsed", - "totalCount", - "totalAvailable", - "totalAvailableBasis", - "hasMore" -]
- Changed
sanctions_trace_ownership6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "rootLei", + "nodes", + "edges", + "complete", + "truncated", + "missingEntityLeis", + "screeningStatus", + "screenedNodeCount", + "flaggedNodeCount", + "caveat" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `lei_not_found`: No GLEIF entity exists for the root LEI in the mirror. `mirror_not_ready`: The GLEIF (LEI) mirror has never completed an initial sync. Other values are possible when a failure originates below the handler.", + "examples": [ + "lei_not_found", + "mirror_not_ready" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "rootLei", - "nodes", - "edges", - "complete", - "truncated", - "missingEntityLeis", - "screeningStatus", - "screenedNodeCount", - "flaggedNodeCount", - "caveat" -]
4 tool updates
- Changed
sanctions_get_entity3 fields changed- added
Output schema / properties / sanctionsScreenAdded value: +{ + "additionalProperties": false, + "description": "Disclosure for the cross-reference screen: how many potential matches existed before the cap, and whether sanctionsHits is the complete set. Present only when screeningStatus is 'screened'.", + "properties": { + "hasMore": { + "description": "True when the potential matches were capped — screen the legal name with sanctions_screen_name to page through the rest.", + "type": "boolean" + }, + "totalAvailable": { + "description": "Potential matches the cross-reference screen found before the cap was applied.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "totalAvailableBasis": { + "description": "How to read totalAvailable: exact = the complete strict match set for this legal name; lower_bound = a bounded scan produced it, so more may exist.", + "enum": [ + "exact", + "lower_bound" + ], + "type": "string" + } + }, + "required": [ + "totalAvailable", + "totalAvailableBasis", + "hasMore" + ], + "type": "object" +} - added
Output schema / properties / screeningStatusAdded value: +{ + "description": "Whether the cross-reference ran: screened = the legal name was 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'.", + "enum": [ + "screened", + "not_ready" + ], + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "lei", - "legalName", - "otherNames", - "sanctionsHits", - "caveat" -]New value: +[ + "lei", + "legalName", + "otherNames", + "sanctionsHits", + "screeningStatus", + "caveat" +]
- Changed
sanctions_resolve_entity11 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum LEI candidates to return."New value: +"Maximum LEI candidates to return in one page." - added
Input schema / properties / offsetAdded value: +{ + "default": 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.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Output schema / properties / hasMoreAdded value: +{ + "description": "True when LEI candidates remain beyond this page — re-call with nextOffset.", + "type": "boolean" +} - changed
Output schema / properties / matches / descriptionPrevious value: -"Ranked LEI candidates, highest-confidence first."New value: +"LEI candidates, ranked by match type, then score, then how much of the query each matched name explains." - added
Output schema / properties / matches / items / properties / queryTokenCoverageAdded value: +{ + "additionalProperties": false, + "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.", + "properties": { + "covered": { + "description": "Query tokens individually matched by one of the matched name's tokens at the applied score floor.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "total": { + "description": "Total tokens in the normalized query.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "covered", + "total" + ], + "type": "object" +} - added
Output schema / properties / nextOffsetAdded value: +{ + "description": "The offset to request next. Present only when hasMore is true.", + "type": "number" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when no LEI matched and how to broaden."New value: +"Guidance when no LEI matched and how to broaden, or when the requested offset sits past the end of the result set." - added
Output schema / properties / totalAvailableAdded value: +{ + "description": "LEI candidates available across all pages, before limit and offset were applied.", + "type": "number" +} - added
Output schema / properties / totalAvailableBasisAdded value: +{ + "description": "How to read totalAvailable: exact = the complete strict candidate set; lower_bound = a bounded scan produced it (every fuzzy pass, and any strict pass that hit the raw-row scan cap), so more may exist.", + "enum": [ + "exact", + "lower_bound" + ], + "type": "string" +} - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Number of LEI candidates returned."New value: +"Number of LEI candidates returned in this page." - changed
Output schema / requiredPrevious value: -[ - "matches", - "normalizedQuery", - "matchModeUsed", - "totalCount" -]New value: +[ + "matches", + "normalizedQuery", + "matchModeUsed", + "totalCount", + "totalAvailable", + "totalAvailableBasis", + "hasMore" +]
- Changed
sanctions_screen_name11 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of potential matches to return."New value: +"Maximum number of potential matches to return in one page." - added
Input schema / properties / offsetAdded value: +{ + "default": 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.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Output schema / properties / hasMoreAdded value: +{ + "description": "True when potential matches remain beyond this page — re-call with nextOffset.", + "type": "boolean" +} - changed
Output schema / properties / hits / descriptionPrevious value: -"Scored potential matches, highest-confidence first."New value: +"Potential matches, ranked by match type, then score, then how much of the query each candidate explains." - added
Output schema / properties / hits / items / properties / queryTokenCoverageAdded value: +{ + "additionalProperties": false, + "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.", + "properties": { + "covered": { + "description": "Query tokens individually matched by one of this candidate's tokens at the applied score floor.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "total": { + "description": "Total tokens in the normalized query.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "covered", + "total" + ], + "type": "object" +} - added
Output schema / properties / nextOffsetAdded value: +{ + "description": "The offset to request next. Present only when hasMore is true.", + "type": "number" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when no candidate matched — how to broaden, and what an empty result does NOT mean."New value: +"Guidance when no candidate matched — how to broaden, and what an empty result does NOT mean — or when the requested offset sits past the end of the result set." - added
Output schema / properties / totalAvailableAdded value: +{ + "description": "Potential matches available across all pages, before limit and offset were applied.", + "type": "number" +} - added
Output schema / properties / totalAvailableBasisAdded value: +{ + "description": "How to read totalAvailable: exact = the complete strict match set; lower_bound = a bounded scan produced it (every fuzzy pass, and any strict pass that hit the raw-row scan cap), so more may exist.", + "enum": [ + "exact", + "lower_bound" + ], + "type": "string" +} - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Number of potential matches returned."New value: +"Number of potential matches returned in this page." - changed
Output schema / requiredPrevious value: -[ - "hits", - "caveat", - "normalizedQuery", - "matchModeUsed", - "totalCount" -]New value: +[ + "hits", + "caveat", + "normalizedQuery", + "matchModeUsed", + "totalCount", + "totalAvailable", + "totalAvailableBasis", + "hasMore" +]
- Changed
sanctions_trace_ownership6 fields changed- added
Output schema / properties / completeAdded value: +{ + "description": "True only when this is the full known ownership picture: nothing was cut off by the requested depth AND every node resolved to a GLEIF Level 1 record. False means the graph below is a partial view — read truncated and missingEntityLeis for which.", + "type": "boolean" +} - added
Output schema / properties / missingEntityLeisAdded value: +{ + "description": "LEIs published in the relationship corpus but absent from the GLEIF Level 1 entity mirror. Their nodes carry the LEI in place of a legal name and no jurisdiction/status — never read that LEI as a legal name, and note any per-node screen for them ran against the LEI string.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / nodes / items / properties / sanctionsScreenAdded value: +{ + "additionalProperties": false, + "description": "Disclosure for this node's cross-reference screen: how many potential matches existed before the per-node cap, and whether sanctionsHits is the complete set. Present only when the node was screened.", + "properties": { + "hasMore": { + "description": "True when this node's potential matches were capped — screen its legal name with sanctions_screen_name to page through the rest.", + "type": "boolean" + }, + "totalAvailable": { + "description": "Potential matches this node's screen found before the per-node cap was applied.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "totalAvailableBasis": { + "description": "How to read totalAvailable: exact = the complete strict match set for this node; lower_bound = a bounded scan produced it, so more may exist.", + "enum": [ + "exact", + "lower_bound" + ], + "type": "string" + } + }, + "required": [ + "totalAvailable", + "totalAvailableBasis", + "hasMore" + ], + "type": "object" +} - added
Output schema / properties / screeningStatusAdded value: +{ + "description": "Whether the per-node cross-reference ran: screened = every node was screened; not_requested = screenNodes was false; not_ready = screening was requested but the sanctions mirror has never synced, so NO node was screened and the absence of hits says nothing about any node.", + "enum": [ + "screened", + "not_requested", + "not_ready" + ], + "type": "string" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when further ownership relationships exist beyond the requested depth — re-run with a higher depth to see them. False means the traversal reached the edge of the loaded relationship corpus.", + "type": "boolean" +} - changed
Output schema / requiredPrevious value: -[ - "rootLei", - "nodes", - "edges", - "screenedNodeCount", - "flaggedNodeCount", - "caveat" -]New value: +[ + "rootLei", + "nodes", + "edges", + "complete", + "truncated", + "missingEntityLeis", + "screeningStatus", + "screenedNodeCount", + "flaggedNodeCount", + "caveat" +]
2 tool updates
- Changed
sanctions_screen_name1 field changed- changed
Input schema / properties / minScore / descriptionPrevious value: -"Jaro-Winkler similarity floor for fuzzy hits (0–1). Applies to fuzzy mode only; defaults to the server's configured floor."New value: +"Score floor for fuzzy hits (0–1), applied uniformly to every fuzzy candidate regardless of how it was matched (Jaro-Winkler, token, or phonetic). No hit below this score is returned. Applies to fuzzy mode only; defaults to the server's configured floor."
- Changed
sanctions_trace_ownership2 fields changed- changed
Output schema / properties / nodes / items / properties / sanctionsHits / descriptionPrevious value: -"Per-node screening results, present only when screen_nodes is true."New value: +"Per-node screening results, present only when screenNodes is true." - changed
Output schema / properties / screenedNodeCount / descriptionPrevious value: -"How many nodes were screened (0 when screen_nodes is false)."New value: +"How many nodes were screened (0 when screenNodes is false)."
6 tool updates
- First observed
sanctions_get_designation - First observed
sanctions_get_entity - First observed
sanctions_list_sources - First observed
sanctions_resolve_entity - First observed
sanctions_screen_name - First observed
sanctions_trace_ownership
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user, then choose Claim with GitHub. An organization namespace such asio.github.acme/serveralso needs that organization to have installed the Glama AI GitHub App and approved its permissions, because GitHub discloses organization membership only to apps it has installed. Use HTTP or DNS when it has not.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Connectors
Screen a name or entity against OFAC SDN, the EU Consolidated list and the UK list.
Screen names against OFAC SDN and 7 more global sanctions lists. Free, no account required.
Screen people & companies against 12 US sanctions & exclusion lists (OFAC, LEIE, SAM, Medicaid).
Screen names against the US Consolidated Screening List: OFAC SDN, BIS Entity List +10 more lists
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceScreens names and companies against OFAC, EU, UK, and UN sanctions lists with fuzzy-match scores, supporting bulk lookups for AML/KYC checks. Data is sourced directly from official government lists and cached for fast repeat checks.-
- AlicenseNot gradedqualityCmaintenanceScreens names against the US Consolidated Screening List including OFAC SDN and BIS Entity List, keyless.10MIT
- AlicenseNot gradedqualityCmaintenanceChecks names against US FinCEN financial crime lists for compliance and AML due diligence, with a single read-only tool.MIT
- AlicenseAqualityAmaintenanceScreens names against the official UK FCDO Sanctions List to identify possible matches with designation details, and retrieves full sanctions entries by unique ID.256Apache 2.0
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Each tool serves a distinct purpose: listing sources, screening names, fetching designation records, resolving LEIs, fetching entity details, and tracing ownership graphs. No two tools overlap in function, and the descriptions clearly differentiate them.
All tool names follow the consistent pattern 'sanctions_' + verb + noun using snake_case: get_designation, get_entity, list_sources, resolve_entity, screen_name, trace_ownership. The verbs and objects are distinct and predictable.
With 6 tools, the server is tightly scoped to the sanctions screening workflow: name screening, designation lookup, entity resolution, entity details, ownership tracing, and source provenance. Each tool earns its place, and the count is well within the ideal 3-15 range.
The tool set covers the full screening lifecycle: list sources for provenance, screen a name, drill into designation details, resolve companies to LEIs, fetch entity records, and trace ownership with optional screening. No obvious gaps exist for the stated purpose, and the server supports complete workflows.