MCP server

Manage VerifyHuman from any MCP client: Claude Desktop, Claude Code, Cursor, Continue or your own. We host it and you sign in with OAuth. Connect once, then ask your AI assistant to manage projects, replace signing keys, create demo keys or read analytics — the same things you can do in the dashboard.

Install (Claude Code)

From a terminal where the Claude Code CLI is installed:

claude mcp add verifyhuman https://vhuman.riwi.com/mcp

The first call opens a sign-in page (OAuth 2.1 with PKCE) in your browser. After that, Claude Code can use all 34 tools — see your first project below for a one-minute walkthrough.

Other clients (Claude Desktop, Cursor, Continue): use the tool below to build the connection settings, or paste the URL into your client's MCP server settings.

Quick connect

Pick your MCP client. First tool call opens a browser for OAuth login — same Auth0 session as the VerifyHuman dashboard.

Claude Desktop

Paste into claude_desktop_config.json (Settings → Developer → Edit Config).

{
  "mcpServers": {
    "verifyhuman": {
      "url": "https://vhuman.riwi.com/mcp"
    }
  }
}
JSON

Claude Code

Run from a terminal in any directory. Adds to your local Claude Code config.

claude mcp add verifyhuman https://vhuman.riwi.com/mcp
bash

Cursor / Continue / others

Any MCP-compatible client supporting Streamable HTTP + OAuth 2.1.

{
  "mcpServers": {
    "verifyhuman": {
      "url": "https://vhuman.riwi.com/mcp"
    }
  }
}
JSON

Staging URL: https://vhuman.riwi.com/mcp

Your first project — paste this prompt into Claude

Once MCP is connected, the fastest way to start a new integration is to paste this into Claude:

Create a new VerifyHuman project named "My survey site" and mint
me a project-scoped secret key for it. Then tell me:
  - the Project ID
  - the secret key (vf_live_*)
  - what env-var names you recommend I use

Claude will call provision_project_with_key (it creates the project and its Secret key in one call — the recommended way to start), show you the Project ID and Secret key, and explain where each goes: NEXT_PUBLIC_VH_SITE_KEY for the Project ID on the page, VH_API_KEY for the Secret key on your server.

Save the Secret key when it is shown — it is shown ONCE. You can always look up which project a key belongs to later with GET /api/v1/api-keys/current.

What is it?

VerifyHuman offers its admin API as a hosted Model Context Protocol server. Any MCP client can connect to it by signing in with OAuth 2.1 and PKCE — nothing to install, no Python, no environment variables. Once connected, your assistant has tools for everything a customer can do:

  • Projects — list, get, create_project, and provision_project_with_key (creates a project AND its Secret key in one call; ideal for survey platforms that create one project per study).
  • Secret keys — list, create, revoke
  • Checks — list, look up, read analytics
  • On your page settings — read, set the protection level
  • Webhooks — create, read, change, delete, send a test
  • Signing keys — view, replace
  • Demo keys — create short-lived test secret keys (not billed)
  • Per-question checks — read the result for each question
  • Server API — everything from start to finish: read the integration guide (lite_integration_guide), create a Server API project (lite_create_project), send a live test score (lite_score_test_call), read the scoring settings in use (lite_get_config), read usage (lite_stats), try out a threshold change (lite_simulate_threshold), read how scores matched your reported outcomes and our threshold suggestions (lite_ground_truth, lite_threshold_recommendations), and set the thresholds (lite_set_thresholds). See the Server API reference.

OAuth discovery

For MCP clients without a built-in "add server" screen, the sign-in settings are published at https://vhuman.riwi.com/api/v1/.well-known/oauth-authorization-server. Most clients read it automatically. (The unusual /api/v1/ prefix is for historical reasons; a copy at /.well-known/oauth-authorization-server on the root path is planned for clients that look there.) Checks made with a demo key from the MCP demo-key tool are marked is_demo=true and are not billed, so they are safe to try.

What your assistant can do

Once connected, your assistant has 34 admin tools. A few example prompts:

  • "List my VerifyHuman projects and tell me which ones haven't been verified against in the last week."
  • "Create a 30-minute demo key for project X and send me the URL."
  • "Rotate the signing key for project Y. Confirm the rotation timestamp moved."
  • "Show me yesterday's analytics for project Z — pass rate, failure breakdown, average liveness score."
  • "Add a webhook on project A pointing at https://my-receiver.example/vh for the verification.completed event, then test it."
  • "For my Server API project, fire a test score for a datacenter IP and show me the recommendation, then simulate moving the block threshold to 80."

