MCP Server

Overview

The VerifEye MCP Server is a remotely-hosted Model Context Protocol (MCP) server that exposes VerifEye's face capabilities — analysis, recognition and the collections recognition needs — as tools an AI assistant (such as Claude) can call over Streamable HTTP.

The MCP server enables you to:

  • Analyze the face(s) in an image for apparent age and gender, plus momentary emotions and attention
  • Onboard a face so the same person is identified on a later image, and compare one image against one onboarded face
  • Manage the collections onboarded faces live in, and label a face with your own identifier
  • 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)

Your MCP client may ask you to confirm rather more than those. Seven of the thirteen tools carry the protocol's destructiveHint, which many clients turn into a confirmation prompt: the four named above, plus verifeye_identify_face, verifeye_compare_face and verifeye_delete_face_key. The two analysis tools carry it because each consumes the image it is given — an uploaded image is deleted once the call is done, so the same uploadId cannot be analyzed a second time — and because the call is metered. verifeye_delete_face_key carries it because a face whose key is gone can be hard to find again. None of those three destroys a face template.


Prerequisites

  • A VerifEye Developer Console account — sign in at the VerifEye Developer Console.
  • An MCP-capable client that supports remote MCP servers over OAuth — see Connecting a client for the ones with worked configurations.

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 every tool, for data residency and compliance. Collections are per region: one created in eu is not visible from us, and a collection that seems to have gone missing is very often in the other region. See Available tools.

The server is listed in the official MCP Registry as ai.realeyes/verifeye. Its registry entry (JSON) lists the same server URL. The URL above is the server's only address: if a registry or directory lists a different one, do not connect to it, and contact us.


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

Every client needs two things: the server URL

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

and a way to identify itself. Claude Code, Claude, Cursor and the Gemini CLI use a pre-registered client ID — the name you will see on the consent screen — and their tab gives the exact value. ChatGPT, VS Code and Codex identify themselves instead by publishing a Client ID Metadata Document and sending its URL, so for those there is nothing to enter. The server offers no dynamic client registration, so a client that expects to register itself on the fly needs one of the IDs below. There is no client secret either way: every client here is a public client and the flow is secured with PKCE.

When you connect, VerifEye opens in your browser: sign in with your Developer Console account and approve the consent screen. An application VerifEye recognises is named there, with the logo it publishes for itself. An application that identified itself with a metadata document from an address VerifEye does not recognise is shown by that address alone — no name, no logo — because anyone who controls the address chooses what it claims. Either screen shows where the authorization will be delivered. Read it, and approve only if you have just started this sign-in yourself — that is the check that holds, because a name and a local address are the two things an application asking on another's behalf can copy.

claude mcp add --scope user --transport http \
  --client-id verifeye-mcp-claude --callback-port 8080 \
  verifeye https://verifeye-mcp-server.realeyes.ai/mcp
  1. Run /mcp and select verifeye.
  2. Authenticate in the browser window that opens.
  3. Run /mcp again — the VerifEye tools are listed.

Both flags are required. --client-id names the pre-registered client, and --callback-port 8080 makes the loopback redirect match the one registered for it. Without --client-id the client tries to register itself, which this server does not offer, and the sign-in ends with invalid_client. With a different callback port it ends with invalid_request and "The specified 'redirect_uri' is not valid for this client."

On claude.ai, and in Claude Desktop — a custom connector is brokered through your Claude account rather than from your own machine, so one entry serves both.

A custom connector is available on the Free, Pro, Max, Team and Enterprise plans, but not everyone on them can add one. On Pro and Max you add it yourself, and the Free plan allows one custom connector in total. On Team and Enterprise only an Owner can add it: the Owner adds it once for the organization under Organization settings → Connectors, and members then connect to it from Customize → Connectors. See Anthropic's guide to custom connectors for the current steps.

  1. Open Customize → Connectors (Settings → Connectors on some plans), click +, then Add custom connector.
  2. Enter the server URL: https://verifeye-mcp-server.realeyes.ai/mcp
  3. Click Continue. Under OAuth client, choose Use your own OAuth client and enter the OAuth client ID: verifeye-mcp-claude. Leave the client secret empty, then click Add.
  4. Sign in with your VerifEye account when prompted.

