sanctions-screening-mcp-server について
sanctions-screening-mcp-serverは、OFAC、EU、UK、UNの制裁リストに対して名前や識別子を照合し、GLEIFで企業を検索します。ローカルミラーをオフラインで使い、コンプライアンス判断ではなく候補の確認を支援します。
主な機能
- 01制裁リスト横断の名前照合
- 02識別子の完全一致検索
- 03GLEIFによる法人検索
- 04法人情報と所有関係の追跡
- 05データソースとミラー状態の確認
活用シーン
- 01取引相手候補の名前を照合する
- 02ウォレット、パスポート、SWIFT/BICを確認する
- 03企業名からLEIを検索する
- 04企業の所有関係を調べる
MCP 対応
MCPクライアントに7つの照合・法人情報ツール、3つのリソース、取引相手確認用プロンプトを公開します。結果は候補を示すもので、人による確認が必要です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://sanctions-screening.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-sanctions-screening https://sanctions-screening.caseyjhand.com/mcp{"mcpServers":{"cyanheads-sanctions-screening":{"type":"http","url":"https://sanctions-screening.caseyjhand.com/mcp"}}}Cursor で開く{"servers":{"cyanheads-sanctions-screening":{"type":"http","url":"https://sanctions-screening.caseyjhand.com/mcp"}}}VS Code で開く{"mcpServers":{"cyanheads-sanctions-screening":{"type":"http","url":"https://sanctions-screening.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-sanctions-screening":{"serverUrl":"https://sanctions-screening.caseyjhand.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
7| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| name | string | はい | スクリーニングする名前(個人、組織、船舶、航空機)を任意の文字体系で指定します。少なくとも 1 つの文字または数字を含み、最大 64 語、1024 文字です。 |
| limit | integer | いいえ | 1 ページに返す候補の最大数です。 |
| offset | integer | いいえ | 返す最初の候補のゼロベースのインデックスです。hasMore が true の場合は、返された nextOffset を指定して再度呼び出すと、すべての一致をページ送りできます。末尾を超える offset はエラーではなく空のページを返します。 |
| sources | array | いいえ | 特定のソースリストに限定します。省略すると、読み込まれたすべてのリストをスクリーニングします。 |
| minScore | number | いいえ | 近似一致のスコア下限(0~1)です。Jaro-Winkler、トークン、音声のいずれの照合方式でも、すべてのあいまい候補に一律で適用されます。クエリトークンは、その一致スコアもこの下限を満たす場合にのみ queryTokenCoverage に加算されます。あいまいモード、および厳格モードで厳格検索に一致しなかったリストを対象とする検索など、すべてのあいまい検索に適用されます。そのため、値を上げると厳格スクリーニングの近似一致も除外される場合があります。完全一致と強い一致には影響しません。デフォルトはサーバーに設定された下限です。 |
| matchMode | enum | いいえ | strict(デフォルト):正規化後の完全一致、次に全トークン一致を検索し、その後、厳格検索で見つからなかった選択リストごとにあいまい検索を実行します。いずれのリストでも厳格検索で見つからなかった場合は全件を検索し、それ以外の場合は、法的形態、冠詞などの機能語、および管轄コード uk、usa、uae、rf を除く氏名のすべての単語を含む候補だけを追加します。fuzzy:選択したすべてのリストに対して、スコア付きの Jaro-Winkler + 音声検索を実行します。strict | fuzzy |
| entityType | enum | いいえ | 1 つのエンティティ種別に限定します。または "any"(デフォルト)を指定して、すべてをスクリーニングします。any | person | organization | vessel | aircraft |
詳細
@cyanheads/sanctions-screening-mcp-server
統合されたOFAC、EU、UK、UNの制裁リストを対象に名前を照合し、GLEIFを使って法人を特定します。ローカルのSQLite + FTS5ミラー上で、あいまい一致による照合をオフラインで実行します。コンプライアンス上の判断を行うものではなく、スクリーニングを支援するツールです。
公開ホスト型サーバー: https://sanctions-screening.caseyjhand.com/mcp
概要
統合されたOFAC、EU、UK、UNの制裁リストとGLEIF LEIレジストリを対象に、ローカルミラーとの照合によって、制裁スクリーニングと法人の特定を行います。名前をスクリーニングしてウォッチリストへの該当候補を確認し、企業のLEIを特定して、所有関係をたどることができます。
重要
コンプライアンス上の判断を行うものではなく、スクリーニングを支援するツールです。 すべての結果は、透明性のあるスコアと情報源の来歴を示す該当候補であり、判定ではありません。該当結果は公式情報源で確認すべき候補です。結果が空でも、問題がないと判断することはできません。制裁コンプライアンスには人によるレビューと適格な判断が必要です。このサーバーはそのプロセスに情報を提供するものであり、プロセスそのものを実行するものではありません。
ツール
| ツール | 説明 |
|---|---|
sanctions_screen_name | 個人、企業、船舶、または航空機の名前を、読み込まれたすべてのウォッチリストと一括で照合します |
sanctions_screen_identifier | IMO番号、SWIFT/BICコード、ウォレットアドレス、パスポート番号または国民ID番号を、読み込まれたすべてのウォッチリストと完全一致で照合します |
sanctions_get_designation | リストの情報源とエントリーID、または公表された参照番号を指定して、指定対象の完全なレコードを取得します |
sanctions_resolve_entity | 企業名を、必要に応じて管轄区域を指定して照合し、GLEIFの候補を順位付けして返します |
sanctions_get_entity | LEIを指定してGLEIF Level 1レコードを取得し、名前、LEI、登録番号による制裁関連の照合情報を返します |
sanctions_trace_ownership | LEIの親会社と子会社をたどり、必要に応じてグラフ内の各法人を照合します |
sanctions_list_sources | 読み込まれた情報源を、レコード数、ライセンス、ミラーの鮮度とともに一覧表示します |
リソース
| リソース | 説明 |
|---|---|
sanctions://designation/{source}/{entryId} | ソースとエントリー ID、または公表された参照番号で指定した制裁指定情報 |
sanctions://entity/{lei} | LEI で指定した GLEIF レベル 1 エンティティ |
sanctions://sources | 読み込まれたソースと件数に加え、各ミラーの準備状況と基準日時 |
リソースを表示できないクライアントでも、すべてのリソースデータにツールからアクセスできます。
プロンプト
| プロンプト | 説明 |
|---|---|
sanctions_vet_counterparty | 取引相手のデューデリジェンスを実施します。スクリーニング、照合、所有関係の追跡、要約を行います |
機能リファレンス
sanctions_screen_name ツール
- 任意の文字体系の
name(最大 64 語、1,024 文字)に、任意のsources、entityType、minScoreフィルターを指定できます。matchModeはstrict(デフォルト)またはfuzzyです。Strict では、選択した各リストで一致が見つからなかった場合に fuzzy パスを実行します。どのリストでも一致が見つからない場合は全件を対象とするパスを実行し、それ以外の場合は strict の一致候補の後に、法人格、冠詞、その他の機能語、および管轄区域コードuk、usa、uae、rfを除いた名前のすべての語を含む候補のみを追加するパスを実行します。fuzzySourcesは fuzzy パスで検索したリストを示します。1 ページあたり最大 100 件(limit、デフォルト 25)を返し、offsetでページを指定します - 一致候補には
source、sourceEntryId、該当する場合はリストで公表されたreferenceNumber、matchedNameとそのmatchedNameType、およびmatchType(exact/strong/approximate)が含まれます。Approximate の一致候補には、Jaro-Winkler の生スコア(0~1)であるscoreとqueryTokenCoverageも含まれます - Approximate スクリーニングでは、各方向について、原表記と決定論的なロシア語アルファベットのローマ字表記を比較し、公表された名前と別名のタイプは常にそのまま保持します。派生的な同一性は引き続き approximate であり、公式な別名でも、同一人物・同一組織との判定でもありません。各リストの独立した 2,000 件の名前を対象とする fuzzy 候補プールでは、原表記の候補が優先されます。残りの容量は、ローマ字表記と先頭 4 コードポイントを削除したシグネチャで補われるため、誤字の検出範囲には上限があります
sourcesは、一致候補の対象が掲載されている選択済みリストをすべて示します。OFAC では、SDN List と非 SDN リストの両方に、両方のファイルで同一のエントリー ID を使って対象を掲載しています。OFAC の両方のリストを選択した場合、その対象は 1 件の一致候補として一度だけ数えられ、スクリーニングでどちらのレコードが一致した場合でも、両方のリストが示されます。指定日を含むその他のフィールドはsourceレコードから取得されます。Consolidated レコードだけ、またはそれより高い精度で一致した場合を除き、sourceはofac_sdnですtotalAvailable、hasMore、nextOffsetで残りの候補をページ分割し、ページを進めることで、カウントされた一致候補すべてに到達できます。totalAvailableBasisは件数がexact(選択済みのすべてのリストで strict に一致)かlower_bound(fuzzy パスを実行)かを示します。また、リストの fuzzy 候補プールが上限に達した場合は、より特徴的な語を指定するようnoticeで通知します
sanctions_screen_identifier ツール
value(手元にある識別子)と、任意のtype(既定値はany、imo、swift_bic、digital_currency_address、passport、national_id)およびsources- 正規化後に完全一致する場合のみ照合されます。あいまい検索やスコアリングは行いません。空白、大文字と小文字の違い、および
-./は無視されます。IMO番号はIMOプレフィックスの有無を問わず一致し、SWIFT/BICは先頭の8文字で比較されるため、支店のBIC11はその機関のBIC8と一致します。ウォレットアドレスでは、16進数(0x…)、bech32(bc1…、ltc1…、bnb1…)、cashaddr形式の場合に限り大文字と小文字を区別せず、base58アドレスは完全一致で比較します typeは、各リストで公開されているラベルに照合されます。imoはOFACのVessel Registration Identification、英国のIMO Number、EUのIMO (vessel identification)に対応します。swift_bicはSWIFT/BICとSWIFT BICに対応します。digital_currency_addressはOFACのDigital Currency Address - <code>に対応します。passportとnational_idは、各リストのパスポートおよび国民IDのラベルに対応します。anyは、カテゴリのないすべてのラベル(MMSI、コールサイン、尾翼番号、納税者番号や登録番号、メールアドレス、ウェブサイト)も対象にします- 該当結果は指定ごとに1件で、リスト、次にエントリーIDの順に並びます。それぞれに、公開された表記のまま一致した
matchedIdentifiersとそのsourcesが含まれます。OFACの両方のリストに掲載されたOFAC対象者は、両方のリスト名を示す1件として返されます。ページ分割はありません。リストが自由記述の備考欄にのみ記載している識別子や、1つのフィールドに他の番号とまとめて記載している識別子は一致しません
sanctions_get_designation ツール
source(ofac_sdn、ofac_consolidated、eu、uk、un)とentryId:スクリーニング結果に含まれるsourceEntryId、またはリストで公開されている参照番号(UNのQDe.004、EUのEU.27.28、英国OFSIのグループID14196)を指定します。前後の空白を除去し、大文字と小文字を区別せずに照合します。まずエントリーIDを照合します。同じ参照番号を持つ指定が2件ある場合は、両方を示してreference_ambiguousとして失敗します- リストで参照番号が公開されている場合、
sourceEntryIdとともにreferenceNumberを返します。OFACは参照番号を公開しておらず、エントリーIDが公開番号です - 公開されているすべての別名、識別子、住所、生年月日と出生地、国籍、特徴情報、プログラム、法的根拠、指定日を返します。情報源にないフィールドは省略され、補完されることはありません
- 識別子には、身分証明書に加え、リストが公開しているSWIFT/BICコード、デジタル通貨アドレス、船舶のコールサイン、航空機の尾翼番号とシリアル番号、電話番号、メールアドレス、ウェブサイトが含まれます。それぞれにリスト独自のラベルによる型が付与され、値は原文のまま保持されます
- 生年月日は、情報源が公開した精度でISO 8601形式になります(
1952-10-07、1946-08、1938、または1955/1957のような期間)。情報源が概算として示している場合はcirca: trueが付与されます。designationDateは情報源独自の指定日をYYYY-MM-DD形式で示します - OFAC対象者の日付は、ファイルに掲載されているリスト上のエントリーに基づきます。
ofac_sdnではSDNリスト、ofac_consolidatedでは非SDNリストが対象となり、古い日付が先になります。両方のファイルに掲載された対象者は、それぞれのファイルで異なる日付を持つ場合があります legalBasisは、リストが引用する法的文書を原文のまま示します。OFACの法的根拠への参照(Executive Order 14024 (Russia))、EU規則のタイトル(2024/1488 (OJ L27052024))、英国制度の規則(The Russia (Sanctions) (EU Exit) Regulations 2019)などが含まれます。複数ある場合は;で連結されます。国連リストは法的根拠を公開していませんfeaturesには、対象者を特定するものではなく説明するためにリストが公開している情報が、リスト独自のラベルを付けて公開順に含まれます。OFACの船舶の旗国、種類、所有者、総トン数、航空機のモデル、運航者、製造日、肩書、性別、制裁に関する注記(Secondary sanctions risk:See Section 11 of Executive Order 14024.)、および英国リストの船舶情報(CurrentBelievedFlagOfShip、TypeOfShip、YearBuilt、…)が該当します。日付は公開されている精度のISO 8601形式で、OFACが概算と示している場合はcirca: trueが付与されます。EUと国連のリストは何も含めません。また、スクリーニングツールが特徴情報の値を照合することもありません
sanctions_resolve_entity ツール
- 任意の文字体系の
name(sanctions_screen_nameと同じ制限)に加え、任意のjurisdiction、status、minScoreを指定できます。matchModeはstrict(デフォルト)で、厳密検索で見つからなかった場合にのみファジー検索に切り替わります。またはfuzzyを指定できます。1ページあたり最大50件の候補(limit、デフォルトは10)を取得でき、offsetで位置を指定します jurisdictionは国コードで、該当国とそのすべての下位区分に一致します(USはUS-DEとUS-CAに一致します)。または ISO 3166-2 の下位区分コード(US-DE)を指定すると、完全一致で検索します。大文字と小文字は区別されませんstatusは、issued(デフォルト)がISSUEDに一致し、lapsedがLAPSEDのみに一致します。anyはフィルターを適用しません。RETIRED、DUPLICATE、ANNULLED、PENDING_TRANSFER、PENDING_ARCHIVAL、MERGEDのレコードを検索するにはanyを指定する必要があります。各候補のstatusに状態が記載されます- GLEIF が公開するすべての名称(正式名称、以前の正式名称、商号、別言語での正式名称、別の文字体系による正式名称の ASCII 音訳)を検索します
- 候補には
lei、legalName、一致した名称を示すmatchedNameとその種類を示すmatchedNameType(LEGAL_NAME、PREVIOUS_LEGAL_NAME、TRADING_OR_OPERATING_NAME、…、種類が保存されていない名称の場合はUNKNOWN)、およびmatchTypeが含まれます。近似一致の場合はscoreとqueryTokenCoverageも含まれます。LEI ごとに候補は1件で、ページネーションには同じtotalAvailable/totalAvailableBasis/hasMore/nextOffsetフィールドが使われます
sanctions_get_entity ツール
- 20文字の
leiを1件指定します。正式名称、otherNames、住所と本店所在地、status、jurisdiction、登録機関、lastUpdateを返します alternateNamesには、GLEIF の種類とともに、その他の名称と音訳された名称がすべて列挙されます。種類が記録される前にミラーに保存された名称はUNKNOWNと表示されますsanctionsHitsは、すべてのウォッチリストに対してエンティティを相互参照します。正式名称とalternateNamesの各項目は厳密に照合されます(完全一致の後、すべてのトークンが含まれるかを確認し、ファジー検索は行いません)。また、LEI とregistrationAuthorityEntityIdは、書類識別子以外の識別子として完全一致で検索されます(パスポート、国民識別番号、IMO番号、SWIFT/BICコード、ウォレットは対象外です)。登録番号は、エンティティのjurisdictionの国について公開されている識別子とのみ照合されます。エンティティが管轄区域を公開していない場合、または番号の代わりに入手不可を示すプレースホルダー(N/A、n.a.)を公開している場合は、登録番号の照合をスキップします- 指定ごとに1件のヒットが返されます。OFAC の両方のリストに掲載されている当事者は、両方のリストを示す
sourcesを持つ1件のヒットになります。完全な名称一致と識別子一致が先に並び、その後に強い名称一致が続きます。マージ後の上限は25件です。matchedOnには、ヒットにつながった入力(legal_name、GLEIF の種類を伴うother_name、lei、registration_number)がすべて列挙されます。識別子が一致した場合は、リストで公開されている識別子がmatchedIdentifiersに追加されます。名称によるヒットがない場合、matchedNameとmatchTypeは付与されません。ヒットにscoreは付与されません。scoreを持つのは近似(ファジー)一致のみで、ここでのスクリーニングはすべて厳密照合です screeningStatus(screened/not_ready)は、相互参照が実行されたかどうかを示します。sanctionsScreenはすべての入力にまたがる指定の個数(totalAvailable)を数え、上限に達したリストにフラグ(hasMore)を付けます。また、常にスクリーニングされる正式名称と LEI 以外に何をスクリーニングしたかをscreenedInputsに列挙します
sanctions_trace_ownership ツール
- ルートの
lei、direction(parents/children/both、デフォルトはboth)、およびdepth(1~5、デフォルトは3)を指定します。screenNodes: trueの場合は、sanctions_get_entityと同様にすべてのノードを照合します(名前は厳密に照合し、LEI と国が一致する登録番号を識別子として使用)。ノードごとに統合後のヒットを最大10件返します。Level 1 レコードがないノードには照合対象の名前がないため、LEI のみで検索します。bothはルートからの親方向の走査と子方向の走査をそれぞれdepthまで行うもので、兄弟ノードや共同親には到達しません nodes(roleとdepthを含む)およびedges(relationshipTypeを含み、それぞれ返された2つのノードを接続します)を返します。roleは、そのノードに到達した側を示します。depthでは、グループの最上位への近道であるIS_ULTIMATELY_CONSOLIDATED_BYを除き、すべての関係タイプを数えます。そのエッジのみをたどってdepth以内に到達したノードは、走査されないリーフとなり、reachedVia: "ultimate"が設定されます。その深さは1ホップです。グラフがtruncatedの場合(深さの上限を超える関係、またはフラグが付いたリーフのリンクを表示しない場合。ultimate-parent エッジは、グラフが返さないエンティティにつながる場合にのみ該当)や、Level 1 レコードのないノードがmissingEntityLeisに列挙されている場合、completeは false になります。読み込まれた関係のみを対象としており、ほとんどのエンティティは親の関係を公開していません- 親を走査で読み取った各ノードには、
parentStatus.direct/.ultimateが含まれます。値はrelationship、exception(すべての理由を含む GLEIF の報告例外。例:NATURAL_PERSONS)、none、またはunknownです。unknownは例外データが読み込まれていないことを意味し、その状態はreportingExceptionsLoaded: falseで示されます screeningStatus(screened/not_requested/not_ready)、screenedNodeCount、およびflaggedNodeCountを返します。照合した各ノードには、独自のsanctionsScreen(hasMore、screenedInputs)と、sanctions_get_entityと同じ形式のmatchedOnおよびmatchedIdentifiersを含むヒットが含まれます
sanctions_list_sources ツール
- 入力はありません。制裁リストごとに1行と
gleifの行を返します。各行にはrecordCount、url(設定されたソース URL)、およびlicenseが含まれます。gleif行のrecordCountは Level 1 エンティティ数、relationshipCountは Level 2 の所有関係数です sanctionsReady/sanctionsAsOfとleiReady/leiAsOfは、それぞれのミラーが同期済みかどうかと、その時刻を示します。sanctionsAsOfは、すべての制裁リストが更新された最後の同期時刻です。準備状況にかかわらず応答するため、失敗する代わりに空のミラーを返しますreportingExceptionsLoadedと、報告例外の読み込み後にgleif行に設定されるreportingExceptionCountを返しますalternateNamesIndexedは、GLEIF の商号、旧名、別言語名、および音訳名がインデックス化されているかどうかを示します。mirror:initがインデックスを構築するまでは、sanctions_resolve_entityは正式名称のみを検索します
sanctions://designation/{source}/{entryId} リソース
sourceは5つのリストコードのいずれか、entryIdはリスト独自の ID または公開されている参照番号です。sanctions_get_designationと同じ方法で解決し、パーセントエンコードされている場合は1回デコードします。sanctions_get_designationのペイロードをapplication/jsonとして返します- 1時間キャッシュされ、スコープは
privateです
sanctions://entity/{lei} リソース
- 1つの
leiに対応するsanctions_get_entityの Level 1 ペイロードです。制裁リストとの相互参照は含まれず、ツールのみで利用できます - 1時間キャッシュされ、スコープは
privateです
sanctions://sources リソース
sanctions_list_sourcesのペイロードを変更せずに返しますttlMs: 0:準備状況と基準時刻がペイロードそのものであるため、キャッシュしません
sanctions_vet_counterparty プロンプト
- 引数:
nameは必須です。jurisdictionは任意です(下位区分を含む国コード、または ISO 3166-2 の下位区分コード)。 - 呼び出し元が保持する識別子(
sanctions_screen_identifierを使用)も含めて名称をスクリーニングし、LEI に解決し、screenNodes: trueで所有関係を追跡し、各ヒットの指定記録を取得したうえで、すべての一致を確認対象の候補として扱い、matchedOnから、エンティティのどの名称または識別子が一致を生じさせたかを示す要約を求めるユーザーメッセージを 1 つ返します。GLEIF の親会社は実質的所有者ではなく、会計上の連結親会社として示し、報告例外については「親会社なし」と解釈するのではなく、その理由を報告します。
機能
@cyanheads/mcp-ts-core を基盤としています。stdio および Streamable HTTP トランスポート、プラグイン可能な認証(none / jwt / oauth)、切り替え可能なストレージ(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1)、オプションの OpenTelemetry トレースを備えた構造化ログを提供します。
制裁スクリーニング固有の機能:
- 1 回のスクリーニングで OFAC SDN、OFAC Consolidated、EU、UK(UKSL)、UN を対象とし、各ヒットの出典情報として一致したリストを表示します
- オフラインで利用でき、キーも不要で、リクエストごとのレート制限もありません。5 つすべてのソースをフレームワークの
MirrorService経由でローカルの SQLite + FTS5 ミラーに正規化します - エイリアスごとの名称インデックスにより、1 回の FTS スキャンでエンティティのあらゆる名称を照合できます。また、IMO 番号、SWIFT/BIC、ウォレットアドレス、文書番号による完全一致検索用の識別子インデックスも備えています
- 厳密な照合からあいまい照合へと順に実行します。正規化後の完全一致、次にすべてのトークンが含まれる一致(FTS5)、その後 Jaro-Winkler + Double-Metaphone を使って、リストごとに 2,000 件の候補プールを検索します。これにより、リストを追加しても別のリストの候補が除外されず、採用された候補はすべてページングで取得できます
- エンティティの解決と所有関係の追跡に、GLEIF Level 1(誰が誰か)と Level 2(誰が誰を所有しているか)を利用します
エージェントに適した出力:
- 出典情報を伴う実質的なシグナル:近似ヒットには、生の Jaro-Winkler
scoreと、文字どおりのqueryTokenCoverage件数が含まれ、合成された信頼度は使用しません。各ヒットにはリスト、プログラム、指定日、一致した名称と、その種別(primary/aka/fka/low-quality-aka)が示されます sanctions_screen_name、sanctions_screen_identifier、sanctions_get_designation、sanctions_get_entity、sanctions_trace_ownershipの出力に、意思決定を支援するcaveatを含めます- 対応範囲の不足を明示:
totalAvailableBasis、screeningStatus、complete/truncated/missingEntityLeis、および各ノードのparentStatusによって、レスポンスで網羅されなかった内容がわかります - 型付きエラー:ソース一覧を除くすべてのツールとリソースは、ミラーが読み込まれるまで再試行可能な
mirror_not_readyとして失敗します。不明な ID はdesignation_not_foundまたはlei_not_foundとして失敗します。ミラーにない LEI の ISO 17442 チェックディジットが無効な場合(文字の入力ミス)はinvalid_lei_checksumとして、2 つの指定で共有される参照番号はreference_ambiguousとして失敗します。文字または数字を含まない名称はname_not_searchableとして、長さの上限を超える名称はname_too_longとして、空白と区切り文字を除去した後に何も残らない識別子はidentifier_not_searchableとして失敗します
はじめに
公開ホストインスタンス
公開インスタンスは https://sanctions-screening.caseyjhand.com/mcp で利用できます。インストールは不要です。任意の MCP クライアントから Streamable HTTP 経由で接続してください。
{
"mcpServers": {
"sanctions-screening-mcp-server": {
"type": "streamable-http",
"url": "https://sanctions-screening.caseyjhand.com/mcp"
}
}
}
セルフホスト/ローカル
以下を MCP クライアントの設定ファイルに追加してください。ミラーは同梱されておらず、npm パッケージからビルドすることもできません。クローンしたリポジトリ(インストール)または Docker イメージ内で bun run mirror:init を実行し、SANCTIONS_MIRROR_PATH をその結果に設定してください(ミラーのライフサイクルを参照)。
{
"mcpServers": {
"sanctions-screening-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/sanctions-screening-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または npx を使用する方法(Bun は不要):
{
"mcpServers": {
"sanctions-screening-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/sanctions-screening-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Streamable HTTP の場合は、トランスポートを設定してサーバーを起動してください。
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
前提条件
- Bun v1.4.0 以上、または Node.js v24 以降。
- ローカルミラー用のディスク領域が必要です。GLEIF Level 1 が大部分を占めます。どのデータソースにも API キーは必要ありません。
インストール
- リポジトリをクローンします:
git clone https://github.com/cyanheads/sanctions-screening-mcp-server.git
- ディレクトリに移動します:
cd sanctions-screening-mcp-server
- 依存関係をインストールします:
bun install
- 環境を設定します:
cp .env.example .env
# edit .env if you need to override defaults (all optional)
- ミラーにデータを取り込みます:
bun run mirror:init
設定
すべてのデータソースでキーは不要なため、ここで設定する項目はありません。
| 変数 | 説明 | デフォルト |
|---|---|---|
SANCTIONS_MIRROR_PATH | SQLite ミラーのファイルシステムパスです。ホスト環境では永続ボリュームを使用してください。 | ./data/sanctions.db |
SANCTIONS_REFRESH_CRON | スケジュールされた更新の cron 設定です(HTTP トランスポートのみ)。監視対象の子プロセスが制裁リストとそのインデックスを更新し、続いて GLEIF の差分を新たに設定された 4 時間の制限時間内に適用します。mirror:init が必要となるデータの欠落はログに記録され、スケジュール実行でゴールデンコピーが読み込まれることはありません。 | 0 4 * * * |
SANCTIONS_REFRESH_SKIP_GLEIF | 1 に設定すると、スケジュールされた更新と mirror:refresh の GLEIF 処理をスキップします。 | 未設定 |
SANCTIONS_FUZZY_MIN_SCORE | minScore が省略された場合に使用される、あいまい一致の Jaro-Winkler 下限値です。 | 0.85 |
OFAC_SDN_URL | OFAC SDN の高度な XML URL です。 | OFAC 公式 URL |
OFAC_CONSOLIDATED_URL | OFAC Consolidated の高度な XML URL です。 | OFAC 公式 URL |
EU_FSF_URL | EU 統合 XML の URL です。token クエリ値は公開されている固定のパス要素であり、認証情報ではありません。 | EU 公式 URL |
UK_SANCTIONS_URL | UK Sanctions List(UKSL)の XML URL です。 | FCDO 公式 URL |
UN_SC_URL | 国連安全保障理事会統合 XML の URL です。 | 国連公式 URL |
GLEIF_GOLDEN_COPY_BASE_URL | GLEIF のゴールデンコピーおよび差分ダウンロード API です。 | https://goldencopy.gleif.org |
MCP_TRANSPORT_TYPE | トランスポートです:stdio または http。 | stdio |
MCP_HTTP_PORT | HTTP サーバーのポートです。 | 3010 |
MCP_SESSION_MODE | HTTP セッションモードです:stateless、stateful、または auto。createApp() では stateless が宣言されており、この変数を設定するとその値が優先されます。 | stateless |
MCP_LOG_LEVEL | ログレベルです(debug、info、warning、error など)。 | info |
LOG_TOOL_FAILURE_PAYLOADS | 失敗したツール呼び出しごとに、キー名による機密情報のマスキングを行い、LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES(デフォルトは 16384)を上限として、引数と結果をログに記録します。自由形式の値に含まれる機密情報はマスキングされません。 | false |
省略可能なオーバーライドの一覧については、.env.example を参照してください。
サーバーの実行
ローカル開発
-
ビルドして実行:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
チェックとテストを実行:
bun run devcheck # Lint, format, typecheck, security, changelog sync bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
ミラーのライフサイクル
ミラーは帯域外で読み込まれ、リクエスト処理中に読み込まれることはありません。
HTTP デプロイでは、スケジュールされた更新は、サービスを実行するランタイムとそのランタイム引数を使用して、別のプロセスで実行されます。SQLite WAL により、子プロセスが書き込み中でもコミット済みのインデックスを読み取れるため、再構築中もヘルスチェックやスクリーニングのリクエストを処理できます。タイムアウトまたはシャットダウン時にはキャンセルを要求し、クリーンアップのために最大 5 秒待機した後、終了していない子プロセスを強制終了して終了を待ちます。どのような最終結果になっても、次回の実行に向けてスロットが解放されます。強制終了された実行では、コミット済みの収集ページが残ることがあります。次回の更新が正常に完了すると、その派生インデックスが完了前に再構築されます。サービスプロセスは、再起動せずに更新された鮮度情報と報告例外数を読み取ります。
| スクリプト | 目的 |
|---|---|
bun run mirror:init | 全件ロード:5つすべての制裁リスト、名称インデックスと識別子インデックス、その後にGLEIFのゴールデンコピー(Level 1とその名称インデックス、Level 2、報告例外)をロードし、各ファイルのContentDateをGLEIFチェックポイントとして記録します。最後にGLEIFの完全一致名称インデックスを作成します。このインデックスは、厳密な照合が上限に達した場合に完全一致する名称を優先します。安全に再実行できます。中断された実行は最初からやり直します。制裁リストのみをロードするには、SANCTIONS_INIT_SKIP_GLEIF=1を設定します。 |
bun run mirror:refresh | 制裁リストを再取得し、リストの完全なドキュメントに掲載されなくなった指定を削除します(1回の実行でリストの最大半分まで)。続いてチェックポイントからGLEIFを最新状態にします。各データセットについて、最後に適用したファイルまで遡れる最小の差分ウィンドウ(IntraDayからLastMonthまで)を適用し、削除も反映します。ロード記録のない報告例外はゴールデンコピーを取得します。また、スクリプトは(cronではなく)GLEIFの完全一致名称インデックスが存在しない場合に作成します。同じ更新処理はHTTP経由でSANCTIONS_REFRESH_CRONでも実行されます(差分のみ)。このスクリプトと同様、実行時間の上限は4時間です。GLEIFをスキップするには、SANCTIONS_REFRESH_SKIP_GLEIF=1を設定します。 |
bun run mirror:verify | ミラーの準備状況、ソースごとのレコード数、GLEIFのLevel 1/Level 2/報告例外の件数、GLEIFの別名がインデックス化されているか、完全一致名称インデックスが作成済みか、GLEIFチェックポイントを報告します。 |
bun run mirror:seed | ローカルのスモークテスト用に、ダウンロードなしで小規模な合成フィクスチャをロードします。 |
ダウンロードに失敗したリスト、または途中で切り詰められた状態で届いたリストは、保存済みの行を保持し、何も削除しません。一方、ほかのすべてのリストは引き続き更新され、名称インデックスと識別子インデックスが再構築されます。その後もGLEIFは更新され、実行は失敗した各リスト(ofac_sdn、euなど)の名前を示して、ゼロ以外の終了コードで終了します。sanctionsAsOfが更新されるのは、すべてのリストが更新された実行時のみです。リストに失敗した場合、初回のmirror:init後もミラーは準備未完了のままです。
GLEIFの更新は全体が一括で適用されるか、まったく適用されないかのどちらかです。leiAsOfとチェックポイントが更新されるのは、すべてのデータセットの対象差分が適用された後のみです。そのため、更新が中断されても両方とも以前の状態を保ち、次回の実行では同じ地点から再適用されます。GLEIFに何も適用されず、leiAsOfも変更されず、mirror:initを示してゼロ以外の終了コードで終了するケースが2つあります。チェックポイントが1か月のウィンドウより古い場合と、ミラーにチェックポイントがない場合です。0.3.0以前で書き込まれたすべてのミラーにはチェックポイントがないため、アップグレード後に一度mirror:initを実行してください。それまでは、トレースで未公開の親はunknownと表示され、sanctions_resolve_entityは正式名称のみを検索し、別名はまだインデックス化されていないという通知を返します。そのファジー照合では、長い名称の特徴的な単語のうち最初の3語で処理が止まり、候補数の上限に達したことが示されます。0.3.0では、ほかの名称は種類を記録せずに保存され、音訳された名称は一切保存されていませんでした。そのため、名称インデックスは保存済みの行からではなく、mirror:initがロードするゴールデンコピーから作成されます。その後は、GLEIFへの書き込みごとにインデックスが最新の状態に保たれます。それ以前のリリースによるGLEIFへの書き込みや、ロールバック後の書き込みではインデックスが古いままになり、次のmirror:initまで正式名称のみの照合に戻り、その通知も表示されます。
以前のリリースで作成されたミラーは、初回オープン時にその場でアップグレードされます。designation テーブルに reference_number 列が追加され、画面が表示される前に、保存済みの指定情報から制裁対象者名インデックスが再構築されます(2026-10-03 のリストでは約 4 秒)。識別子インデックスは初回検索の前に保存済みレコードから構築されるため、再初期化しなくても、データが格納されたミラーから sanctions_screen_identifier が結果を返します。以前のリリースで読み取れなかった、または誤って読み取られた情報、すなわち参照番号、身分証明書以外の OFAC および UK の識別子、公表精度での日付、各ファイル固有のリストから取得した OFAC の指定日、legalBasis、features は、次回の制裁リスト更新で取り込まれます。この更新では保存済みの指定情報がすべて書き換えられるため、cron を待たずにアップグレード後に mirror:refresh を実行してください。それまでは、sanctions_get_designation は保存済みのすべてのレコードに対して features: [] を返します。また、以前のリリースで識別子として保存されたプレースホルダー(英国の N/A パスポート)は、引き続き sanctions_screen_identifier で一致します。同じ mirror:refresh の GLEIF 処理が実行されると、GLEIF の完全一致名称インデックスも構築されます。それまでは、2,000 件の名称上限に達する厳密な照合はインデックスなしで実行されるため、スキャンで到達できなかった完全一致の名称は見つかりません。同期後に実行されなかった同期によって保存済みレコードが変更された場合(たとえば、以前のリリースがロールバック後に実行された場合)も、オープン時に識別子インデックスが再構築されます。GLEIF ミラーの初回オープン時には、解決クエリで参照されない lei_entity のステータスインデックスが削除されます。全件データでは約 2 秒かかり、後続の書き込みで再利用される約 54 MiB の領域が解放されます。ファイルサイズが縮小するのは、手動で VACUUM を実行した後だけです。
mirror:init と mirror:refresh の各処理はすべて、上限付きのバッチでストリーミングされるため、ピーク時のメモリ使用量はソースのサイズではなくバッチサイズに左右されます。制裁関連の XML は合計約 172 MB です。GLEIF Level 1 のゴールデンコピーは約 340 万件(圧縮時約 890 MB)で、ディスク使用量の大半を占めます。その名称インデックス(約 400 万件)でさらに約 0.8 GB を使用します。報告例外は約 640 万行で、ディスク上のサイズは約 525 MiB です。
Docker
docker build -t sanctions-screening-mcp-server .
docker run --rm -p 3010:3010 -v sanctions-data:/usr/src/app/data sanctions-screening-mcp-server
Dockerfile はデフォルトで HTTP トランスポート、ステートレスセッションモードを使用し、ログを /var/log/sanctions-screening-mcp-server に出力します。再起動後もミラーを保持できるよう、/usr/src/app/data にボリュームをマウントし、docker exec を使って bun run mirror:init でデータを格納してください。OpenTelemetry のピア依存関係はデフォルトでインストールされます。これらを省略するには、--build-arg OTEL_ENABLED=false を指定してビルドしてください。
プロジェクト構成
| ディレクトリ | 用途 |
|---|---|
src/index.ts | createApp() のエントリーポイントです。サーフェスを登録し、スクリーニングサービスを初期化し、HTTP 更新をスケジュールします。 |
src/config | サーバー固有の環境変数の解析と、Zod による検証を行います。 |
src/mcp-server/tools | ツール定義(*.tool.ts)と共通のスクリーニングに関する注意事項です。 |
src/mcp-server/resources | リソース定義(*.resource.ts)です。 |
src/mcp-server/prompts | プロンプト定義(*.prompt.ts)です。 |
src/services/screening | スクリーニングサービスです。ミラー、正規化済みスキーマ、OFAC/EU/UK/UN/GLEIF の取り込み処理、照合エンジンが含まれます。 |
scripts/mirror-*.ts | ミラーのライフサイクルを操作する CLI です。初期化、更新、検証、シードを行います。 |
tests/ | ツール、リソース、プロンプト、サービス、統合、ファズ、スモークテストです。 |
開発ガイド
開発ガイドラインとアーキテクチャのルールについては、CLAUDE.md/AGENTS.md を参照してください。要点は次のとおりです。
- ハンドラーは例外をスローし、フレームワークが捕捉します。ツールのロジック内で
try/catchを使わないでください。 - リクエスト単位のログ記録には
ctx.logを使います。ミラーにはctx.stateではなく、getScreeningService()経由でアクセスします。 - 新しいツールとリソースは、
src/mcp-server/*/definitions/index.tsのバレル経由で登録します。 - 外部ソースはラップし、生データを検証してから共通スキーマに正規化し、出力スキーマを返します。ソースにないフィールドを捏造したり、信頼度スコアを生成したりしないでください。
帰属表示
このサーバーは、各利用条件に従い、以下のソースからのオープンデータを再配布します。
| ソース | 発行元 | ライセンス |
|---|---|---|
| OFAC SDN および統合リスト | 米国財務省外国資産管理局 | 米国政府のパブリックドメイン |
| EU 統合金融制裁リスト | 欧州委員会/EEAS | 自由に再配布可能 |
| 英国制裁リスト(UKSL) | 英国外務・英連邦・開発省 | オープン・ガバメント・ライセンス v3.0(帰属表示が必要) |
| 国連安全保障理事会統合リスト | 国連安全保障理事会 | 自由に再配布可能 |
| GLEIF LEI データ(レベル 1 + レベル 2) | グローバル法人識別子財団 | CC0 1.0 ユニバーサル |
OFSI 統合リストが 2026 年 1 月 28 日に閉鎖されて以降、UKSL は英国の唯一の権威ある情報源となっています。
貢献
Issue を歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
ライセンス
Apache-2.0 — 詳細は LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。