Creating projects from your server

Products that build VerifyHuman in often want to create one project per study, panel or campaign automatically. The MCP provision_project_with_key tool is the way to do it.

Note — MCP does NOT use a Secret key. When your server calls MCP, it signs in with OAuth 2.1 client credentials (a client_id and client_secret pair), not a vf_live_* Secret key. Your backend swaps them for a short-lived access token and sends that to the MCP server. If you want to set a single VERIFYHUMAN_PLATFORM_API_KEY environment variable for MCP, use the REST route instead at /docs/api → /projects/provision or ask our onboarding team to set up an OAuth client for your server.

Example (your backend, run when you create a new study):

# Pseudocode — your backend, called from your "new study" handler

response = await mcp_client.call_tool(
    "provision_project_with_key",
    {
        "name": f"Study {study.id}",
        "external_id": study.id,          # cross-reference back to you
        "api_key_name": f"study-{study.id}-key",
        "is_test_key": False,             # live key for production traffic
    },
)

# Persist BOTH in your study's config:
study.verifyhuman_site_key = response["site_key"]   # → SDK siteKey
study.verifyhuman_api_key  = response["api_key"]    # → /token/verify
# (api_key is the full plaintext — only shown ONCE)

The tool does both steps together. If creating the key fails after the project was created, the response has api_key: null and an api_key_error message; you can try again with create_api_key(project_id) using the returnedproject_id.

Permissions needed: projects:write AND keys:write on the access token. Claude Desktop and Claude Code get every permission when you sign in; a server signing in for itself must ask for both.

When to use MCP vs. the dashboard vs. the SDK

  • SDK — you're putting the check on your page. See the SDK guide.
  • Dashboard — you want screens to view projects, change settings, browse analytics and manage your team.
  • MCP — you want to automate those admin tasks or have an AI assistant do them for you. The same actions as the dashboard, through tools.

Security model

  • OAuth 2.1 with PKCE — the standard sign-in for apps like these. Each client signs in through your browser and gets access tokens that last 1 hour, plus refresh tokens that last 30 days and are replaced on every use.
  • Tokens only reach your organisation. Every tool call is tied to one user and one organisation; the assistant cannot reach projects in another organisation even if it knows their IDs.
  • No personal data in tool responses. IP addresses and browser details are removed from check records before they reach the assistant.
  • Secrets are shown once. Secret keys, webhook signing secrets and project signing keys are shown in full only when created or replaced; after that, only their details are shown.
  • Stolen refresh tokens are caught. Using a refresh token that was already replaced cancels every token in its chain, old and new, so you must sign in again.

Tool permissions

Different tools need different permissions on the access token. Claude Desktop and Claude Code get every permission when you sign in. Other clients can ask for only some:

  • projects:read — list and read projects
  • projects:write — change the protection level and project settings, create Server API projects, and set Server API thresholds
  • verifications:read — read check records and per-question results
  • analytics:read — pass rates, usage, figures over time
  • keys:write — create and revoke Secret keys, replace signing keys
  • webhooks:write — create, change and delete webhooks, and send tests

Not in scope

Some actions are only in the dashboard, on purpose, because they are sensitive or need a person to decide:

  • Changing your plan
  • Inviting or removing organisation members
  • Data subject requests, appeals and other legal requests

Self-hosted / local stdio MCP

For networks with no internet access, or for developers working on the tools, an older package that runs on your own machine (stdio) is available at packages/mcp/ in the repository. It signs in with an Auth0 device code and runs as a Python process started by your client. Most customers should use the hosted server: nothing to install, fixes arrive immediately, and no local Python or environment variables are needed.

Troubleshooting

  • Connection fails / 401 errors — your tokens may have expired. Most clients sign in again automatically; if not, remove the MCP server from your client settings and add it again. Your browser opens so you can sign in.
  • "org not found" on a tool call — your token belongs to one organisation. If you belong to several, the first one is chosen by default; disconnect and reconnect to pick a different one when you sign in.
  • Rate-limit errors when creating demo keys — demo keys are limited per IP address (about 10 a minute, then a short block). Wait a moment and try again.
  • Tool says "not_found" for a project I own — we give the same answer for a project in another organisation, so we never reveal that it exists. Check that you're connected to the right organisation with the get_organization tool.

Issues + roadmap: docs/plans/mcp_hosted_server.md.