Skip to Content
ConceptsOperator verification
Open in Claude Open in ChatGPT

Operator verification

When an agent calls an MCP server or a platform, the request goes to an endpoint someone operates. Operator verification (called counterparty verification in the API and audit log) checks who operates that endpoint, from public evidence, and shows the result as a badge on the platform.

It checks identity, not quality. A verified badge tells you which domain serves the endpoint and, at the higher level, that the operator listed it in the official MCP Registry under that domain. It does not tell you the server is well run, honest, or fit for your data. Those are still your calls to make.

Enterprise. Operator verification is included on the Enterprise plan and switches on automatically when an organisation moves to Enterprise. On other plans the badges, the report and the policy setting do not appear; see Pricing & plans.

The levels

Each endpoint gets one level, worked out from the checks that currently pass. It is never stored as a simple yes or no.

LevelWhat it means
UnverifiedThe checks ran, and none of them confirmed who operates the endpoint.
Domain verifiedThe endpoint serves valid HTTPS on a public address, on a domain AgentValet could identify.
Listed in MCP RegistryDomain verified, and the official MCP Registry lists this server, at this address, under a namespace bound to that same domain.

The levels are ordered: Unverified, then Domain verified, then Listed in MCP Registry. Listed in MCP Registry needs the domain check to pass too.

Unverified is a neutral result, not a warning. Plenty of legitimate servers are unverified, for example an internal tool or a new server that isn’t in the registry yet.

States without a level

Two states mean AgentValet has not reached a conclusion, so there is no level to show:

  • Not yet checked. No check has finished for this endpoint yet. A catalog platform with no endpoint address on record also shows this, because there is nothing to check.
  • Check unavailable. The checks ran but could not reach the sources they need (for example, a timeout). This is different from Unverified: Unverified means the checks worked and found nothing.

What is checked

There are three automated checks (sources). Separately, an admin can approve a version of a server (see Approved versions).

1. Domain

AgentValet connects to the endpoint’s host over HTTPS. The check passes when the host answers with a certificate the runtime’s trust store accepts, at a public IP address. AgentValet then works out the registrable domain (the part you buy from a registrar, such as linear.app for mcp.linear.app).

What it proves: the endpoint is served from that domain.

What it does not prove: which company owns the domain. A look-alike domain such as linear-app.io would pass for itself. Read the domain in the badge, not just the level.

2. Official MCP Registry

AgentValet looks the server up in the official MCP Registry (registry.modelcontextprotocol.io, API v0.1). The check passes when an active, latest entry has a remote URL whose host is exactly the endpoint’s host, and the entry’s namespace is a reverse-DNS name (for example app.linear/linear, which maps to linear.app) with the endpoint host under that domain and both on the same registrable domain.

The registry checks that a publisher owns its namespace when it publishes (by DNS or HTTP for reverse-DNS names, and by GitHub sign-in for io.github names). It does not check that the remote URLs in an entry are on that domain. AgentValet makes that check itself, which is why a listing under someone else’s namespace does not count.

An io.github.<org> namespace does not count, even when its remote is on the endpoint’s host. GitHub sign-in proves a GitHub account, not a domain, and nothing public ties a GitHub organisation to a domain reliably enough to lift a level. Such an entry shows as a near miss (“Listed under a GitHub namespace”). When several entries qualify, the one with the alphabetically first namespace is reported, so the result does not change with the registry’s ordering.

This source applies only to MCP servers. For other platforms it shows as not applicable.

3. Operator identity statement (self-declared)

An operator can publish a signed statement naming itself, at https://{domain}/.well-known/merchant-identity.json. This follows the Merchant Identity Assertion draft (draft-anders-merchant-identity-assertions, using the verification procedure from its -02 revision, wire version 1).

AgentValet verifies the statement strictly:

  • media type application/merchant-identity+json, strict JSON (duplicate keys are rejected), and the required claims present
  • proof type MerchantIdentityProof-v1, algorithm Ed25519, and proof.created equal to issuedAt
  • the verification method is issuer.keyDirectory#kid, on the issuer’s own domain
  • the key comes from a JWKS entry with kty OKP, crv Ed25519 and use sig
  • the Ed25519 signature covers the claims in RFC 8785 (JCS) canonical form
  • the statement is inside its validity window
  • the subject is the endpoint’s registrable domain

