Follow-on to #5 (merged via PR #8), which shipped the foundational agentic-browsing work:
robots.txt, sitemap.xml, llms.txt
Accessibility tree fixes (forms, nav, cookie dialog)
CLS improvements on homepage/contact
Regression docs and tests
WebMCP was intentionally deferred — experimental in Chrome, low adoption (~0.3% of top sites per Locomotive audit), and Lighthouse only scores it when --enable-experimental-web-platform-features is on.
This ticket covers the next layer: exposing site actions as named, callable tools so agents can invoke them directly instead of guessing from screenshots.
What WebMCP is
WebMCP lets a page register actions as typed tools via navigator.modelContext. An agent calls searchContactForm() or submitContactInquiry({...}) instead of hunting for buttons in the DOM.
Lighthouse agentic-browsing checks (when flag enabled):
Registered tools — site exposes at least one valid tool
Form coverage — transactional forms declare what they do
Schema validity — tool names, descriptions, and input schemas are well-formed
Scope
Phase 1 — Contact flow (highest value)
Target page: /contact
Register a submit_contact_inquiry tool with JSON schema:
name (string, required)
email (string, required)
subject (string, required)
message (string, optional)
Tool execute should POST to existing Django contact endpoint (or call shared view logic) and return structured success/error
Handle reCAPTCHA gracefully in production (document agent limitation or provide DEBUG-only bypass path for audit demos)
Add readOnlyHint: false and clear description per WebMCP spec
Phase 2 — Site navigation helpers
Target pages: homepage + service pages
Register list_services tool — returns structured list of service name, URL, summary (sourced from PUBLIC_PAGE_ENTRIES in public/seo.py or a shared config)
Register get_page_content or navigate_to_service tool — given a service slug/name, return canonical URL and short description
Chrome flag setup (chrome://flags/#enable-experimental-web-platform-features)
Lighthouse CLI command for WebMCP checks
List of registered tools and expected inputs/outputs
Add feature flag / settings toggle (WEBMCP_ENABLED) so tools only register in environments where we want them
Add unit or integration tests for tool registration guards (enabled/disabled, schema shape)
Capture baseline Lighthouse agentic-browsing HTML report with flag on for /contact and /
Implementation notes
Imperative API (preferred for dynamic behavior):
if(navigator.modelContext){navigator.modelContext.registerTool({name:'submit_contact_inquiry',description:'Submit a contact inquiry to AI ML Operations',inputSchema:{type:'object',properties:{name:{type:'string'},email:{type:'string'},subject:{type:'string'},message:{type:'string'},},required:['name','email','subject'],},annotations:{readOnlyHint:false},execute:async(input)=>{/* POST to /contact */},});}
Load WebMCP JS only on public pages that need it (contact + base layout), behind WEBMCP_ENABLED
Do not expose authenticated planning/financial actions
Tools run in the visitor's browser session — no separate API keys; design for unauthenticated marketing flows only
Suggested order
WEBMCP_ENABLED setting + guarded JS loader
submit_contact_inquiry on /contact
list_services on homepage
Lighthouse audit with experimental flag; fix schema/coverage failures
Documentation + regression checklist
Acceptance criteria
With WEBMCP_ENABLED=True and Chrome experimental flag on, Lighthouse agentic-browsing shows pass (not N/A) for all three WebMCP checks on /contact
At least one registered tool callable from Chrome Labs Awesome WebMCP demo flow or equivalent test harness
submit_contact_inquiry creates a Contact record and triggers email (same behavior as HTML form) when reCAPTCHA not required
WebMCP scripts absent when WEBMCP_ENABLED=False (production default until deliberately enabled)
Docs updated with enablement steps and tool catalog
## Context
Follow-on to #5 (merged via PR #8), which shipped the foundational agentic-browsing work:
- `robots.txt`, `sitemap.xml`, `llms.txt`
- Accessibility tree fixes (forms, nav, cookie dialog)
- CLS improvements on homepage/contact
- Regression docs and tests
**WebMCP was intentionally deferred** — experimental in Chrome, low adoption (~0.3% of top sites per [Locomotive audit](https://locomotive.agency/blog/lighthouse-agentic-browsing-audit/)), and Lighthouse only scores it when `--enable-experimental-web-platform-features` is on.
This ticket covers the next layer: exposing site actions as **named, callable tools** so agents can invoke them directly instead of guessing from screenshots.
---
## What WebMCP is
[WebMCP](https://developer.chrome.com/blog/webmcp) lets a page register actions as typed tools via `navigator.modelContext`. An agent calls `searchContactForm()` or `submitContactInquiry({...})` instead of hunting for buttons in the DOM.
Lighthouse agentic-browsing checks (when flag enabled):
1. **Registered tools** — site exposes at least one valid tool
2. **Form coverage** — transactional forms declare what they do
3. **Schema validity** — tool names, descriptions, and input schemas are well-formed
---
## Scope
### Phase 1 — Contact flow (highest value)
Target page: `/contact`
- [ ] Register a `submit_contact_inquiry` tool with JSON schema:
- `name` (string, required)
- `email` (string, required)
- `subject` (string, required)
- `message` (string, optional)
- [ ] Tool `execute` should POST to existing Django contact endpoint (or call shared view logic) and return structured success/error
- [ ] Handle reCAPTCHA gracefully in production (document agent limitation or provide DEBUG-only bypass path for audit demos)
- [ ] Add `readOnlyHint: false` and clear `description` per WebMCP spec
### Phase 2 — Site navigation helpers
Target pages: homepage + service pages
- [ ] Register `list_services` tool — returns structured list of service name, URL, summary (sourced from `PUBLIC_PAGE_ENTRIES` in `public/seo.py` or a shared config)
- [ ] Register `get_page_content` or `navigate_to_service` tool — given a service slug/name, return canonical URL and short description
- [ ] Optional: `open_contact_with_subject` tool — pre-fills subject query param for hosting/pricing CTAs
### Phase 3 — Declarative form annotations (if supported)
- [ ] Evaluate HTML form-level WebMCP annotations as alternative/complement to imperative `registerTool`
- [ ] Annotate contact form fields so Lighthouse **form coverage** check passes without duplicating schema in JS
### Phase 4 — Audit, docs, and regression
- [ ] Add `docs/agentic-browsing.md` section (or `docs/webmcp.md`) with:
- Chrome flag setup (`chrome://flags/#enable-experimental-web-platform-features`)
- Lighthouse CLI command for WebMCP checks
- List of registered tools and expected inputs/outputs
- [ ] Add feature flag / settings toggle (`WEBMCP_ENABLED`) so tools only register in environments where we want them
- [ ] Add unit or integration tests for tool registration guards (enabled/disabled, schema shape)
- [ ] Capture baseline Lighthouse agentic-browsing HTML report with flag on for `/contact` and `/`
---
## Implementation notes
- **Imperative API** (preferred for dynamic behavior):
```javascript
if (navigator.modelContext) {
navigator.modelContext.registerTool({
name: 'submit_contact_inquiry',
description: 'Submit a contact inquiry to AI ML Operations',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string' },
email: { type: 'string' },
subject: { type: 'string' },
message: { type: 'string' },
},
required: ['name', 'email', 'subject'],
},
annotations: { readOnlyHint: false },
execute: async (input) => { /* POST to /contact */ },
});
}
```
- Load WebMCP JS only on public pages that need it (contact + base layout), behind `WEBMCP_ENABLED`
- Do **not** expose authenticated planning/financial actions
- Tools run in the visitor's browser session — no separate API keys; design for unauthenticated marketing flows only
---
## Suggested order
1. `WEBMCP_ENABLED` setting + guarded JS loader
2. `submit_contact_inquiry` on `/contact`
3. `list_services` on homepage
4. Lighthouse audit with experimental flag; fix schema/coverage failures
5. Documentation + regression checklist
---
## Acceptance criteria
- [ ] With `WEBMCP_ENABLED=True` and Chrome experimental flag on, Lighthouse agentic-browsing shows **pass** (not N/A) for all three WebMCP checks on `/contact`
- [ ] At least one registered tool callable from Chrome Labs [Awesome WebMCP](https://github.com/chrome-labs/awesome-webmcp) demo flow or equivalent test harness
- [ ] `submit_contact_inquiry` creates a `Contact` record and triggers email (same behavior as HTML form) when reCAPTCHA not required
- [ ] WebMCP scripts absent when `WEBMCP_ENABLED=False` (production default until deliberately enabled)
- [ ] Docs updated with enablement steps and tool catalog
---
## References
- #5 — foundational agentic browsing (closed)
- PR #8 — implementation merged to master
- https://locomotive.agency/blog/lighthouse-agentic-browsing-audit/
- https://www.tryvizup.com/blog/lighthouse-agentic-browsing
- https://developer.chrome.com/blog/webmcp
- https://github.com/chrome-labs/awesome-webmcp
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
Follow-on to #5 (merged via PR #8), which shipped the foundational agentic-browsing work:
robots.txt,sitemap.xml,llms.txtWebMCP was intentionally deferred — experimental in Chrome, low adoption (~0.3% of top sites per Locomotive audit), and Lighthouse only scores it when
--enable-experimental-web-platform-featuresis on.This ticket covers the next layer: exposing site actions as named, callable tools so agents can invoke them directly instead of guessing from screenshots.
What WebMCP is
WebMCP lets a page register actions as typed tools via
navigator.modelContext. An agent callssearchContactForm()orsubmitContactInquiry({...})instead of hunting for buttons in the DOM.Lighthouse agentic-browsing checks (when flag enabled):
Scope
Phase 1 — Contact flow (highest value)
Target page:
/contactsubmit_contact_inquirytool with JSON schema:name(string, required)email(string, required)subject(string, required)message(string, optional)executeshould POST to existing Django contact endpoint (or call shared view logic) and return structured success/errorreadOnlyHint: falseand cleardescriptionper WebMCP specPhase 2 — Site navigation helpers
Target pages: homepage + service pages
list_servicestool — returns structured list of service name, URL, summary (sourced fromPUBLIC_PAGE_ENTRIESinpublic/seo.pyor a shared config)get_page_contentornavigate_to_servicetool — given a service slug/name, return canonical URL and short descriptionopen_contact_with_subjecttool — pre-fills subject query param for hosting/pricing CTAsPhase 3 — Declarative form annotations (if supported)
registerToolPhase 4 — Audit, docs, and regression
docs/agentic-browsing.mdsection (ordocs/webmcp.md) with:chrome://flags/#enable-experimental-web-platform-features)WEBMCP_ENABLED) so tools only register in environments where we want them/contactand/Implementation notes
WEBMCP_ENABLEDSuggested order
WEBMCP_ENABLEDsetting + guarded JS loadersubmit_contact_inquiryon/contactlist_serviceson homepageAcceptance criteria
WEBMCP_ENABLED=Trueand Chrome experimental flag on, Lighthouse agentic-browsing shows pass (not N/A) for all three WebMCP checks on/contactsubmit_contact_inquirycreates aContactrecord and triggers email (same behavior as HTML form) when reCAPTCHA not requiredWEBMCP_ENABLED=False(production default until deliberately enabled)References