ChatGPT sends a metadata document, so there is no client ID to enter.

A custom MCP connector needs ChatGPT Developer mode, which is available on the Pro, Plus, Business, Enterprise and Education plans on the web — not the Free plan. Turn it on first in Settings → Security and login; see OpenAI's Developer mode guide for the current steps.

  1. Go to Settings → Plugins → Browse plugins, then click the + button.
  2. Give it a Name and, under Connection, enter the Server URL: https://verifeye-mcp-server.realeyes.ai/mcp
  3. Leave Authentication on OAuth.
  4. Tick I understand and want to continue, then click Create.
  5. Sign in with your VerifEye account when prompted.

VS Code sends a metadata document, so there is no client ID to enter.

Install VerifEye MCP in VS Code

Or add .vscode/mcp.json to your project root:

{
  "servers": {
    "verifeye": { "type": "http", "url": "https://verifeye-mcp-server.realeyes.ai/mcp" }
  }
}

Start the server from the MCP: List Servers command, then sign in when the browser opens.

Cursor's client ID goes under auth: verifeye-mcp-cursor.

Add VerifEye MCP server to Cursor

Or add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "verifeye": {
      "url": "https://verifeye-mcp-server.realeyes.ai/mcp",
      "auth": { "CLIENT_ID": "verifeye-mcp-cursor" }
    }
  }
}

Restart Cursor if the server does not appear or the sign-in does not complete — Cursor picks a fixed callback port, and a stale one can leave it stuck.

The Gemini CLI's client ID goes under oauth: verifeye-mcp-gemini. By default it takes whatever loopback port the operating system hands it, which would match nothing registered here, so redirectUri below pins it to 7777 — keep it as shown. The authProviderType: dynamic_discovery below selects OAuth endpoint discovery — it does not mean the self-registration this server lacks. Add to ~/.gemini/settings.json, merging with any keys already there:

{
  "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"]
      }
    }
  }
}
  1. Run /mcp auth verifeye and sign in.
  2. Run /mcp — the VerifEye tools are listed.

The Codex desktop app uses your ChatGPT connectors. Add VerifEye once as a custom connector — the same steps as the ChatGPT tab above, and ChatGPT Developer mode is required — and it then appears in Codex under Apps, ready to call.

Do not add it from Codex's own MCPs → Add server list: that Authenticate step does not complete. Use the connector.


Providing the image

Three tools take an image — verifeye_identify_face, verifeye_onboard_face and verifeye_compare_face — and each takes it as a public URL. The URL is passed through to the VerifEye Face API, which fetches the image itself: the MCP server never downloads it. None of them accepts the image inline as base64. Inline base64 would mean the assistant writing the encoded image out token by token, which for any image large enough to be usable costs far more time and quota than fetching a URL.

This has one practical consequence: an image attached to the conversation cannot be passed to a tool. The assistant can see such an image but cannot hand the bytes to a tool as an argument. Put the image somewhere reachable and give the assistant that link. Prefer an object-storage pre-signed link that expires in minutes; a durably public URL works too, and exposes the face for as long as it is there. Where the client can reach the internet itself, it can upload the image instead — see If you have no URL: upload the image below.

For a usable result the image should also meet the image requirements: an RGB JPEG or PNG, 300x300 to 2000x2000 pixels and 50–2000 KB, with the face centered, upright, at least 150x150 pixels, and covering 20–80% of the frame.

If you have no URL: upload the image

Where the server offers verifeye_get_upload_url, a client can upload the image instead. The tool hands back a short-lived form, the client posts the file to VerifEye storage, and the image tool then takes the returned uploadId in place of imageUrl — see Available tools for the form and the POST. The image is stored in the region you asked for, deleted the moment the first tool call that uses it returns, and removed by a daily lifecycle sweep if no call ever comes, so nothing is left published anywhere.

