Didit MCP Server
MCP serverMonitoring & opsKYC, KYB, AML, wallet screening, transaction monitoring, and fraud workflows for AI agents.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use Didit MCP Server
From the project's README
As published by didit-protocol/mcp in README.md.
The official Model Context Protocol server for Didit — bring KYC, KYB, AML screening, transaction monitoring, biometrics, and full workspace operations to Claude, Cursor, VS Code, Windsurf, Zed, and any MCP client.
- 130+ tools across sessions, workflows, vendor users/businesses, transactions, the standalone verification APIs, lists, cases, reports, webhooks, and billing.
- Auth is "Log in with Didit" (OAuth 2.1 + PKCE) — the MCP acts as the signed-in user with their role's permissions. There is no API-key mode: every tool calls the user-scoped console endpoints, which only accept a Bearer token.
- Every tool calls a single Didit REST endpoint and returns the JSON verbatim.
Full documentation: https://docs.didit.me/integration/mcp/overview
Quick start
Hosted (recommended)
No install, no API key — point your client at the hosted URL and sign in via the browser:
https://mcp.didit.me/mcp
Claude Code
claude mcp add --transport http didit https://mcp.didit.me/mcp
Cursor (~/.cursor/mcp.json)
{ "mcpServers": { "didit": { "url": "https://mcp.didit.me/mcp" } } }
Windsurf / Zed (via the mcp-remote bridge)
{ "mcpServers": { "didit": { "command": "npx", "args": ["-y", "mcp-remote@latest", "https://mcp.didit.me/mcp"] } } }
See per-client setup for Claude Desktop and VS Code.
Authentication
The MCP is an OAuth 2.1 resource server; the Didit console (business.didit.me) is the authorization server. On first connect your client opens a browser, you Log in with Didit and approve the scopes, and the MCP then acts as you — across every organization you belong to, with your role's permissions. Tokens are short-lived and refreshed automatically.
Scopes: didit:management (workspace operations) and didit:verification (running checks). Your console role is enforced server-side on every call.
There is no API-key mode. Every tool targets the user-scoped console endpoints (
/organization/{org}/application/{app}/…), which authorize a Bearer token with per-role privileges and rejectx-api-key. (For raw REST access with an application API key — e.g. creating sessions from your backend — use the REST API directly, not this server.)
See Authentication.
Tools
130+ tools, grouped by area. The full catalogue with read/write/destructive markers is in docs/TOOLS.md and at docs.didit.me. Highlights:
- Discovery & cross-app:
didit_context_get,didit_session_search,didit_transaction_search,didit_vendor_user_search,didit_analytics— aggregate across every org/app in one call. - Sessions: create, list, get decision, update status, reviews, bulk import.
- Verification APIs:
didit_verify_id,didit_verify_aml,didit_verify_face_match,didit_verify_kyb_search, … - Workflows (incl. branching graphs):
didit_workflow_search,didit_workflow_get_graph,didit_workflow_edit_graph— build conditional/branching workflows (fuzzy-match conditions, Document-AI steps) by sending small ops; large feature configs are kept server-side, never resent.didit_workflow_get_id_verification_methods_cataloganddidit_workflow_get_kyb_registry_cataloganswer the server-driven questions a config write depends on (which countries offer non-doc lookup / wallets, which KYB data tiers and monitoring a country's registries sell). - Compliance: transaction monitoring, custom and preset rule management with backtesting, lists/blocklist/allowlist, cases, reports, audit logs, alerts.
- Workspace: questionnaires, webhooks, members, billing, branding.
File inputs
Tools that consume files (face upload, ID/PoA/liveness/face/age verification, branding) accept the file in one of two forms:
*_path— an absolute path on the machine running the MCP server. Only works for local/stdio runs (e.g. Claude Code with a local server), where your files and the server share a filesystem.*_base64— the file content inline, as raw base64 or adata:URL. Use this against the hosted endpoint; it is how the Didit Console Copilot passes chat attachments (its agent resolves attachment references likeatt_1into base64 before the call reaches the MCP).
Both forms enforce the same 15MB cap and magic-bytes allow-list (png/jpg/jpeg/webp/gif/bmp/ico/pdf). The hosted transport's JSON body limit is 25MB (MCP_JSON_BODY_LIMIT).
Run it yourself
The hosted server above is the easy path — no install. To self-host, clone this repo and run it with Docker or Node. It authenticates the user the same way (OAuth, or a user Bearer token for headless runs); there is no API-key mode.
git clone https://github.com/didit-protocol/mcp.git && cd mcp
# Docker (recommended) — serves /mcp and /healthz on port 3000
docker build -t didit-mcp . && docker run -p 3000:3000 --env-file .env didit-mcp
# …or with Node
npm install && npm run build
node dist/http.js # hosted HTTP/OAuth
DIDIT_ACCESS_TOKEN=<user-access-token> node dist/index.js # stdio (headless)
All Didit base URLs and OAuth endpoints are environment variables with public defaults (verification.didit.me, apx.didit.me, business.didit.me) — override them for a private deployment. See ARCHITECTURE.md and .env.example for the full reference.
Workflow feature configuration
Every workflow feature node takes a config object. The tables below are the complete
contract - what didit_workflow_create, didit_workflow_update, didit_workflow_validate_graph,
didit_workflow_set_graph and didit_workflow_edit_graph accept, and what the API stores.
A key that is not listed here is not part of the contract and is dropped silently on save.
didit_workflow_get_feature_config_schema returns the same data as JSON at runtime.
Generated from schema/feature-config-schema.json (contract sha256:200a66d7054aaf6cdddd94d7bd9c62050912862bf6e291908b667b20436ef4cd, schema version 1), which is a copy of the artifact service-didit-verification generates from its feature-config serializers. Do not edit by hand — run npm run schema:readme.
AGE_ESTIMATION
Configuration for Age Estimation feature.
| Key | Type | Accepts | Meaning |
|---|---|---|---|
borderline_maximum_age_threshold | integer | null | integer >=1 <=100 | |
borderline_minimum_age_threshold | integer | null | integer >=1 <=100 | |
enable_id_verification_fallback | boolean | null | boolean | |
external_capture_device_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when an external capture device is detected. |
face_audio_recording_enabled | boolean | null | boolean | Record the microphone during the selfie capture, so a reviewer can hear the session. Off by default. |
face_liveness_duplicated_face_name_mismatch_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a duplicate face is found under a different name. |
face_liveness_flash_mode | string | null | string | |
face_liveness_max_attempts | integer | null | integer >=1 <=3 | |
face_liveness_method | string | null | 'ACTIVE_3D'|'FLASHING'|'PASSIVE' | |
face_liveness_multiple_faces_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when more than one face is present in the capture. |
face_liveness_possible_duplicated_face_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when this face matches a previously seen user. |
face_liveness_score_decline_threshold | number | null | number | |
face_liveness_score_review_threshold | number | null | number | |
face_luminance_max_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the selfie is brighter than face_luminance_max_threshold. |
face_luminance_max_threshold | integer | null | integer >=0 <=100 | |
face_luminance_min_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the selfie is darker than face_luminance_min_threshold. |
face_luminance_min_threshold | integer | null | integer >=0 <=100 | |
face_privacy_mode_enabled | boolean | null | boolean | |
face_quality_decline_threshold | integer | null | integer >=0 <=100 | |
face_quality_review_threshold | integer | null | integer >=0 <=100 | |
frame_injection_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when injected video frames are detected. |
minimum_age_threshold | integer | null | integer >=1 <=100 | |
screen_capture_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the selfie is a photo of a screen. |
status_rules | array | array | |
virtual_camera_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a virtual camera feed is detected. |
AML
Configuration for AML feature (used for both KYC AML and KYB Company AML).
| Key | Type | Accepts | Meaning |
|---|---|---|---|
aml_country_weight | integer | null | integer >=0 <=100 | |
aml_dob_weight | integer | null | integer >=0 <=100 | |
aml_match_score_threshold | integer | null | integer >=0 <=100 | |
aml_name_weight | integer | null | integer >=0 <=100 | |
aml_score_approve_threshold | integer | null | integer >=0 <=100 | |
aml_score_review_threshold | integer | null | integer >=0 <=100 | |
case_blueprint | uuid | null | uuid | Which case blueprint the automatically-created case is built from. Only meaningful with create_cases_on_hit; the account default is used when unset. |
create_cases_on_hit | boolean | null | boolean | Open a case automatically when the screening returns a hit, instead of leaving the hit to be triaged from the session. Off by default. |
fallback_to_native | boolean | null | boolean | |
is_aml_ongoing_monitoring_enabled | boolean | null | boolean | Keep screening the PERSON after the session is approved, raising a new hit when they later appear on a watchlist. Off by default. |
kyb_company_aml_country_weight | integer | null | integer >=0 <=100 | |
kyb_company_aml_dob_weight | integer | null | integer >=0 <=100 | |
kyb_company_aml_match_score_threshold | integer | null | integer >=0 <=100 | |
kyb_company_aml_name_weight | integer | null | integer >=0 <=100 | |
kyb_enable_ongoing_monitoring | boolean | null | boolean | The same, for the COMPANY on a KYB workflow. The two switches are independent. |
kyb_score_approve_threshold | integer | null | integer >=0 <=100 | |
kyb_score_review_threshold | integer | null | integer >=0 <=100 | |
provider_key | string | null | string | |
status_rules | array | array |
DATABASE_VALIDATION
Configuration for Database Validation feature.
The node is opt-in and does nothing while
database_validation_countriesis empty - the editor blocks publishing in that state and the compliance check reports it as a gap. Place it after the step that produces its inputs (usually OCR), and usedatabase_validation_field_sourcesonly for inputs no upstream step can fill.
| Key | Type | Accepts | Meaning |
|---|---|---|---|
database_validation_countries | json | null | {"": {"services": ["<service_id>", ...]}} | The databases to check, per country - this node runs NOTHING until at least one country carries at least one service id. Service ids come from the country's live catalog (e.g. bra_cpf for BRA); ids that do not belong to the named country, and countries with no live service, are dropped on save. The legacy {"<ISO3>": "one_by_one"|"two_by_two"|"not_enabled"} shape is still accepted and auto-expanded to that country's live services. |
database_validation_field_sources | json | null | {"<db_validation_input_field>": {"source": "document_ai"|"questionnaire"|"expected_data", "key": "||expected_details.|metadata."}} | Where to read a database input that no earlier step in the graph can fill. source names the producer and key names the value inside it: a Document AI field key for document_ai, a questionnaire node id for questionnaire, and expected_details.<field> or metadata.<key> for expected_data. Exact-key matches against an upstream step resolve automatically and are deliberately not persisted, so renaming a Document AI field never freezes a stale mapping into the config. A malformed entry is dropped on save rather than rejected, which un-satisfies its service and drops it from the selection. |
database_validation_no_match_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the database returns no match at all. |
database_validation_not_applicable_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when no selected database covers the holder's country or document. |
database_validation_partial_match_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the database matches some, but not all, of the submitted fields. |
status_rules | array | array |
DOCUMENT_AI
Configuration for the Document AI feature.
At most 3 documents per node, field keys unique within a document, and at most one field per document may set
is_full_name(it is optional - a document may mark none).
| Key | Type | Accepts | Meaning |
|---|---|---|---|
document_ai_document_tampering_action | string | null | 'REVIEW'|'DECLINE' | Verdict when the document looks tampered with. |
document_ai_documents | array | array | |
document_ai_max_attempts_exceeded_action | string | null | 'REVIEW'|'DECLINE' | Verdict when the user runs out of document_ai_max_retry_attempts. |
document_ai_max_retry_attempts | integer | null | integer >=2 <=5 | |
document_ai_missing_required_fields_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a field marked required could not be extracted. |
document_ai_name_match_score_threshold | integer | null | integer >=0 <=100 | |
document_ai_name_mismatch_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the field flagged is_full_name disagrees with the verified identity's full name, scored against document_ai_name_match_score_threshold. |
document_ai_unreadable_document_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the uploaded document cannot be read at all. |
document_ai_unsupported_file_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the uploaded file type is not supported. |
status_rules | array | array |
EMAIL_VERIFICATION
Configuration for Email Verification feature.
| Key | Type | Accepts | Meaning |
|---|---|---|---|
breached_email_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the address appears in a known credential breach. |
cross_org_fraud_email_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when this address was flagged as fraudulent by another organization in the network. |
disposable_email_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the address belongs to a disposable-mail provider. |
duplicated_email_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the address was already verified for this application. |
email_alphanumeric_code | boolean | null | boolean | |
email_code_size | integer | null | integer >=4 <=8 | |
email_enrichment_enabled | boolean | null | boolean | |
email_intelligence_score_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the enrichment score is worse than email_intelligence_score_threshold. |
email_intelligence_score_threshold | integer | null | integer >=0 <=100 | |
email_max_check_attempts | integer | null | integer >=1 <=5 | |
email_max_retries | integer | null | integer >=1 <=5 | |
frequent_email_breach_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the address appears in many breaches. |
only_corporate_emails_allowed | boolean | null | boolean | |
recent_email_breach_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the address appears in a recent breach. |
status_rules | array | array |
FACE_MATCH
Configuration for Face Match feature.
| Key | Type | Accepts | Meaning |
|---|---|---|---|
face_match_eyes_covered_action | string | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when calibrated evidence says the eyes region is covered in the selfie. NO_ACTION records evidence without changing Face Match; REVIEW sends Face Match to review; DECLINE declines it. The signal remains shadow-only until the region reports calibrated=true. |
face_match_face_covered_action | string | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when calibrated evidence says the face region is covered in the selfie. NO_ACTION records evidence without changing Face Match; REVIEW sends Face Match to review; DECLINE declines it. The signal remains shadow-only until the region reports calibrated=true. |
face_match_max_attempts | integer | null | integer >=1 <=3 | |
face_match_mouth_covered_action | string | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when calibrated evidence says the mouth region is covered in the selfie. NO_ACTION records evidence without changing Face Match; REVIEW sends Face Match to review; DECLINE declines it. The signal remains shadow-only until the region reports calibrated=true. |
face_match_not_computed_action | string | null | 'REVIEW'|'DECLINE' | Verdict when no face-match score could be produced (missing portrait or selfie). |
face_match_score_decline_threshold | integer | null | integer >=0 <=100 | |
face_match_score_review_threshold | integer | null | integer >=0 <=100 | |
status_rules | array | array |
IP_ANALYSIS
Configuration for Device & IP Analysis feature.
| Key | Type | Accepts | Meaning |
|---|---|---|---|
automation_detected_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the session looks driven by automation rather than a person. |
cross_org_fraud_device_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when this device was flagged as fraudulent by another organization in the network. |
cross_org_fraud_ip_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when this IP was flagged as fraudulent by another organization in the network. |
device_app_tampered_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the host application binary looks tampered with. |
device_blocklist_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the device is on the organization's block list. |
device_debugger_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a debugger is attached to the host application. |
device_emulator_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the device is an emulator rather than real hardware. |
device_hooking_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when runtime hooking or instrumentation is detected. |
device_integrity_missing_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when no platform device-integrity attestation was returned. |
device_rooted_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the device is rooted or jailbroken. |
duplicated_device_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when this device was already used by another verified user. |
duplicated_ip_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when this IP was already used by another verified user. |
expected_ip_mismatch_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the IP disagrees with the expected IP sent on the session. |
ip_geofencing_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the connecting IP's country is not allowed by ip_geofencing_by_country. |
ip_geofencing_by_country | json | null | {"": {"allowed": true|false, "states"?: {"<state_code>": {"allowed": true|false}} | null}} | Country allow/deny rules for the connecting IP address, applied only while is_ip_geofencing_enabled is true. allowed is required and must be a real boolean; states is optional and null when the country needs no per-state rule. Countries that are not valid ISO3 are dropped on save. |
ip_mismatch_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the IP country disagrees with the document's issuing country. |
is_ip_geofencing_enabled | boolean | null | boolean | |
multiple_devices_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the session was driven from more than one device. |
recovered_device_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the device reports a recovered or restored state. |
status_rules | array | array | |
vpn_detection_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the connection comes through a VPN, proxy or Tor exit. |
KYB_DOCUMENTS
| Key | Type | Accepts | Meaning |
|---|---|---|---|
kyb_document_age_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a document is older than its configured freshness window. |
kyb_document_critical_mismatch_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a document contradicts the registry on a critical company detail. |
kyb_document_max_attempts_exceeded_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when the user runs out of kyb_document_max_retry_attempts. |
kyb_document_max_retry_attempts | integer | null | integer >=1 <=5 | |
kyb_document_non_critical_mismatch_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a document contradicts the registry on a minor detail. |
kyb_document_subtype_config | json | null | {"<KYB_DOCUMENT_GROUP|KYB_DOCUMENT_SUBTYPE>": {"enabled": true|false, "max_age_days": <0-3650>|-1|null}} | Per-group or per-subtype switch and freshness window. Keys must be a known KYB document group or subtype code. max_age_days is null for the default window, -1 for unlimited, or an integer 0-3650; anything else is rejected. |
kyb_document_tampering_action | string | null | 'NO_ACTION'|'REVIEW'|'DECLINE' | Verdict when a company document looks tampered with. |
kyb_required_document_groups | json | null | ["<KYB_DOCUMENT_GROUP>", ...] | The company paperwork to collect, as a list of document-GROUP codes - each group is satisfied by any one of the document types it covers. The KYB Documents feature refuses to save with an empty list: a node that requires nothing is the same as not having the node. |
status_rules | array | array |
KYB_KEY_PEOPLE
The workflow ids here point at separate KYC workflows: a KYB graph verifies the company, and the people behind it are verified by the linked person workflows.
Shortened here. Read the whole README on GitHub.
Signals
- Last commit
- Sep 2026
Advanced
- Delivery
- mcp MCP server → your ahel gateway (mcp.ahel.ai) → every connected AI client.
- Catalog kind
- mcp-server
- Gateway key
me-didit-mcp- Source
- github.com/didit-protocol/mcp
- Hosted endpoint
https://mcp.didit.me/mcp