MCP server
Programmatic admin for VerifyHuman from any MCP-compatible client — Claude Desktop, Claude Code, Cursor, Continue, or your own. Hosted and OAuth-secured. Connect once, then ask your LLM to manage projects, rotate signing keys, mint demo keys, or inspect analytics — same surface as the dashboard.
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://verifyhuman.riwi.com/mcp"
}
}
}JSONClaude Code
Run from a terminal in any directory. Adds to your local Claude Code config.
claude mcp add verifyhuman https://verifyhuman.riwi.com/mcpbashCursor / Continue / others
Any MCP-compatible client supporting Streamable HTTP + OAuth 2.1.
{
"mcpServers": {
"verifyhuman": {
"url": "https://verifyhuman.riwi.com/mcp"
}
}
}JSONStaging URL: https://vhuman.riwi.com/mcp
What is it?
VerifyHuman exposes its admin API as a remote Model Context Protocol server. Any MCP-compatible LLM client can connect to it via OAuth 2.1 + PKCE — no local install, no Python, no env vars. Once connected, the LLM has tools for the full customer surface:
- Projects — list, get (write operations via dashboard or the new server-to-server
/projects/provisionendpoint) - API keys — list, create, revoke
- Verifications — list, look up, query analytics
- Widget config — get, set mode
- Webhooks — full CRUD, test delivery
- Signing keys — inspect, rotate
- Demo keys — mint short-lived test keys (billing-isolated)
- Phase 3 — read per-question scoring events
OAuth discovery
For MCP clients that don't have a built-in "add server" UI: discovery metadata is served at https://verifyhuman.riwi.com/api/v1/.well-known/oauth-authorization-server. Well-behaved clients fetch that automatically. (The non-standard /api/v1/ prefix is historical — for clients that look at the root path, /.well-known/oauth-authorization-server is being added as a mirror in a follow-up.) Demo verifications minted via the MCP demo-key tool run with is_demo=true and stay isolated from billed usage — safe to play with.
What the LLM can do
Once connected, your LLM has 23 tools spanning the admin surface. A few representative 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/vhfor theverification.completedevent, then test it."
When to use MCP vs. the dashboard vs. the SDK
- SDK — you're embedding the verify widget in your product. See the SDK guide.
- Dashboard — you want a visual UI to inspect projects, edit widget config, browse analytics, manage team.
- MCP — you want to script those admin actions or have an LLM do them for you. Same operations as the dashboard, just via tool calls.
Security model
- OAuth 2.1 with PKCE — the standard public-client flow. Each LLM client gets browser-driven consent and short-lived access tokens (1 hour) plus rotating refresh tokens (30 days).
- Tokens are scoped to your org. Every tool call resolves the bearer to a specific user + organization; the LLM cannot reach projects in another org even if it knows their IDs.
- PII never leaves the server in tool responses. Verification logs strip IP addresses and user-agent strings before returning to the LLM.
- Plaintext secrets surface once. API keys, webhook signing secrets, and project signing keys are returned in plaintext only at creation/rotation; subsequent reads show metadata only.
- Refresh-token theft detection. Re-using a rotated refresh token revokes the entire chain — both old and new bearers — forcing a fresh login.
Tool scopes
Different tools require different scopes on the bearer token. First-party clients (Claude Desktop, Claude Code) get the full scope set by default at consent time. Third-party clients can request a subset:
projects:read— list / read project metadataprojects:write— change widget mode, project settingsverifications:read— read verification logs and per-question eventsanalytics:read— pass rates, quota, time-serieskeys:write— mint / revoke API keys, rotate signing keyswebhooks:write— CRUD webhooks and test delivery
Not in scope
Some operations stay dashboard-only on purpose — they're admin-sensitive or human-in-the-loop:
- Billing tier changes
- Organization member invitations / removal
- DSR / appeals / legal endpoints
Self-hosted / local stdio MCP
For air-gapped environments or contributors hacking on the tool surface, an older stdio-transport package is available at packages/mcp/ in the repository. It uses Auth0 Device Code flow and runs as a Python subprocess of the LLM client. Most customers should prefer the hosted server — it's zero-install, gets fixes immediately, and doesn't require local Python or env-var configuration.
Troubleshooting
- Connection fails / 401 errors — your tokens may have expired. Most clients re-do the OAuth flow automatically; if not, remove the MCP server from your client config and re-add it. The browser opens for a fresh login.
- "org not found" on a tool call — your bearer is scoped to a specific org. If you belong to multiple, the first one is selected by default; disconnecting and reconnecting lets you pick a different org during consent.
- Rate-limit errors on demo-key minting — the demo-key endpoint is IP rate-limited (10/minute soft, then a short hard block). Slow down and retry.
- Tool says "not_found" for a project I own — that response also covers cross-org access (an existence leak would be a security hole). Confirm you're connected as the right org via the
get_organizationtool.
Issues + roadmap: docs/plans/mcp_hosted_server.md.