This needs a client that can make an outbound HTTPS request of its own, and many cannot. An assistant that runs your tools inside a locked-down sandbox — a browser-based assistant, or a desktop app that runs commands in a container with no egress — does not reach storage at all, and fails with a DNS or connection error rather than a VerifEye one. A command-line client on your own machine has no such limit. A public URL works in both, which is why it stays the path to reach for first.

These tools process facial (biometric) data, and one of them stores it. You are responsible for obtaining valid, informed consent for that processing before a call runs, and for meeting the requirements of the privacy and biometric-data regulations that apply to the people in your images (e.g. GDPR, BIPA, CCPA). In most places a face template is personal data; in many it is special-category data needing explicit consent. See the Realeyes Privacy Policy.

Three things follow, and they are specific to these tools:

  • Prefer a short-lived pre-signed link to a durably public URL. Publishing a face at a stable address exposes it to anyone who finds the address, for as long as it is there. A link that expires in minutes does not.
  • Remove the image once the call has returned. VerifEye does not keep the image — not even on onboarding, where what is stored is the template derived from it — and neither should the place you put it for the one call that needed it.
  • Onboarding outlives the conversation. verifeye_onboard_face creates a face template that persists until something deletes it, and the assistant that created it will not remember it tomorrow. Write down the faceId it returns, or attach an externalKey you can look the face up by, and keep your own record of who consented to what. verifeye_delete_face is how you honour an erasure request.

Available tools

Thirteen tools, in four groups. Every one of them takes region (eu/us, eu by default) and every result echoes it, because a conversation that has called in both regions has no other way to tell one answer from another.

Tool What it does Stores or destroys data
verifeye_identify_face Analyzes the face(s) in an image, and identifies them against a collection if you name one No
verifeye_onboard_face Onboards the face(s) in an image into a collection so the person is identified later Stores a face template
verifeye_compare_face Compares the face(s) in an image against one onboarded face No
verifeye_delete_face Deletes one onboarded face Irreversible
verifeye_list_collections Lists the collections on the account, or checks whether one exists No
verifeye_create_collection Creates an empty collection No
verifeye_set_collection_description Replaces a collection's description No
verifeye_reset_collection Deletes every face in a collection, keeping the collection Irreversible
verifeye_delete_collection Deletes a collection and every face in it Irreversible
verifeye_get_face_by_key Finds an onboarded face by your own identifier No
verifeye_set_face_key Attaches your own identifier to an onboarded face No
verifeye_delete_face_key Removes your identifier from an onboarded face Loses the way of finding the face
verifeye_get_upload_url Hands back a short-lived form for uploading one image No

A tool that fails does so with a code you can branch on — see Errors.

verifeye_identify_face

Analyzes the face(s) in an image and returns the attributes you ask for — apparent age, apparent gender, momentary emotions and momentary attention — from a single VerifEye Face API Identify call. Age and gender are on by default. Emotions and attention are off by default and add a surcharge on every face the call answers about — a fraction of what that face already costs, not a second charge: requesting either emotions or attention applies it, and requesting both does not apply it twice. Turn them on only when you need them.

Pass collectionId to also identify the faces against a collection you have onboarded into. Nothing is ever onboarded by this tool, with or without a collection: a face the collection does not hold comes back as NotExisting with no faceId. That is what makes this, rather than verifeye_onboard_face, the way to check whether a face is already known.

Input parameters:

Parameter Type Required Default Description
imageUrl string One of the two — Public URL of a JPEG or PNG image. See Providing the image.
uploadId string One of the two — Id from verifeye_get_upload_url, once the image has been uploaded to it. Supply imageUrl or uploadId, never both.
collectionId string No — Identify against this collection of onboarded faces. Omit for an anonymous analysis.
age boolean No true Estimate apparent age.
gender boolean No true Detect apparent gender (Male/Female).
emotions boolean No false Detect momentary emotions. Adds a surcharge per face — see above.
attention boolean No false Detect momentary attention signals. Adds a surcharge per face — see above.
maxFaces integer No 1 Maximum number of faces to analyze (1–4).
region string No eu Data-residency region: eu or us.

Enable at least one of age, gender, emotions or attention — a call with all four turned off is rejected.

Result:

