ss-api-mcp-server
v1.0.0
Published
MCP server for the Sanction Scanner AML/sanctions screening API. Exposes the full Sanction Scanner API V2 as tools so AI clients can screen names, manage cases, customers, KYB, transactions and more remotely using your own API credentials.
Downloads
202
Maintainers
Readme
Sanction Scanner MCP Server
A Model Context Protocol (MCP) server that exposes the Sanction Scanner API V2 as tools, so MCP-compatible AI clients (Claude Desktop, Claude Code, Cursor, and others) can run sanctions/PEP/adverse-media screening, manage cases, customers, KYB, transaction monitoring and more — using your own Sanction Scanner API credentials.
The server runs locally on your machine over stdio. Your credentials stay on your machine, are sent only to the Sanction Scanner API over HTTPS, and are never logged.
It covers the entire API: 139 tools spanning Scan, Adverse Media, Case management, Customer (KYC), KYB, Transaction Monitoring, Account, SCIM user/group provisioning, Reports, Local/White lists, and general configuration endpoints.
Requirements
- Node.js 18 or newer
- A Sanction Scanner account with API credentials (an API username and password used for HTTP Basic authentication). You can find or create these in the Sanction Scanner dashboard under your API settings.
Installation
Option A — via npx (recommended once published)
No manual install needed; your MCP client launches it on demand (see configuration below):
npx -y sanctionscanner-mcp-server --helpOption B — build from source
git clone <this-repo> # or copy this folder
cd sanctionscanner-mcp-server
npm install # installs deps and builds dist/ automatically
node dist/index.js --helpConfiguration
Add the server to your MCP client's configuration. For Claude Desktop, edit claude_desktop_config.json
(Settings → Developer → Edit Config) and add an entry under mcpServers:
{
"mcpServers": {
"sanctionscanner": {
"command": "npx",
"args": ["-y", "sanctionscanner-mcp-server"],
"env": {
"SANCTIONSCANNER_USERNAME": "your-api-username",
"SANCTIONSCANNER_PASSWORD": "your-api-password"
}
}
}
}If you built from source, point command at Node and the built entry point instead:
{
"mcpServers": {
"sanctionscanner": {
"command": "node",
"args": ["/absolute/path/to/sanctionscanner-mcp-server/dist/index.js"],
"env": {
"SANCTIONSCANNER_USERNAME": "your-api-username",
"SANCTIONSCANNER_PASSWORD": "your-api-password"
}
}
}
}Restart your client after editing the config. The same command/args/env shape works for Claude Code, Cursor, and other MCP clients.
Environment variables
| Variable | Required | Description |
|---|---|---|
| SANCTIONSCANNER_USERNAME | yes* | API username for HTTP Basic auth. |
| SANCTIONSCANNER_PASSWORD | yes* | API password for HTTP Basic auth. |
| SANCTIONSCANNER_AUTH_KEY | yes* | Alternative to username/password: the pre-encoded Base64 of username:password. |
| SANCTIONSCANNER_BASE_URL | no | Override the API base URL. Default: https://api.sanctionscanner.com. |
| SANCTIONSCANNER_TOOLSETS | no | Comma-separated list of tags to expose (e.g. Scan,Customer,Kyb). Default: all groups. |
| SANCTIONSCANNER_READONLY | no | Set to true to expose only read-only (GET) tools. Default: false. |
| SANCTIONSCANNER_TIMEOUT_MS | no | Per-request timeout in milliseconds. Default: 60000. |
* Provide either SANCTIONSCANNER_USERNAME + SANCTIONSCANNER_PASSWORD, or SANCTIONSCANNER_AUTH_KEY.
Scoping the toolset
Some MCP clients work best with a focused set of tools. You can limit what gets registered:
- By group:
SANCTIONSCANNER_TOOLSETS=Scan,Customerexposes only the Scan and Customer tools. Valid group names:Scan,Customer,Kyb,Transaction,Account,SCIM,General,Report,LocalList,WhiteList. - Read-only:
SANCTIONSCANNER_READONLY=trueregisters only GET tools — useful for read-only analyst workflows where no data should be modified.
Tools
Tools are named {group}_{action} in snake_case, derived from the API's own structure, so they read naturally and namespace cleanly. A few examples:
| Tool | Method & endpoint | What it does |
|---|---|---|
| scan_by_name | GET /api/v2/Scan/ByName | Screen a person/entity name against sanctions, PEP and watchlists. |
| scan_adverse_media | POST /api/v2/Scan/AdverseMedia | Run an adverse-media news scan (requires the Adverse Media module). |
| scan_case_open / scan_case_close | POST/DELETE …/Case/{scanId}/… | Open or close a case for a scan. |
| scan_batch_upload | POST /api/v2/Scan/BatchUpload | Upload an Excel file of search terms for batch screening. |
| customer_create / customer_get / customer_update / customer_delete | …/Customer… | Manage customer (KYC) records. |
| kyb_search / kyb_company / kyb_check | …/Kyb/… | Company (KYB) lookups and checks. |
| transaction_execute_transaction | POST /api/Transaction/ExecuteTransaction | Score a transaction against a ruleset. |
| scim_create_user / scim_list_users | …/scim/v2/Users… | SCIM user provisioning. |
| report_statistics | GET /api/v2/Report/Statistics | Compliance statistics. |
To see the full, current list grouped by tag:
npx -y sanctionscanner-mcp-server --list-tools
# or, from source:
node dist/index.js --list-toolsHow tools are described
Each tool's description and parameter docs are generated from the bundled OpenAPI specification, so they stay faithful to the API:
- Enums are expanded with their meanings. For example,
searchTypeis documented as0 = Any, 1 = Individual, 2 = Organization, 3 = Vessel, 4 = Aircraft, andcustomerStatusas1 = New, 2 = Reviewed, 3 = Monitoring, …. - Required vs optional fields, string length limits, numeric ranges, and date formats are enforced and surfaced.
- Tool annotations mark read-only, destructive (DELETE), and idempotent operations so clients can treat them appropriately.
Responses
Successful responses are returned as JSON. Sanction Scanner wraps payloads in an envelope of the form
{ "isSuccess": true, "result": … }; a false isSuccess is surfaced as a tool error. Very large
responses are truncated under a character limit, with a note to use the start/limit query parameters
(available on list endpoints) or to add filters.
Security notes
- Credentials stay local. They are read from environment variables, held only in memory, sent solely to the Sanction Scanner API over HTTPS, and never written to logs. All diagnostic logging goes to stderr and never includes secrets.
- stdio transport. The server communicates over standard input/output as a subprocess of your MCP client. It does not open any network port.
- Write operations are included. Tools such as
customer_delete,scan_case_close, and the blacklist/whitelist endpoints change or remove data. UseSANCTIONSCANNER_READONLY=trueif you want to prevent any modifications, and review write actions before approving them in your client.
Updating to a new API version
The server reads its tool definitions from openapi/sanction-scanner-api-v2.json at startup. To pick up
API changes, replace that file with an updated Sanction Scanner OpenAPI document and restart — no code
changes are required. Tool names, schemas, and descriptions regenerate automatically from the new spec.
Troubleshooting
- "Missing API credentials" on startup: set
SANCTIONSCANNER_USERNAMEandSANCTIONSCANNER_PASSWORD(orSANCTIONSCANNER_AUTH_KEY) in theenvblock of your MCP client config. - Authentication failed (401): double-check your username/password against the Sanction Scanner dashboard. If you use
SANCTIONSCANNER_AUTH_KEY, ensure it is the Base64 ofusername:password. - Permission denied (403): your account may not have access to that endpoint/module (for example, Adverse Media or Transaction Monitoring are separately licensed).
- Timeouts: increase
SANCTIONSCANNER_TIMEOUT_MS(e.g. to120000) for large batch or report calls. - Too many tools in your client: scope with
SANCTIONSCANNER_TOOLSETSand/orSANCTIONSCANNER_READONLY.
Notes on the API specification
A few endpoints in the upstream spec appear to be duplicates or contain naming inconsistencies. They are all exposed as distinct tools so nothing is lost, but you generally only need one of each:
transaction_convert_to_case(/ConvertToCase) andtransaction_convert_case(/TransactionConvertCase) appear to do the same thing.transaction_close_case(/CloseCase) andtransaction_remove_case(/TransactionRemoveCase) appear to overlap.transaction_update_transaction_assign_user(/UpdateTransactionAssignUser) andtransaction_update_transaction_assing_user(/UpdateTransactionAssingUser) — the second contains a spelling inconsistency present in the API itself.
License
MIT
