Skip to main content
The script (script.js) is a self-contained vanilla JavaScript file under 20KB. It runs as an IIFE (immediately invoked function expression) — it never pollutes the global scope and will never break your page.

Execution order

Every time the script loads on a page, it does the following in sequence:
1

Ping (immediate)

Before anything else, the script fires a POST to /api/ping with the current page URL and script version. This confirms the script is correctly installed — your dashboard installation badge updates within seconds.
2

Inject discoverability tags

The script adds machine-readable metadata to the page <head> so AI agents can find the manifest:
3

Detect AI agents

The script checks the user-agent string for known AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Operator, and others) and headless browser signals. If an agent is detected, it’s recorded with each event.
4

Scan for forms

All <form> elements on the page are scanned. For each form, the script:
  • Extracts all input fields (name, type, required, placeholder)
  • Classifies the form type: contact_form, booking, newsletter, signup, purchase, quote, login, search, upload, or support
  • Generates a human-readable name from aria-labels, legends, nearby headings, or the form ID
  • Generates a tool_name (snake_case, used in the manifest)
  • Injects data-mcp-action, data-mcp-description, data-mcp-params attributes
5

Detect third-party widgets

The script detects embedded widgets that aren’t standard HTML forms:
6

Extract business info

The script reads Schema.org JSON-LD from the page (@type: LocalBusiness, Organization, etc.) to extract the business name, description, address, and phone number. This enriches the manifest.
7

Sync to OpenHermit

All detected actions (and business info) are sent to /api/actions/sync. OpenHermit stores new actions or updates existing ones — preserving any agent prompts you’ve already configured. The API returns your configured prompts back.
8

Inject agent prompts into DOM

Any configured prompts are injected as a hidden off-screen div with an aria-label. This means both DOM-reading and accessibility-tree-reading agents can find your instructions without any visual impact on the page.
9

Track form submissions

Event listeners are added to form submit buttons. When a form is submitted, a completion or error event is sent to /api/events via navigator.sendBeacon (fire-and-forget — never slows down the page).
10

Watch for dynamic content (SPAs)

A MutationObserver watches for new content added to the DOM. If a form appears after the initial load (common in React/Vue/Angular apps), the script re-runs detection automatically.

Form type detection

The script classifies forms by scanning their HTML for keyword signals: If no signal matches, the form is classified as contact_form by default.

Performance impact

  • Script size: < 20KB uncompressed
  • Loads async — never blocks page rendering
  • Uses sendBeacon for event tracking — fire-and-forget, zero latency impact
  • Only runs after DOMContentLoaded — doesn’t affect Time to First Byte or FCP

Security

The script never reads or transmits form field values. It only reads:
  • Field names, types, and labels (for schema building)
  • Page URL and title
  • User agent string (for agent detection)
  • Schema.org structured data (if present)
Sensitive user input is never captured.