Only the attributes you request are included; age, gender, emotions and attention are each omitted when their flag is off. The identity fields — faceId, faceStatus and externalKey — appear only when you passed a collectionId.

{
  "region": "eu",
  "collectionId": "customer-faces",
  "faces": [
    {
      "faceConfidence": 0.999,
      "faceId": "8f14e45f-ceea-467a-9d1f-3c2b7a0f51d2",
      "faceStatus": "Existing",
      "externalKey": "customer-4417",
      "age": { "estimatedAge": 27.5, "uncertainty": 0.2, "reliable": true },
      "gender": "Female",
      "emotions": { "present": ["happiness"], "undetermined": ["empathy"] },
      "attention": { "present": ["presence", "eyesOnScreen"], "undetermined": [] }
    }
  ],
  "unprocessedFaceCount": 0
}
Field Type Description
region string The region the request was processed in.
collectionId string The collection the faces were looked up in. Without a collectionId of your own this is the server's own analysis collection — see Under the hood.
faces[].faceConfidence number Face-detection confidence (0.0–1.0). This is detection confidence, not attribute confidence.
faces[].faceId string The onboarded face this one matched. Present only when you passed a collectionId, and only for a face the collection holds.
faces[].faceStatus string Existing for a face the collection holds, NotExisting for one it does not. Present only when you passed a collectionId.
faces[].externalKey string Your own identifier for the matched face, where it carries one. Present only when you passed a collectionId.
faces[].age object Absent when age was not requested, and also when the model produced no estimate — see Absent versus undetermined.
faces[].age.estimatedAge number Estimated apparent age.
faces[].age.uncertainty number Uncertainty of the estimate (lower is better). A unitless image-quality score from 0 upwards — not a margin of error, and not a number of years.
faces[].age.reliable boolean false when the estimate is unreliable (uncertainty above 1.0). Prefer this flag over the raw age. Absent when there is no uncertainty to judge it by, which is not the same as false.
faces[].gender string Detected gender — Male or Female. Present only when gender was requested.
faces[].emotions object Absent when emotions was not requested, and also when the model had nothing to report — see Absent versus undetermined.
faces[].emotions.present string[] Emotions observed on this frame.
faces[].emotions.undetermined string[] Emotions that could not be determined.
faces[].attention object Absent when attention was not requested, and also when the model had nothing to report — see Absent versus undetermined.
faces[].attention.present string[] Attention signals observed on this frame.
faces[].attention.undetermined string[] Attention signals that could not be determined.
unprocessedFaceCount integer Faces detected but not analyzed — those beyond maxFaces, plus any beyond the detector's own limit.

A face the Face API cannot answer for with sufficient confidence has no entry in faces at all, and is not counted in unprocessedFaceCount — so faces can hold fewer entries than the image holds faces even when unprocessedFaceCount is 0. See Face detection restrictions.

The result carries no position and no index: the faces array is ordered by how dominant each face is on the image, not by where it is, so with maxFaces above 1 the position in the array does not say which answer belongs to which person. Where you need that, verifeye_compare_face returns boundingBox for every face it compares, and calling Identify directly returns faces[].face.boundingBox.

Absent versus undetermined

These are two different answers and the result keeps them apart.

An absent attribute was not analyzed. Either you did not request it, or the model that owns it had nothing to report for this face. The tool does not distinguish those two, and neither does the VerifEye Face API underneath it: in both cases the attribute is simply not there.

A signal named in a present group's undetermined list is the opposite claim: the analysis ran, and could not decide that one signal. So "emotions": {"present": ["happiness"], "undetermined": ["surprise"]} means surprise was looked for and could not be told, while no emotions key at all means nothing was looked for. Do not treat a missing attribute as a set of undetermined signals.

Reading emotions and attention

verifeye_onboard_face

Onboards the face(s) in an image into a collection, so the same person is identified by verifeye_identify_face or verifeye_compare_face later. The collection must already exist — create it with verifeye_create_collection.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection to onboard into. It must already exist.
imageUrl string One of the two — Public URL of a JPEG or PNG image. See Providing the image.
uploadId string One of the two — Id from verifeye_get_upload_url. Supply imageUrl or uploadId, never both.
externalKey string No — Your own identifier for the onboarded face, unique within the collection. Requires maxFaces of 1.
maxFaces integer No 1 Maximum number of faces to onboard (1–4). Every face on the image is onboarded, so keep this at 1 unless you mean to onboard everyone in the photo.
region string No eu Data-residency region: eu or us.

