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: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.Inject discoverability tags
The script adds machine-readable metadata to the page
<head> so AI agents can find the manifest: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.
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
Detect third-party widgets
The script detects embedded widgets that aren’t standard HTML forms:
| Widget | Detection method |
|---|---|
| Calendly | window.Calendly object or .calendly-inline-widget |
| Typeform | tf-widget element or typeform embed script |
| HubSpot | window.hbspt or .hs-form |
| Intercom | window.Intercom |
| Drift | window.drift |
| Crisp | window.$crisp |
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.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.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.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).Form type detection
The script classifies forms by scanning their HTML for keyword signals:| Type | Signals |
|---|---|
contact_form | contact, message, inquiry, reach out, get in touch |
booking | book, appointment, schedule, reserve, calendar, slot |
newsletter | newsletter, subscribe, email list, updates, notify |
signup | sign up, register, create account, join, membership |
purchase | buy, checkout, order, purchase, payment, cart |
quote | quote, estimate, calculate, price, cost, proposal |
login | login, sign in, password, username |
search | search, find, look for |
upload | upload, attach, file, CV, resume, document |
support | support, help, ticket, issue, problem, complaint |
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)

