AgentronicsDOCS

Detection

How the Agentronics SDK identifies which kind of agent — if any — is on the page.

Detection

The SDK identifies four classes of agent. They are not symmetric — some are exact-match, some are heuristic, some are not detectable at all from the page. Being upfront about that asymmetry is the most important thing on this page.

ClassHow we detectConfidence
WebMCPnavigator.modelContext is set by the agent's browser/extensionExact — confidence: 1
Crawlernavigator.userAgent matches a known AI/search bot signatureSignature — confidence: 0.9 (spoofable)
DOM-driverA weighted bag of automation signals (Playwright, Puppeteer, Selenium…)Heuristic — confidence: 0.0–1.0
Screenshot modelCannot be detected client-side. Use declareAgent().Declared — trust: 'declared' | 'verified'

Running detection

import { Agentronics } from '@agentronics/sdk'
 
const client = Agentronics.init({ publishableKey: process.env.NEXT_PUBLIC_AGENTRONICS_KEY! })
 
const identity = await client.detect()
// → { class: 'webmcp', trust: 'detected', confidence: 1, vendor: 'claude-extension', … }
// or null if no agent fires above threshold

detect() runs WebMCP first (with a short poll for late-injecting extensions), then a known-crawler User-Agent match, then DOM heuristics. The first class that matches wins.

Tuning

await client.detect({
  webmcp:  { pollMs: 500 },    // 0 to skip the poll, false to skip WebMCP entirely
  crawler: { confidence: 0.9 },// false to skip crawler matching
  dom:     { threshold: 0.4 }, // raise to be stricter, false to skip DOM heuristics
})

Crawlers

Crawlers are AI and search bots that fetch your pages — OpenAI's GPTBot, Anthropic's ClaudeBot, PerplexityBot, Googlebot, Bingbot, and friends. The SDK identifies them by matching navigator.userAgent against a signature table:

import { detectCrawler } from '@agentronics/sdk'
 
const id = detectCrawler()
// → { class: 'crawler', trust: 'detected', confidence: 0.9,
//     vendor: 'GPTBot', signals: { matched: 'GPTBot', category: 'ai', ua } }
// or null

detectCrawler is also wired into the detect() pipeline (after WebMCP, before DOM), so you usually don't call it directly. Bring your own signatures for first-party crawlers:

detectCrawler({
  signatures: [
    { name: 'AcmeBot', category: 'ai', pattern: /AcmeInternalCrawler/i },
  ],
})

The bundled table covers AI crawlers (GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, anthropic-ai, PerplexityBot, Google-Extended, Applebot-Extended, Amazonbot, Bytespider, CCBot, Meta-ExternalAgent, cohere-ai) and search crawlers (Googlebot, Bingbot, DuckDuckBot, YandexBot, Baiduspider, Applebot).

Two caveats — read these

  • User-Agent is self-reported and spoofable. A match is high-confidence, not proof, so we report confidence: 0.9, never 1. Don't gate a security-critical decision on a crawler match alone — pair it with declareAgent() + a verification token if you need trust.
  • Client-side detection only sees JS-executing crawlers. Most crawlers fetch your HTML and never run the SDK, so they are invisible to detectCrawler(). Comprehensive crawler coverage needs server/edge User-Agent inspection — that belongs to a future edge product, not v0.1. Treat client-side crawler detection as a best-effort signal for the bots that do render.

Agents declaring themselves

Screenshot agents — and any agent that wants higher trust than detection alone provides — should call declareAgent():

import { declareAgent } from '@agentronics/sdk'
 
const id = declareAgent({
  class: 'screenshot',
  vendor: 'browser-use',
  verificationToken: '<token from your verification endpoint>',
})
// → trust: 'verified' if a token is supplied, otherwise 'declared'

verified requires the gateway to validate the token against the customer's configured verification endpoint. That validation lands with the gateway in Phase 8.

What we deliberately do not do

  • No fingerprinting beyond detection. No canvas hashes, no audio context probes, no font enumeration.
  • No silent retries to defeat anti-detection tooling. If a sophisticated DOM-driver scrubs navigator.webdriver, it passes as human and that's the right answer for v0.1.
  • No server-side header inspection in v0.1. That belongs to a future edge product — and it's exactly where comprehensive crawler detection will live.

See research/phase-0.5-detection-spike.md in the repo for the full methodology, signal weights, and decision log.

On this page