Result:

{
  "region": "eu",
  "collectionId": "customer-faces",
  "faces": [
    {
      "faceId": "8f14e45f-ceea-467a-9d1f-3c2b7a0f51d2",
      "faceStatus": "New",
      "externalKey": "customer-4417",
      "faceConfidence": 0.998
    }
  ],
  "unprocessedFaceCount": 0,
  "externalKeyAssigned": true
}
Field Type Description
region string The region the face was onboarded in.
collectionId string The collection the face was onboarded into.
faces[].faceId string The onboarded face. This is the only handle to it — write it down, or give the face an externalKey.
faces[].faceStatus string New for a face VerifEye had not seen in this collection, Existing when the same person was already onboarded — in which case nothing new was stored.
faces[].externalKey string The identifier attached to the face, when one was asked for and it stuck.
faces[].faceConfidence number Face-detection confidence (0.0–1.0).
unprocessedFaceCount integer Faces detected but not onboarded — those beyond maxFaces, plus any beyond the detector's own limit.
externalKeyAssigned boolean Absent unless an externalKey was asked for. false means the face was onboarded but the key was not attached.
externalKeyError string Why the key was not attached. Present only when externalKeyAssigned is false.
externalKeyErrorCode string The error code for that failure — external_key_in_use, say — so you can branch on it rather than on the wording. Absent when no face was onboarded, since there was then nothing to attach a key to.

The external key is attached by a second call, because the Face API's onboard takes no key: by the time it runs, the face is already in the collection. So a failure there does not fail the onboarding — the face comes back either way, and externalKeyAssigned, externalKeyError and externalKeyErrorCode say that the key did not stick and why. Retry it with verifeye_set_face_key.

A face with neither a remembered faceId nor an external key can afterwards be removed only by emptying the whole collection, which is why both of those fields matter more here than anywhere else on this page.

verifeye_compare_face

A one-to-one check: compares the face(s) in an image against one face already onboarded in a collection, and answers how similar each is. Use it when you know whose face you are checking against — to search a collection for whoever the image shows, use verifeye_identify_face with the collectionId instead. Nothing is onboarded by this call and the submitted image is not added to the collection.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection holding the onboarded face.
faceId string Yes — The onboarded face to compare against, from verifeye_onboard_face or verifeye_get_face_by_key.
imageUrl string One of the two — Public URL of a JPEG or PNG image. See Providing the image.
uploadId string One of the two — Id from verifeye_get_upload_url. Supply imageUrl or uploadId, never both.
maxFaces integer No 1 Maximum number of faces on the submitted image to compare (1–4).
region string No eu Data-residency region: eu or us.

Result:

{
  "region": "eu",
  "collectionId": "customer-faces",
  "faceId": "8f14e45f-ceea-467a-9d1f-3c2b7a0f51d2",
  "faces": [
    {
      "similarity": 98,
      "isMatch": true,
      "faceConfidence": 0.998,
      "boundingBox": { "x": 412, "y": 96, "width": 208, "height": 262 }
    }
  ],
  "unprocessedFaceCount": 0
}
Field Type Description
region string The region the comparison ran in.
collectionId string The collection holding the onboarded face.
faceId string The onboarded face that was compared against.
faces[].similarity integer How similar this face is to the onboarded one, 0–100.
faces[].isMatch boolean VerifEye's own verdict at its match threshold. Read this rather than setting your own cut-off on similarity.
faces[].faceConfidence number Face-detection confidence (0.0–1.0).
faces[].boundingBox object Pixel position of this face in the submitted image, origin top-left: x, y, width, height. This tool alone returns it, and it is how to say which face on a group photo matched.
unprocessedFaceCount integer Faces detected but not compared — those beyond maxFaces, plus any beyond the detector's own limit.

