Skip to content

Speedmap Connect (MCP server)

The first identity MCP server designed so a NIN never enters an AI context window. Verify from Claude, ChatGPT, Cursor and VS Code.

View as Markdown

Speedmap Connect is a Model Context Protocol server that lets AI assistants and agents run Speedmap checks on your behalf: a compliance officer reconciling KYC without leaving the chat, a developer wiring verification into an agent from the editor, a bulk job dispatched conversationally.

It uses the same API keys, entitlements, consent rules and billing as the REST API. What changes is what comes back: assertions only. Tools return verified, match, masked names and risk scores, never the NIN, BVN or identity record, so personal data does not land in a model's context, logs or training data.

Connect

The remote server speaks Streamable HTTP and is stateless: every request is a POST carrying your key, and no session is kept. Nothing to install.

POSThttp://localhost:4000/mcp

Authenticate with your Speedmap key as a bearer token, Authorization: Bearer sk_test_.... Use a sandbox key while you evaluate: test data, no billing. Requests count against the same per-key rate limit as the REST API.

For clients that only run local (stdio) servers, the @speedmap/mcp package bridges to the remote server. It needs Node.js 20 or later and reads your key from SPEEDMAP_API_KEY:

SPEEDMAP_API_KEY=sk_test_... \
SPEEDMAP_MCP_URL=http://localhost:4000/mcp \
npx -y @speedmap/mcp

Claude Code

Terminal
claude mcp add --transport http speedmap http://localhost:4000/mcp \
  --header "Authorization: Bearer sk_test_..."

Claude Desktop

Add the server to claude_desktop_config.json (Settings → Developer → Edit config), then restart Claude Desktop.

claude_desktop_config.json
{
  "mcpServers": {
    "speedmap": {
      "command": "npx",
      "args": [
        "-y",
        "@speedmap/mcp"
      ],
      "env": {
        "SPEEDMAP_API_KEY": "sk_test_...",
        "SPEEDMAP_MCP_URL": "http://localhost:4000/mcp"
      }
    }
  }
}

ChatGPT

Turn on developer mode (Settings → Connectors → Advanced), then add a custom connector:

  1. Server URL: http://localhost:4000/mcp
  2. Authentication: API key, sent as a bearer token. Paste your sk_test_ key.
  3. Enable the connector in a chat and ask it to verify a test identity.

Cursor

Add the server to ~/.cursor/mcp.json for every project, or .cursor/mcp.json in one project.

~/.cursor/mcp.json
{
  "mcpServers": {
    "speedmap": {
      "url": "http://localhost:4000/mcp",
      "headers": {
        "Authorization": "Bearer sk_test_..."
      }
    }
  }
}

VS Code

Add .vscode/mcp.json to your workspace. The inputs entry makes VS Code prompt for the key and store it securely instead of keeping it in the file.

.vscode/mcp.json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "speedmap-key",
      "description": "Speedmap API key",
      "password": true
    }
  ],
  "servers": {
    "speedmap": {
      "type": "http",
      "url": "http://localhost:4000/mcp",
      "headers": {
        "Authorization": "Bearer ${input:speedmap-key}"
      }
    }
  }
}

Any other client

Any client that supports remote MCP servers over Streamable HTTP works: point it at the URL above with the Authorization header. To check your setup from a terminal:

cURL
curl -X POST http://localhost:4000/mcp \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Guarantees

  1. Assertions only. No NIN, BVN or identity record is returned to the model. Results carry a dashboard_url where authorized staff can see more.
  2. Purpose is constrained. reason is an enum of the 38 NIMC purpose codes in every tool schema. An agent cannot invent one, and the server instructions tell it to ask the user when the purpose is unclear.
  3. Consent first. Tools that touch personal data require consent_obtained: true, which the assistant may set only after the user confirms consent. Consent is checked before any provider is called, exactly as on the REST API.
  4. Bulk never returns rows. bulk_verify returns a job id and a dashboard link. A developer cannot pull 10,000 records into a chat.
  5. Registry text is data, not instructions. Text from registries (company names, provider messages) is stripped of control and invisible characters and length-capped before it reaches the model.
  6. Errors do not leak. Tool errors carry Speedmap's own error code and a scrubbed message, never provider internals or identifiers.
  7. Sandbox and live are separate. sk_test_ keys use test data and are free; sk_live_ keys reach the live registries (NIMC and NIBSS) and are billed.

Tools

Twelve tools. Verification tools return a short sentence for the model plus the same fields as structuredContent.

verify_nin

Verify a Nigerian NIN. Checks an NIN against NIMC. Never returns the identity record.

Returns: reference_id, product, status, match, field_matches, field_confidence, masked subject and summary, mode, dashboard_url.

