Add WebMCP tool registration for agentic browsing (#9) (#12)
Deploy Company Site / test (push) Successful in 10s
Deploy Company Site / deploy (push) Successful in 4s

## Summary

- Add `WEBMCP_ENABLED` setting and guarded `webmcp-tools.js` loader on public pages
- Register navigation tools (`list_services`, `get_page_content`, `navigate_to_service`, `open_contact_with_subject`) and contact tool (`submit_contact_inquiry`)
- Annotate contact form with declarative WebMCP attributes for Lighthouse form coverage
- Extend `PUBLIC_PAGE_ENTRIES` with summaries shared by SEO and WebMCP tools
- Add `docs/webmcp.md`, update `docs/agentic-browsing.md`, and regression tests

Closes #9

## Test plan

- [x] `python manage.py test public.tests` — 20 tests pass
- [ ] Set `WEBMCP_ENABLED=True`, enable Chrome experimental web platform features flag
- [ ] Verify homepage HTML includes `webmcp-config` and `webmcp-tools.js`
- [ ] Verify `/contact` form has `toolname="submit_contact_inquiry"`
- [ ] Run Lighthouse agentic-browsing on `/` and `/contact` with experimental flag
- [ ] Call `list_services` from WebMCP-capable Chrome on homepage
- [ ] Call `submit_contact_inquiry` on `/contact` with `DEBUG=True` (reCAPTCHA bypass)

Reviewed-on: #12
This commit was merged in pull request #12.
This commit is contained in:
2026-07-02 16:57:47 +00:00
parent 7c9aba7e6c
commit bb5aa6de82
9 changed files with 628 additions and 18 deletions
+112 -14
View File
@@ -5,21 +5,119 @@ from django.template.loader import render_to_string
from django.urls import reverse
# Public marketing pages included in sitemap and llms.txt.
# Tuple: (url_name, title, changefreq, priority, summary)
PUBLIC_PAGE_ENTRIES = (
("public_index", "Home", "weekly", "1.0"),
("forward_deployed", "Forward-Deployed AI", "monthly", "0.9"),
("bot", "AI Agents", "monthly", "0.9"),
("ml_model", "ML Models", "monthly", "0.8"),
("chat", "Secure AI Chat", "monthly", "0.8"),
("ai_sensor", "AI Sensor Algorithms", "monthly", "0.7"),
("ai_education", "AI Education", "monthly", "0.7"),
("computers", "Computer Builds", "monthly", "0.7"),
("file_hosting", "File Hosting", "monthly", "0.7"),
("web_design", "Web Design and Hosting", "monthly", "0.8"),
("contact", "Contact", "monthly", "0.9"),
("terms_of_service", "Terms of Service and Privacy", "yearly", "0.3"),
(
"public_index",
"Home",
"weekly",
"1.0",
"Company homepage with an overview of AI ML Operations services.",
),
(
"forward_deployed",
"Forward-Deployed AI",
"monthly",
"0.9",
"Embedded AI engineering — we work inside your environment to build production systems.",
),
(
"bot",
"AI Agents",
"monthly",
"0.9",
"Custom AI agents and agentic workflows tailored to your operational bottlenecks.",
),
(
"ml_model",
"ML Models",
"monthly",
"0.8",
"Machine learning model development, training, and deployment for production use.",
),
(
"chat",
"Secure AI Chat",
"monthly",
"0.8",
"Private, hosted AI chat deployments with enterprise-grade security.",
),
(
"ai_sensor",
"AI Sensor Algorithms",
"monthly",
"0.7",
"Computer vision and sensor-fusion algorithms for real-world sensing applications.",
),
(
"ai_education",
"AI Education",
"monthly",
"0.7",
"Hands-on AI training and workshops for teams adopting agentic workflows.",
),
(
"computers",
"Computer Builds",
"monthly",
"0.7",
"Custom workstation and server builds optimized for AI and ML workloads.",
),
(
"file_hosting",
"File Hosting",
"monthly",
"0.7",
"Managed file hosting and storage for teams that need reliable data access.",
),
(
"web_design",
"Web Design and Hosting",
"monthly",
"0.8",
"Web design, development, and managed hosting for business sites and apps.",
),
(
"contact",
"Contact",
"monthly",
"0.9",
"Contact form to inquire about forward-deployed AI engineering services.",
),
(
"terms_of_service",
"Terms of Service and Privacy",
"yearly",
"0.3",
"Terms of service and privacy policy for AI ML Operations, LLC.",
),
)
SERVICE_URL_NAMES = frozenset({
"forward_deployed",
"bot",
"ml_model",
"chat",
"ai_sensor",
"ai_education",
"computers",
"file_hosting",
"web_design",
})
def get_service_entries():
"""Return service page metadata for WebMCP navigation tools."""
return [
{
"slug": url_name,
"name": title,
"summary": summary,
}
for url_name, title, _changefreq, _priority, summary in PUBLIC_PAGE_ENTRIES
if url_name in SERVICE_URL_NAMES
]
def _absolute_url(request, url_name):
return request.build_absolute_uri(reverse(url_name))
@@ -41,7 +139,7 @@ def sitemap_xml(request):
"changefreq": changefreq,
"priority": priority,
}
for url_name, _title, changefreq, priority in PUBLIC_PAGE_ENTRIES
for url_name, _title, changefreq, priority, _summary in PUBLIC_PAGE_ENTRIES
]
content = render_to_string("public/sitemap.xml", {"pages": pages})
return HttpResponse(content, content_type="application/xml; charset=utf-8")
@@ -53,7 +151,7 @@ def llms_txt(request):
"title": title,
"url": _absolute_url(request, url_name),
}
for url_name, title, _changefreq, _priority in PUBLIC_PAGE_ENTRIES
for url_name, title, _changefreq, _priority, _summary in PUBLIC_PAGE_ENTRIES
]
content = render_to_string(
"public/llms.txt",