A statement issued by a third party also needs the subject domain’s authorisation, either a DNS TXT record at _mia-auth.{domain} reading v=mia1; issuer=<issuer domain>, or a signed /.well-known/mia-delegation.json (media type application/merchant-delegation+json) signed with a key from the subject domain’s own key directory.

A valid statement shows as Operator identity published (self-declared). It does not raise the level. The draft itself says a valid assertion does not independently verify the legal entity behind it: it shows that whoever controls the domain chose to name themselves, not that the name is true.

Limits of this source:

  • Explicit revocation (revocationUri) is not checked. The draft makes it optional.
  • The draft is an individual Internet-Draft, which expires and may change or be abandoned. AgentValet keeps this check separate so it can be replaced.

Approved versions and tool changes

The level says who operates an endpoint. An approved version says whether the server is still the one an admin reviewed. For an MCP server, AgentValet records two fingerprints and lets an admin approve (pin) them:

  • Operator identity fingerprint. A SHA-256 hash over what the checks concluded about the operator: the endpoint host, its registrable domain, the registry namespace and how it was bound to the domain, and, when an identity statement validated, its subject, issuer domain, key id and stated legal name. Check times and raw responses are not part of it, so a routine re-check does not change it; a change of operator, registry namespace or signing key does.
  • Tool manifest hash. Each tool definition the server returns from tools/list is hashed exactly as sent: SHA-256 over its RFC 8785 (JCS) canonical JSON, so the name, description, input schema, annotations and every other field count. The manifest hash is SHA-256 over the canonical JSON of the name-sorted list of {name, sha256} pairs. Changing any tool’s description or schema, adding a tool or removing one changes it.

Every manifest AgentValet sees is kept (append-only) with the canonical definition of each tool, so an admin can see exactly what changed. Manifests are recorded when the server is added, on a rescan, when an agent refreshes its tool list, and in the background on use when the last one is more than 6 hours old.

Approving a version

Adding an MCP server approves the version seen at that moment, with the adding admin as the approver. After that, an admin approves a new version from the platform’s detail panel with a note of at least 10 characters. The approval records the identity fingerprint and manifest hash the admin was shown; if either changed while they were reviewing, it is refused and they review again. An approval can be withdrawn, also with a note. Approvals and withdrawals are append-only, visible only to your organisation, and written to the audit log (counterparty.pinned, counterparty.unpinned). An approval is never part of the level.

The badge shows one of:

StateMeaning
Approved versionThe identity fingerprint and every tool definition match the approved version.
Tools changed: awaiting approvalSome tool definitions differ. Only the changed or new tools are affected.
Operator changed: awaiting approvalThe identity fingerprint differs. Every tool is affected.
Operator and tools changed: awaiting approvalBoth differ.
Approved, awaiting first checkApproved before any check had finished, so the approval names no identity yet. The first conclusive check binds it. Until then it is not treated as the approved version.
Approved, awaiting first tool listingApproved before the server’s tools were first listed. The first listing binds it. Until then it is not treated as the approved version.
Approved, identity not yet confirmedThe approval names an identity, but no check result is available to compare it with.
Not approvedNo version has been approved (for example, a server added before operator verification was switched on for your organisation).

What happens when a server changes

Two things, independent of each other:

  1. Changed tools are held back from agents. When a server with an approved version changes its tools, only the tools whose definition still matches the approved one are synced. Changed and new tools are not offered to agents (list_platforms, /v1/agent/tools) until an admin approves the new version, and nothing that was approved is removed. Admins get an in-app notification and a counterparty.manifest_changed audit entry naming the changed, added and removed tools (names and hashes only).
  2. Policy can refuse or hold calls. A policy can require the approved version (see Require a minimum operator level). Under that policy, a call to a changed tool, or to any tool when the operator identity changed, is observed, held for approval or refused (403 denied_by_counterparty_pin), as the policy says. Approving a held call lets that one call through; it does not approve the new version. When an approved call runs, the requirement is checked again against the server as it is then: if the server changed after the call was held, the call does not run (counterparty_changed).

