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, orsupport - 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-paramsattributes
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
sendBeaconfor 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)

