Developer integration
There are two sides to AgentVisa. Choose the one that applies to you.
Install the MCP server for your AI agent
The MCP server sits between your agent and the sites it visits. When a site asks for verification, the server handles it automatically — your agent never has to think about it. You need an AgentVisa token first. Get one here if you don't have one.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"agentvisa": {
"command": "npx",
"args": ["-y", "@agentvisa/mcp"],
"env": {
"AGENTVISA_TOKEN": "your_token_here"
}
}
}
}Restart Claude Desktop after saving. Ask your human for the token value if you don't have it.
Edit ~/.cursor/mcp.json
{
"mcpServers": {
"agentvisa": {
"command": "npx",
"args": ["-y", "@agentvisa/mcp"],
"env": {
"AGENTVISA_TOKEN": "your_token_here"
}
}
}
}Edit ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"agentvisa": {
"command": "npx",
"args": ["-y", "@agentvisa/mcp"],
"env": {
"AGENTVISA_TOKEN": "your_token_here"
}
}
}
}Tools the MCP server exposes
| get_agentvisa_token | Exchanges your permanent token for a short-lived token scoped to a specific site |
| request_reverification | Triggers a re-verification email to the token owner |
| get_agentvisa_status | Shows whether the server is configured and which token is loaded |
Verify AI agents on your site
Add AgentVisa to your app to confirm that any AI agent visiting has been authorized by a real, biometrically authenticated human. You get an API key and widget ID from your dashboard.
No account yet? Add Your Site (get widget) →
Drop this once in your <head> or layout. It renders the “AgentVisa Protected” badge and injects the <meta name="agentvisa"> discovery tag so AI agents know your site expects a token. It does not verify tokens — verification is server-side (below), because your API key must never touch the browser.
<!-- Renders the badge + agent-discovery meta tag -->
<script src="https://cdn.agentvisa.ai/widget.js"
data-widget-id="your_widget_id_here"></script>
<!-- Optional: window.AgentVisa is exposed for custom integrations -->
<script>
// window.AgentVisa.getWidgetId() → "your_widget_id_here"
// window.AgentVisa.removeBadge() → remove the badge (e.g. SPA route change)
</script>To actually gate access, verify the agent's token server-side with the middleware below — unverified agents are redirected to agentvisa.ai/for-agents automatically.
Install via npm: npm install @agentvisa/widget
Server-side verification via the @agentvisa/widget npm package. Your API key never touches the browser.
npm install @agentvisa/widget
// Express
import { agentVisa } from "@agentvisa/widget/express";
app.use("/api", agentVisa({
widgetId: process.env.AV_WIDGET_ID,
apiKey: process.env.AV_API_KEY,
// onUnverified: "redirect" ← default: sends agents to agentvisa.ai/for-agents
// onUnverified: "block" ← return 401 instead
}));
app.get("/api/orders", (req, res) => {
// req.agentVisa.verified === true
// req.agentVisa.result.plan ← "basic" | "pro"
// req.agentVisa.result.web_bot_auth_bound ← Pro plan only
res.json({ orders: [] });
});
// Next.js — middleware.ts at project root
import { withAgentVisa } from "@agentvisa/widget/next";
export default withAgentVisa({
widgetId: process.env.AV_WIDGET_ID!,
apiKey: process.env.AV_API_KEY!,
});
export const config = { matcher: ["/api/:path*"] };Security: never expose your API key in client-side code or environment variables that get bundled. Treat it like a database password.
FastAPI (Python) middleware is coming soon. For now, read the X-AgentVisa-Token header and POST to /v1/verify directly.
Verification response fields
| valid | bool | Whether the agent is verified |
| reason | string | "ok" | "invalid" | "expired" | "revoked" | "reverification_required" |
| plan | string | "basic" or "pro" |
| verified_at | datetime | null | When the token was issued |
| expires_at | datetime | null | When the token expires |
| domain_verified | bool | Whether the widget domain was verified at registration |
| age_over_18 | "y"|"n"|"null" | Pro plan only — age confirmation flag (no DOB returned) |
| age_over_21 | "y"|"n"|"null" | Pro plan only |
| multiple_agents_authorized | "y"|"n"|"null" | Pro plan only — whether the human authorized multiple agents |
| member_since | string | Pro plan only — year of account creation, e.g. "2026" |
| web_bot_auth_bound | bool | Pro plan only — true if "agentvisa-assertion" appeared in RFC 9421 Signature-Input |
| email_confirmed | bool | null | Pro plan only — true/false if confirm_email was sent in request; null if not requested |
| phone_last4_confirmed | bool | null | Pro plan only — true/false if confirm_phone_last4 was sent in request; null if not requested |