With maxFaces at 1, whether the person is on the image at all is simply faces[0].isMatch.

verifeye_delete_face

Deletes one onboarded face. This is the tool to use when someone asks for their face data to be erased.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection holding the face.
faceId string Yes — The face to delete.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the face was deleted in.
collectionId string The collection it was deleted from.
faceId string The face that was deleted.
deleted boolean true when the face is gone.

verifeye_list_collections

Lists the face collections on the account in one region, or checks whether one particular collection exists if you pass collectionId. It reads nothing about the faces inside, and onboards nothing. Use it before onboarding or deleting anything, so you work against a collection that is really there rather than a name you assumed.

Input parameters:

Parameter Type Required Default Description
collectionId string No — Check for this one collection instead of listing them all.
limit integer No 50 Maximum collections to return (1–200).
region string No eu Data-residency region: eu or us.

Result:

{
  "region": "eu",
  "collections": [
    {
      "collectionId": "customer-faces",
      "description": "Returning customers at the front desk",
      "createdAt": "2026-08-14T09:21:04Z",
      "updatedAt": "2026-09-02T11:47:55Z"
    }
  ],
  "totalCount": 1,
  "truncated": false,
  "found": true
}
Field Type Description
region string The region that was listed.
collections[].collectionId string The collection's id.
collections[].description string What it is for. Absent rather than empty when the account never set one.
collections[].createdAt string When it was created.
collections[].updatedAt string When it was last changed.
totalCount integer Without a collectionId, how many collections the account has in this region, which can be more than collections holds. With one, 1 if that collection exists and 0 if it does not.
truncated boolean true when limit cut the list short.
found boolean With a collectionId, whether that collection exists. Without one, whether the account has any collections at all.

Collections are per region. One created in eu is not visible from us, and a collection that seems to be missing is very often in the other region.

verifeye_create_collection

Creates an empty collection to onboard faces into. Nothing is destroyed by this call, and an empty collection costs nothing to keep.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — Id for the new collection: 1–512 characters of letters, digits, dot, underscore and dash. No spaces and no accented letters.
description string No — What the collection is for, for whoever reads the list later (up to 1024 characters).
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the collection was created in.
collectionId string The new collection's id.
created boolean true. A collection that already existed is a failure with its own code, not a quiet success.

The id is permanent: there is no way to rename a collection afterwards, only to change its description. If a collection with that id already exists the call fails with collection_exists and creates nothing — and that existing collection may hold faces that are not yours to add to, so check with verifeye_list_collections first. The collection is created in one region only; create it again in the other region if you need it there.

verifeye_set_collection_description

Replaces a collection's description — the free text that says what it is for. The collection's id and the faces in it are not touched.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection to describe.
description string Yes — The new description, replacing whatever is there (up to 1024 characters). To clear it, pass a single space.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the collection lives in.
collectionId string The collection that was described.
description string The text it now carries.

It replaces rather than appends, so pass the full text you want, and read the current one with verifeye_list_collections first if you mean to extend it.

verifeye_reset_collection

Deletes every face in a collection. The collection itself stays, empty. To remove one person, use verifeye_delete_face; to remove the collection as well, use verifeye_delete_collection.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection to empty.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the collection lives in.
collectionId string The collection that was emptied.
facesRemoved integer How many faces were destroyed — null, because the Face API's reset response names the collection and nothing else. There is no way to report afterwards how much was destroyed.

verifeye_delete_collection

Deletes a collection and every face in it.

Before deleting, the tool reads the account's verification configurations in that region. If any of them routes face data into this collection, the call fails with collection_in_use and names them. That refusal cannot be overridden from here — a verification still pointing at the collection means deleting it would break live verifications for real users, so the verification has to be changed in the VerifEye Developer Console first. If the check itself cannot be completed the call fails with collection_usage_unknown and deletes nothing.

The check reads up to 50 verification configurations. An account with more than that gets collection_usage_unknown rather than a delete the server cannot vouch for; delete the collection from the Developer Console instead.