Input

  • methodstring

    nin (raw NIN, financial institutions and government only) or share_code. Defaults to nin.

  • ninstring

    11-digit NIN, for method nin.

  • share_codestring

    NINAuth share code, for method share_code.

  • reasonstringrequired

    One of the 38 purpose codes. The assistant must ask if unsure.

  • consent_obtainedtruerequired

    Set only after the user confirms the data subject consented.

  • first_namestring

    Expected first name.

  • last_namestring

    Expected last name.

  • date_of_birthstring

    Expected date of birth, YYYY-MM-DD.

verify_bvn

Verify a BVN. Match / no-match through NIBSS. No PII is returned.

Returns: reference_id, product, status, match, field_matches, field_confidence, masked subject and summary, mode, dashboard_url.

Input

  • bvnstringrequired

    11-digit BVN.

  • reasonstringrequired

    One of the 38 purpose codes. The assistant must ask if unsure.

  • consent_obtainedtruerequired

    Set only after the user confirms the data subject consented.

  • first_namestring

    Expected first name.

  • last_namestring

    Expected last name.

  • date_of_birthstring

    Expected date of birth, YYYY-MM-DD.

verify_business

Verify a company (CAC / KYB). Looks up a CAC-registered company by RC number, TIN or exact name.

Returns: Company name, status, type and registration date in summary, plus the fields above. Directors and shareholders need the REST API.

Input

  • rc_numberstring

    RC or BN number, e.g. RC1234567.

  • tinstring

    Tax identification number.

  • company_namestring

    Exact registered name.

  • expected_namestring

    Name to check against the register.

verify_account

Verify a bank account name. NIBSS name enquiry on a 10-digit NUBAN.

Returns: Masked account name, bank name and name_match.

Input

  • account_numberstringrequired

    10-digit NUBAN.

  • bank_codestringrequired

    CBN bank code, e.g. 058. See list_banks.

  • expected_namestring

    Name you expect on the account.

face_match

Face liveness and match. Passive liveness on a selfie, optionally compared with the BVN photo.

Returns: Pass/fail and confidence scores only.

Input

  • image_urlstringrequired

    HTTPS URL of the selfie.

  • bvnstring

    Compare against the photo on this BVN.

  • reasonstringrequired

    One of the 38 purpose codes. The assistant must ask if unsure.

check_signals

Fraud risk signals. One risk score from SIM swap, BVN changes and the watchlist.

Returns: risk_score, risk_level and factors.

Input

  • phonestring

    Mobile number.

  • bvnstring

    11-digit BVN.

  • reasonstringrequired

    One of the 38 purpose codes. The assistant must ask if unsure.

  • consent_obtainedtruerequired

    Set only after the user confirms the data subject consented.

bulk_verify

Start a bulk job. Queues many checks of one product. Results are never returned into the conversation.

Returns: job_id, status, total and dashboard_url.

Input

  • productstringrequired

    nin, bvn, phone, business, account or signals.

  • itemsarrayrequired

    1 to 10,000 request bodies, as for the REST API.

  • namestring

    Job label.

get_bulk_job

Bulk job progress. Progress and outcome counts. Never rows.

Returns: The bulk job: status, processed, total, progress, counts.

Input

  • job_idstringrequired

    From bulk_verify.

get_verification

Get a verification. Fetches an earlier check, e.g. to resolve a pending one.

Returns: reference_id, product, status, match, masked subject and summary, dashboard_url.

Input

  • reference_idstringrequired

    Starts with spm_.

Request consent. Creates a consent request the person approves by link, email or USSD.

Returns: consent_id, status, authorization_url, ussd_code, expires_at.

Input

  • identifier_typestringrequired

    bvn or nin.

  • identifierstringrequired

    11-digit BVN or NIN.

  • categoriesstring

    Y/N mask, default YYNN.

  • channelstring

    redirect, email or ussd. Default redirect.

  • emailstring

    For the email channel.

  • reasonstringrequired

    One of the 38 purpose codes. The assistant must ask if unsure.

list_reasons

List purpose codes. The 38 NIMC purpose codes accepted as reason.

Returns: One key: label line per code.

No input.

list_banks

List bank codes. Bank names and CBN codes for verify_account.

Returns: One code: name line per bank.

No input.

Example prompts

With a sandbox key, try:

  • "Verify NIN share code SPM001 for a loan application and check the surname is Griffin."
  • "Is RC1234567 an active company?"
  • "Check whether account 0123456789 at GTBank belongs to Clarke Griffin before we pay her."
  • "Run a fraud check on BVN 22222222225 with phone 08099990000."

The machine-readable manifest is at /.well-known/mcp.json.

Questions? Email developers@speedmap.ng. This page is also available as Markdown.