---
icon: plug
label: MCP Server
---

# MCP Server

## Overview

The VerifEye MCP Server is a remotely-hosted [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that exposes VerifEye's demographic-estimation capabilities — apparent **age** and **gender** — as tools an AI assistant (such as Claude) can call over Streamable HTTP.

The MCP server enables you to:
- Estimate apparent age and detect gender for faces in an image, directly from an MCP client
- Authenticate once via OAuth — your client never sends an API key
- Choose where each image is processed — in the EU or the US — on every call (data residency)

!!!tip
The MCP server is a thin, OAuth-authenticated layer over the [Demographic Estimation API](/cloud-apis-web-sdks/demographic-estimation-api/). Your account's API key is resolved **server-side** from your login — the client never sees or sends it.
!!!

---

## Prerequisites

- A **VerifEye Developer Console** account — sign in at the [VerifEye Developer Console](https://verifeye-console.realeyes.ai/).
- An **MCP-capable client** that supports remote MCP servers over OAuth (for example, Claude Code, claude.ai, or the Gemini CLI).

---

## Server URL

`https://verifeye-mcp-server.realeyes.ai/mcp`

The server has a single global endpoint. You choose where each image is processed — in the **EU** or the **US** — on every call via the `region` parameter (`eu`/`us`) on each tool, for data residency and compliance. See [Available tools](#available-tools).

---

## Authentication

The MCP server uses **OAuth 2.1** (authorization code with PKCE). Authentication happens through a branded VerifEye login and consent screen — you never put an API key into your MCP client.

### Authorization flow

1. Your MCP client reads the MCP server's protected-resource metadata and discovers the VerifEye authorization server.
2. The client starts an OAuth 2.1 authorization-code flow (with PKCE) and opens the VerifEye login in your browser.
3. You sign in with your VerifEye Developer Console account and approve the **Allow / Deny** consent screen.
4. The authorization server returns a short-lived, signed access token scoped to the MCP server. Your client refreshes it automatically until the refresh window lapses.
5. The client calls the MCP server with that token. The server resolves your account's API key on the server side and calls VerifEye on your behalf — the key is never exposed to the client.

---

## Connecting a client

### Claude Code (CLI)

```bash
claude mcp add --scope user --transport http \
  --client-id verifeye-mcp-claude --callback-port 8080 \
  verifeye https://verifeye-mcp-server.realeyes.ai/mcp
```

Then run `/mcp` in Claude Code, select **verifeye**, and authenticate — the branded VerifEye login opens in your browser. Approve it to connect; the tools become available to the assistant.

### claude.ai (connector)

Add the same URL — `https://verifeye-mcp-server.realeyes.ai/mcp` — through the Connectors UI. The server uses pre-registered OAuth clients and does **not** support automatic client registration, so edit the connector and set the **OAuth Client ID** to `verifeye-mcp-claude`. Then complete the VerifEye login and consent.

### Gemini CLI

The [Gemini CLI](https://github.com/google-gemini/gemini-cli) connects over Streamable HTTP with a pre-registered OAuth client. Add the server to `~/.gemini/settings.json` (merge with any keys already there):

```json
{
  "mcpServers": {
    "verifeye": {
      "httpUrl": "https://verifeye-mcp-server.realeyes.ai/mcp",
      "authProviderType": "dynamic_discovery",
      "oauth": {
        "clientId": "verifeye-mcp-gemini",
        "redirectUri": "http://localhost:7777/oauth/callback",
        "scopes": ["verifeye"]
      }
    }
  }
}
```

Because the server does not support automatic client registration, `clientId` must be set to `verifeye-mcp-gemini`, and `redirectUri` must be pinned to port `7777` — the CLI otherwise picks a random port, which the server rejects. Then run `/mcp auth verifeye` in the CLI to complete the VerifEye login and consent; `/mcp` then lists the available VerifEye tools.

---

## Available tools

### verifeye_estimate_age

Estimates the apparent age of the face(s) in an image.

**Input parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `imageUrl` | string | No | — | Public URL of a JPEG or PNG image. Provide either `imageUrl` or `imageBase64`. |
| `imageBase64` | string | No | — | Base64-encoded JPEG or PNG (no `data:` prefix). Used only when `imageUrl` is not set. |
| `maxFaceCount` | integer | No | `1` | Maximum number of faces to analyze (1–10). |
| `region` | string | No | `eu` | Data-residency region: `eu` or `us`. |

**Result:**

```json
{
  "region": "eu",
  "faces": [
    {
      "faceIndex": 0,
      "estimatedAge": 27.5,
      "uncertainty": 0.2,
      "reliable": true,
      "faceConfidence": 0.999
    }
  ],
  "unprocessedFaceCount": 0
}
```

| Field | Type | Description |
|-------|------|-------------|
| `region` | string | The region the request was processed in. |
| `faces[].faceIndex` | integer | Zero-based index of the face in the result. |
| `faces[].estimatedAge` | number | Estimated apparent age. |
| `faces[].uncertainty` | number | Uncertainty of the estimate (lower is better). |
| `faces[].reliable` | boolean | `false` when the estimate is unreliable (uncertainty above 1.0). Prefer this flag over the raw age. |
| `faces[].faceConfidence` | number | Face-detection confidence (0.0–1.0). |
| `unprocessedFaceCount` | integer | Faces detected but not analyzed (beyond `maxFaceCount`). |

---

### verifeye_detect_gender

Detects the apparent gender (Male or Female) of the face(s) in an image.

**Input parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `imageUrl` | string | No | — | Public URL of a JPEG or PNG image. Provide either `imageUrl` or `imageBase64`. |
| `imageBase64` | string | No | — | Base64-encoded JPEG or PNG (no `data:` prefix). Used only when `imageUrl` is not set. |
| `maxFaceCount` | integer | No | `1` | Maximum number of faces to analyze (1–10). |
| `region` | string | No | `eu` | Data-residency region: `eu` or `us`. |

**Result:**

```json
{
  "region": "eu",
  "faces": [
    {
      "faceIndex": 0,
      "gender": "Female",
      "faceConfidence": 0.999
    }
  ],
  "unprocessedFaceCount": 0
}
```

| Field | Type | Description |
|-------|------|-------------|
| `region` | string | The region the request was processed in. |
| `faces[].faceIndex` | integer | Zero-based index of the face in the result. |
| `faces[].gender` | string | Detected gender — `Male` or `Female`. |
| `faces[].faceConfidence` | number | Face-detection confidence (0.0–1.0). |
| `unprocessedFaceCount` | integer | Faces detected but not analyzed (beyond `maxFaceCount`). |

---

## Notes & limitations

- **Estimates, not legal proof.** Age is an *apparent-age* estimate, not a legal proof of age; gender is a demographic estimate, not a self-declared identity attribute.
- **Honor the `reliable` flag.** For age, treat the result as unreliable when `reliable` is `false` (the model's uncertainty exceeds 1.0).
- **Images.** JPEG or PNG only, supplied as a publicly reachable URL or as raw base64 (no `data:` prefix). The server fetches `imageUrl` itself, so it must be reachable. Up to 10 faces per call; extra detected faces are reported in `unprocessedFaceCount`.
- **Region & residency.** `region` (`eu`/`us`) selects where the image is processed. Your account must be authorized in the chosen region.
- **Usage.** Tool calls run as your VerifEye account and count against your account's usage limits.

---

## Additional Resources

- [Model Context Protocol specification](https://modelcontextprotocol.io/) — the open protocol the server implements.
- [Demographic Estimation API](/cloud-apis-web-sdks/demographic-estimation-api/) — the underlying REST API the tools call.
- [Authentication](/cloud-apis-web-sdks/authentication/) — API key and bearer-token authentication for the REST APIs.

---

*Last updated: 2026-06-26*