The check is made with the account's own VerifEye credentials: one call to list the account's verification configurations, then one read for each configuration returned — up to 50 — before anything is deleted. A delete is therefore slower than the single call it looks like from the outside, and slower the more verification configurations the account has.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection to delete.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the collection was deleted in.
collectionId string The collection that was deleted.
deleted boolean true when the collection is gone.

verifeye_get_face_by_key

Looks up which onboarded face carries one of your own identifiers, and returns its faceId. Use it to turn a customer number or member id back into the faceId that verifeye_compare_face and verifeye_delete_face need. It reads nothing about the face itself: no image, no attributes, nothing biometric.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection to look in.
externalKey string Yes — Your own identifier for the face.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region that was searched.
collectionId string The collection that was searched.
externalKey string The key asked about, echoed either way.
found boolean Whether a face holds the key.
faceId string The face holding it. Absent when found is false.

A key no face holds is a normal answer, not an error: found is false and there is no faceId. That is also how to check a key is free before assigning it. A collection that does not exist is a different thing — that fails with collection_not_found, so do not treat the two alike.

verifeye_set_face_key

Attaches one of your own identifiers to a face already onboarded in a collection, so you can find it again with verifeye_get_face_by_key without remembering the faceId. No face data is changed or destroyed — this only labels it.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection holding the face.
faceId string Yes — The onboarded face to label, from verifeye_onboard_face.
externalKey string Yes — Your own identifier: 1–512 printable ASCII characters, no spaces and no accented letters.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the face lives in.
collectionId string The collection holding the face.
faceId string The face that was labelled.
externalKey string The key it now carries.
result string Created when the face had no key, Updated when it did and the key replaced it.

A key belongs to exactly one face. If another face already holds it the call fails with external_key_in_use and nothing is changed — check first with verifeye_get_face_by_key, and release it with verifeye_delete_face_key if it needs to move.

verifeye_delete_face_key

Removes the link between one of your own identifiers and the face that holds it. The face itself is not deleted and stays onboarded — to delete the face, use verifeye_delete_face.

Input parameters:

Parameter Type Required Default Description
collectionId string Yes — The collection holding the face.
externalKey string Yes — Your own identifier to remove.
faceId string Yes — The face that holds it — look it up with verifeye_get_face_by_key if you do not have it.
region string No eu Data-residency region: eu or us.

Result:

Field Type Description
region string The region the face lives in.
collectionId string The collection holding the face.
externalKey string The key that was removed.
faceId string The face it was removed from.
deleted boolean true when the key is no longer linked.

faceId is required here, and is checked against the key. The Face API would accept the removal without one and unlink the key from whichever face happens to hold it — which is a different operation from the one a caller who named a face is asking for, and would quietly unlink someone else's.

verifeye_get_upload_url

Hands back a short-lived form for uploading one image to VerifEye storage, for a client that has an image but nowhere public to put it. It is registered only where the server serves uploads: a client that does not see it in tools/list has to supply a URL.

Input parameters:

Parameter Type Required Default Description
region string No eu Data-residency region: eu or us. Use the same region for the tool that consumes the image — it is stored in the one named here.

Result:

Field Type Description
uploadId string Pass this to an image tool as uploadId, in place of imageUrl.
uploadUrl string The address to send the image to.
method string The HTTP method to use.
fields object Name/value pairs that have to be sent with the file, unchanged and in the order returned.
expiresInSeconds integer How long the form stays valid — five minutes.
region string The region the image is stored and analyzed in.

Sending the image: one multipart/form-data POST to uploadUrl, with every entry of fields first, in the order returned, and the file last in a part named file. Storage refuses the upload if a field is missing, altered or sent after the file. The accepted size, 1–2000 KB, is inside the form's signature, so an over-size image is refused at ingress rather than after it is stored.

Then call one of the image tools — verifeye_identify_face, verifeye_onboard_face or verifeye_compare_face — with uploadId instead of imageUrl; supplying both is rejected. The image is deleted the moment that call returns, so an uploadId is good for one call.


Errors

A tool that fails raises an MCP error whose text is one line of JSON:

{
  "code": "collection_not_found",
  "message": "VerifEye found no such collection in the 'eu' region (404). Collections are per region, so one created in the other region is not visible here.",
  "retryable": false,
  "nextStep": "List what exists with verifeye_list_collections, in this region and in the other."
}

code is the stable half and is what to branch on — the message wording is free to change. retryable says whether repeating the same call could succeed. nextStep is absent when there is nothing useful to suggest.

Code Means
invalid_argument An argument is missing, malformed or not allowed. Most are caught by the MCP server before VerifEye is asked; the same code is also returned when VerifEye itself rejects the arguments with a 400.
image_unusable VerifEye could not use the image — it could not be fetched, decoded, or was too large.
account_not_resolved The account behind this MCP session could not be resolved, or has no VerifEye API key.
unauthorized VerifEye rejected the credentials.
forbidden The account is not entitled to the operation in this region.
collection_not_found The named collection does not exist in this region. Collections are per region.
face_not_found No such face in that collection in this region. The face id may be wrong, the collection may be wrong, or both may exist in the other region — the call cannot tell which. A face that was already deleted answers the same way.
collection_exists A collection with this id already exists, and nothing was created.
external_key_in_use The external key is already attached to a different face, and nothing was changed.
collection_in_use A verification configuration routes face data into this collection, so it was not deleted. Not overridable — change the verification in the Developer Console first.
collection_usage_unknown Whether the collection is in use could not be established, so it was not deleted.
quota_exceeded The account has exceeded its quota or rate limit.
timeout VerifEye did not answer inside the tool's time box.
upstream_error VerifEye answered, but not with anything the tool can use.

Under the hood

The tools wrap the VerifEye Face API's Identify, Onboard and Compare operations and its collection endpoints, one tool per operation, with the account's API key resolved server-side from your login.

Identify requires a collection to run against, even when you are not identifying anyone. So for an anonymous analysis — verifeye_identify_face with no collectionId — the server uses a default collection of its own named mcp-default-collection, and creates it on the account the first time it is needed. Because Identify never adds a face, that collection stays empty: no face from an MCP call is ever onboarded into it, which is also why the server refuses an attempt to onboard into it. You never name or manage it yourself; it appears in verifeye_list_collections because it is a real collection on your account.

Faces you do onboard go into collections you create and name. Those are ordinary VerifEye collections, visible to the VerifEye Face API and to the Developer Console, and usable from your own backend — the MCP server holds nothing of its own beyond them.


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. A face match is evidence of similarity, not an identity check on its own.
  • Emotions and attention are momentary. Single-frame yes/no observations, never scores — see Reading emotions and attention.
  • Honor the reliable flag. For age, treat the result as unreliable when reliable is false (the model's uncertainty exceeds 1.0). If the flag is absent there was nothing to judge the estimate by, so do not read that as reliable.
  • Onboarding is the only tool that stores anything. verifeye_identify_face and verifeye_compare_face add nothing to a collection. verifeye_onboard_face stores a face template that persists until it is deleted — see Consent and retention are your responsibility.
  • Deletion cannot be undone. verifeye_delete_face, verifeye_reset_collection and verifeye_delete_collection destroy face templates permanently, and verifeye_reset_collection cannot report how many it destroyed.
  • Images. JPEG or PNG only, supplied as a publicly reachable URL, or uploaded with verifeye_get_upload_url where the client can reach storage — see Providing the image. Up to 4 faces per call; extra detected faces are reported in unprocessedFaceCount.
  • Collection ids. 1–512 characters of letters, digits, dot, underscore and dash. Permanent — a collection cannot be renamed, only described.
  • External keys. 1–512 printable ASCII characters with no spaces. One key belongs to exactly one face.
  • Region & residency. region (eu/us) selects where the image is processed and where a collection lives. Your account must be authorized in the chosen region, and a collection created in one region is invisible from the other.
  • Usage. Tool calls run as your VerifEye account and count against your account's usage limits. An image call is charged per face it answers about, and a call that finds no face still counts as one, because the detector ran. emotions and attention are an add-on: they do not add a second charge, they surcharge those same faces at the rate in your plan. Requesting either applies it; requesting both does not apply it twice.

Additional Resources


Last updated: 2026-10-12