agentronicsDOCS

Detection

How the Agentronics SDK spots agents on the page — self-declared, browser automation, vision models, WebMCP and crawlers.

Detection

Detection labels traffic; it never blocks it. The SDK uses five sources, from strongest to weakest:

SourceClassHowConfidence
Self-declarationanyThe agent names itself (presentIdentity(), declareAgent(), an X-Agent header)trust: 'declared' — a claim
WebMCP activitywebmcpAn agent activates or calls one of your tools through document.modelContextExact — confidence: 1
Vision behaviourscreenshotHow the visitor clicks and types (see below)Scored, 0.6–1
DOM / headlessdomAutomation fingerprints — navigator.webdriver, ChromeDriver / Playwright / Puppeteer globals, headless UAScored, 0.4–1
Crawler User-Agentcrawlernavigator.userAgent matches a known bot0.9 — spoofable; verify on the server

init() runs detection automatically (autoDetect, on by default) and keeps the result in client.agentContext, so every tool call is attributed without you passing identity around. Call client.detect() to re-run it.

const identity = await client.detect()
// → { class: 'dom', trust: 'detected', confidence: 0.72, signals: { webdriver: {…}, automationGlobals: {…} } }
// or null — a human, or an agent that hasn't shown itself

WebMCP agents

document.modelContext exists for every visitor of a WebMCP-capable browser (Chrome and Edge origin trials, ChatGPT Desktop, …), so its presence alone says nothing about an agent. The SDK reports a WebMCP agent once one acts: a toolactivated event, or a call to a tool you published with publishToWebMcp(). From then on the session is attributed to that agent (unless a stronger, declared or verified identity is already in place).

webMcpSupport() tells you whether the page can serve tools at all: 'document', 'navigator' (the old alias, removed in Chrome 152), 'legacy' (old polyfills) or null.

Vision-model agents

Computer-use agents (ChatGPT agent, Claude computer use, Gemini computer use, …) look at screenshots and drive a real browser with synthetic mouse and keyboard input. They often pass DOM checks, but they interact differently from people:

  • teleport clicks — a click with no pointer movement before it;
  • centre clicks — clicks within a pixel or two of an element's exact centre, again and again;
  • metronome typing — key intervals with almost no variance, or text inserted with no key presses;
  • no hover, no wheel — clicks and scroll jumps with no mousemove or wheel events between;
  • VM-shaped viewport — exact sandbox sizes such as 1024×768 or 1280×800 (a weak signal on its own).

The monitor scores these over a short window and reports a screenshot agent only when several agree after at least three interactions. It reads event timing and coordinates — never key values or text — and ignores synthetic (isTrusted: false) events, which are DOM automation instead.

Agentronics.init({
  publishableKey,
  visionDetection: { threshold: 0.7, minInteractions: 4 }, // or false to turn it off
})
 
client.vision?.score()   // live 0–1 score
client.vision?.signals() // { clicks, teleportClicks, centreClicks, keyIntervalCv, … }

DOM / headless

A weighted bag of signals: navigator.webdriver, ChromeDriver's cdc_* globals, Playwright / Puppeteer / Selenium / PhantomJS / Nightmare globals, a headless User-Agent, empty navigator.languages or plugins on desktop, a Chrome UA without window.chrome. Raise dom.threshold (default 0.4) to be stricter.

Crawlers

detectCrawler() matches navigator.userAgent against AI crawlers (GPTBot, OAI-SearchBot, ChatGPT-User, Claude-User, Claude-SearchBot, ClaudeBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Amazonbot, Bytespider, CCBot, Meta-ExternalAgent, cohere-ai) and search crawlers (Googlebot, Bingbot, DuckDuckBot, YandexBot, Baiduspider, Applebot). In the browser it only sees crawlers that run JavaScript and can't tell a real GPTBot from a spoofed one — verify crawlers on the server with their published IP ranges.

Tuning

await client.detect({
  webmcp: { pollMs: 500 },     // wait for WebMCP activity; 0 = check once; false = skip
  crawler: { confidence: 0.9 }, // false = skip
  dom: { threshold: 0.4 },     // false = skip
})

What we deliberately don't do

  • No canvas, audio or font fingerprinting, and no reading what visitors type.
  • No retries to defeat anti-detection tooling. An agent that hides well browses as a human — and is still welcome.
  • Detection never blocks. Use authorization rules to decide what each kind of agent may call.

On this page