The identity fingerprint is built from the last conclusive result of each check, even after that result’s validity has run out, so an outage or a late re-check does not count as a change. Only a new conclusive result can change it. An expired result still lowers the level shown on the badge.

What lands in the audit trail

Every call to a platform in an organisation with operator verification on records, in the audit entry’s counterparty block: the state and level, the check run it came from, each source’s result with the SHA-256 of the evidence fetched, the identity fingerprint, the manifest id and hash, the approval state with the approved hashes, any changed tools, the tool called, the policy requirement and the outcome (met, observed_below, held or denied, and which condition failed). The signed governance receipt for the call carries the state, level, approval state, both hashes, the approval id and the outcome.

What is not checked

  • Legal entity. AgentValet does not match operators against business registers (such as ABN Lookup or the NZBN register). There is no “entity verified” level.
  • Behaviour. No check looks at what a server does, how it handles data, or whether its tools are what they say. Approved versions detect that a tool definition changed; they do not judge whether the definition, or the code behind it, is honest.
  • The server’s code and TLS key. The manifest hash covers what the server says its tools are, not the code that runs them. A server can change behaviour without changing a definition. The TLS key is not pinned.
  • Domain ownership by a company. See the domain check above.

Why unverified servers are still allowed

Verification never blocks adding a platform or MCP server. Adding one never waits for a check and never asks you to confirm anything.

What happens when an agent uses a platform is up to your policies. By default a policy has no requirement. You can set a minimum level, require the approved version, or both, and the default for that requirement is to observe only: record what would have happened and block nothing. Requiring approval, or denying the call, is something you switch on per policy. See Require a minimum operator level.

When checks run

  • In the background, when a platform or MCP server is added.
  • On a platform’s first use by an agent.
  • Several times a day, on a schedule (every 6 hours). Each run re-checks the endpoints that are due.
  • When someone clicks Re-check now on the platform’s detail panel.

So a change on the operator’s side, such as a new registry listing, shows up after the next scheduled run, or when an organisation uses Re-check now.

A pass does not last forever. Domain and registry passes stay valid for 14 days, and the scheduled runs re-check a host after 7, so a pass is normally renewed well before it lapses. An identity statement’s pass lasts until the statement’s own expiry, capped at 14 days. A check that cannot reach its source (Unavailable) never replaces an earlier result: the last pass or fail still counts until it lapses. A lapsed domain pass reads as Check unavailable, not Unverified. A failed or unavailable check is retried within a few hours.

To spread the load on operators, checks are rate-limited: one check per endpoint host every 10 minutes, six per registrable domain every 10 minutes, and 30 manual re-checks per organisation per hour.

When a level drops

If an endpoint’s level drops, or its identity statement stops validating, AgentValet writes a counterparty.level_dropped entry to the audit log of every organisation with operator verification on that uses that endpoint, and sends an in-app notification to that organisation’s admins. There is no email for this.

How the checks fetch content

The checks fetch content from addresses that operators control, so every fetch is guarded:

  • HTTPS only. Redirects are not followed.
  • Private, loopback, link-local, carrier-grade NAT (CGNAT) and unique local (ULA) addresses are refused.
  • Responses are capped at 1 MB, with a 5 second timeout.
  • Fetched content is treated as untrusted data, never as instructions.

One residual risk remains: DNS rebinding between the address check and the connection is not fully ruled out.

Known limits

  • It is an Enterprise feature. Organisations on other plans do not get badges, the report, audit evidence or the policy setting.
  • Identity, not endorsement. A verified operator can still run a bad server.
  • The domain check proves a domain, not a company.
  • The identity statement is self-declared and rests on an expiring individual Internet-Draft. Revocation is not checked.
  • The policy preview, and the scope list agents get from list_platforms, do not predict a hold or refusal caused by operator verification. That is decided when the call is made.
  • There is no public lookup page or embeddable badge for operators yet.
  • Tool changes are noticed when tools are listed: on add, rescan, an agent’s tool refresh, or the background refresh on use (at most every 6 hours per server per proxy). A server can change between those moments, and AgentValet calls the tool by name, so a change made after the last listing is not caught until the next one.

Next

Last updated on