Week 13 (2026-03-17 → 2026-03-27)

API key hashing upgraded to HMAC-SHA-256

  • hashApiKey() now uses HMAC-SHA-256 with API_KEY_HASH_SALT env var; falls back to plain SHA-256 without it
  • Breaking: existing API keys invalidated after deploying with salt set — users must regenerate
  • API_KEY_HASH_SALT documented in README env var table

[OSS] Update CLI + website instructions for npm adapter packages

  • integrate CLI now shows "Recommended: use the npm package" banner for nuxt/astro/docusaurus
  • INSTALL.md in nuxt/astro/docusaurus adapters now leads with npm install instructions; manual file setup is the alternative
  • Platform pages for Nuxt, Astro, Docusaurus now lead STEPS with npm install / npx astro add; CLI is the alternative step

[OSS] OpenAPI spec → MCP tool generation

  • detectTools() now reads ctx.metadata.openapi.endpoints and emits real server.tool(...) handlers (capped at 20)
  • Tool names derived from operationId (slugified) or fallback {method}-{path-slug}
  • Supports path params, query params, and request body props as typed Zod schemas
  • Generated tools include path-param URL substitution, query string building, AbortController timeout (10s), and truncated response (3000 chars)
  • GET endpoints annotated readOnlyHint: true, non-GET annotated destructiveHint: true
  • Wired into both standalone Express and Vercel self-host templates
  • openapiServerUrl from spec used as base URL (falls back to site baseUrl)
  • 6 new tests covering detection, cap, and generated output

feat: adoption_snapshots table — monthly adoption trend snapshots with protocol/tier/category/hosting breakdowns

  • New adoption_snapshots DB table (JSONB columns: by_protocol, by_tranco_tier, by_category, by_hosting_type)
  • lib/adoption-snapshots.ts: upsertAdoptionSnapshot, getAdoptionSnapshots, getAdoptionSnapshot helpers
  • Drizzle migration 0018_supreme_lila_cheney.sql

Terminology Migration (mcp → agent)

  • Renamed 4 core files: mcp-host.ts → agent-host.ts, meta-mcp.ts → meta-agent.ts
  • 50+ files updated: fields, routes, domain refs, DB schema
  • URLs: mcp.w2agent.dev → agent.w2agent.dev, /api/mcp/ → /api/agent/
  • OSS repo: 19 files updated (CLI, adapters, webhook paths, docs)
  • DB migration 0011 for column renames

Homepage Redesign

  • New hero: "The Agent Web" with dual positioning (developers + end users)
  • Audit tool moved to dedicated /audit page
  • Stats bar with IntersectionObserver count-up animation
  • OG image route (/opengraph-image) with 1200x630 PNG

Navigation Overhaul

  • Header: 8 nav items → 2 (Agents + Developers mega-menu) + dual CTAs
  • Desktop mega-menu: 4-column layout, click-to-toggle, backdrop close
  • Mobile overlay: full-screen, accordion sections, auth at bottom
  • Footer: expanded to 4 columns

Browser Extension v1

  • Chrome Manifest V3 with esbuild build pipeline
  • Service worker: hostname-based site detection, dual-layer caching
  • Popup: audit score/grade display
  • Side panel: streaming chat with session history
  • Lookup API: GET /api/sites/lookup?host=

Connect Page

  • /connect with meta server config snippets for Claude Desktop & Cursor
  • Tool descriptions, example queries by category

Agent Discovery — DB Schema

  • Added 8 new columns to sites table: agent_source, agent_type, verified, quality_score, last_verified_at, benchmark_rating, github_url, github_stars
  • Drizzle migration 0014_closed_whizzer.sql
  • SiteConfig interface and siteRowToConfig() updated in agent-host.ts

Agent Discovery — Auto-Discovery Scanner

  • Auto-discovery scanner (scripts/auto-discover.ts): batch script probing domains for /llms.txt + /.well-known/agent-card.json, two-phase (quick probe → full metadata), concurrency 10 with 200ms throttle, auto-registers qualifying sites as agentSource: "auto-discovered". Extended storeExternalSite() in lib/agent-host.ts to persist discovery fields (agentSource, agentType, lastVerifiedAt, displayName, description).

Discovery Agent

  • feat(discovery): per-caller memory — session tokens (24h TTL), rejected agent filtering, interaction history. caller_id returned in discover/rate responses.
  • feat(discovery): interview and rate MCP tools fully implemented (slug-based Q&A with LLM quality assessment; 1–5 ratings stored in agent_ratings)
  • feat(discovery): caller_id/api_key optional params on discover and rate tools for cross-session continuity

Discovery Agent — Interview Cache

  • discovery_interview_cache table (Drizzle migration 0001)
  • lib/interview-cache.ts: getCachedInterviews, cacheInterviews, normalizeQuery
  • runDiscover: checks cache per candidate/question before MCP calls; background-writes live results
  • runInterview: synchronously writes responses + quality scores to cache after each interview
  • Cache TTL: 24h, per-query granularity, COALESCE preserves quality scores on discover writes
  • Tests: orchestration tests cover all-hit, partial-hit, all-miss, cache-write-after-ranking paths

Agent Discovery — Curated Third-Party Import

  • 28 well-known MCP servers registered in directory (GitHub, Cloudflare, Playwright, Supabase, Brave Search, Stripe, Sentry, Vercel, Linear, Notion, Firecrawl, Resend, Figma, etc.)
  • storeExternalSite() now passes through category, githubUrl, githubStars, displayName, description, verified on upsert (previously hardcoded category: null and omitted fields on conflict)
  • scripts/import-third-party.ts + pnpm import:third-party:prod for future re-imports
  • Directory CATEGORY_LABELS extended with 10 new categories: search, database, infrastructure, productivity, communication, utilities, payments, web-scraping, email, design

Directory — Benchmark Rating Stars

  • renderStars(rating) helper added to lib/ui-utils.ts — converts 1–5 float to ★/☆ string
  • Directory cards: show amber ★ stars below Agent Score when benchmarkRating is set
  • Agent detail page: Benchmark stars displayed inline next to Agent Score in header

E-commerce Generators (OSS)

  • Product extraction: JSON-LD → microdata → OG tag precedence, per-URL dedup, quality filter (name + price/description)
  • MCP tools: search-products, get-product, check-inventory, get-reviews — added to all 3 server templates (standalone, Vercel, CF Workers) with shared handler code
  • Product schema JSON-LD: generates @type: Product with Offers, Brand, AggregateRating for pages with microdata/OG product data but no existing Product JSON-LD
  • product-catalog.md: comparison-optimized markdown table (name, price, availability, rating, URL)
  • Compute-once buildEcommerceArtifacts() in engine pipeline — all generators receive same immutable product data
  • Stable productId (deterministic hash of URL/SKU/GTIN) for reliable tool lookups
  • products.json data file for MCP server

Bug Fixes

  • Purple badge collision (self-hosted → violet)
  • get_website_info hardcoded URLs for self-hosted agents
  • /pricing placeholder page (fixes 404 on nav link)
  • Astro validation: 109/109 checks passing

Health Monitoring

  • Continuous endpoint health checks for all agents in directory
  • Tiered frequency: top 50 agents / 5 min, next 200 / 15 min, rest / 1 hr
  • EWMA-based status (α=0.3): healthy / degraded / down / unknown
  • Colored dot on directory cards, status + latency row on detail pages
  • Sentry alerts on status transitions and mass degradation
  • New cron: /api/cron/health-check at */5 * * * *
  • DB: 5 new columns on sites — health_status, last_health_check_at, consecutive_failures, health_latency_ewma, health_success_ewma
  • Migration: drizzle/0015_health_monitoring.sql

LLM-Judged Benchmark (Tier 2)

  • lib/benchmark.ts: per-category test suites (docs, restaurant, ecommerce, tool, general), gpt-5-mini judge, structured scoring (relevance + completeness + accuracy, 1–5 each)
  • lib/chat.ts: extracted queryAgent(slug, question) shared helper (used by both meta-agent and benchmark)
  • lib/meta-agent.ts: query_website tool refactored to use queryAgent() — eliminates duplicated RAG pipeline
  • DB migration 0015: added last_benchmarked_at column to sites
  • Daily cron /api/cron/benchmark at 3 AM UTC — 30-agent batches, 7-day freshness window
  • pnpm benchmark:prod for manual trigger

Multi-Agent Routing

  • lib/routing/ module: query decomposition (decompose.ts), agent execution + orchestration (router.ts), types (types.ts)
  • route_query MCP tool on meta-agent: decomposes composite queries → matches agents via directory search → executes via MCP Client → returns per-agent results
  • LLM-powered decomposition (Gemini 2.5 Flash Lite): outputs domain-oriented searchTerm + semantic query per sub-query
  • MCP Client execution pattern (same as discovery agent's interviewAgent): connect → listTools → callTool → close
  • Sequential execution, up to 5 agents, per-agent timeout (8s connect + 4s listTools + 6s callTool)
  • routeId UUID per request for future cross-agent observability
  • searchWebsites() extracted to lib/directory/search.ts (breaks circular dependency)
  • Meta-agent maxDuration raised from 30 → 60 for multi-agent routing latency budget

Workflow Templates

  • Pre-built multi-agent compositions: restaurant reservation, product comparison, appointment booking
  • Sequential step execution with {{input.*}} / {{stepN.*}} variable interpolation
  • Per-step agent resolution: exact slug or dynamic directory search
  • list_workflows + execute_workflow MCP tools on meta-agent
  • REST: GET /api/workflows (list), POST /api/workflows/execute (run)
  • Rate-limited with expensiveApiLimiter (5/min), maxDuration: 60 for chained MCP calls

UCP Profile Generation

  • E-commerce detection in lib/ucp.ts: heuristic detection (Shopify/WooCommerce platform markers + commerce URLs), ≥2 signals required
  • Pass-through for sites with existing /.well-known/ucp manifest (validated JSON)
  • Generated manifest advertises product_search capability pointing to agent's MCP endpoint
  • Storage: sites/{slug}/ucp.json in Vercel Blob, wired into deploy + directory-submit + refresh flows
  • Serving: /.well-known/ucp on agent subdomains via middleware rewrite + dedicated route handler
  • Lightweight loadSiteUcpManifest() loader (reads only ucp.json, not full SiteData)

A2A Commerce Integration

  • Commerce-ready agent cards: e-commerce sites (UCP manifest or category: "ecommerce") get product-search, get-product-details, and optional initiate-checkout skills in /.well-known/agent-card.json
  • deriveCapabilities() extended with optional category param — emits "commerce" badge for ecommerce sites
  • Directory filter UI: new "Commerce" capability filter badge
  • Meta-agent search_websites hasCapability enum updated with "commerce" — DB-filters by category = "ecommerce"

GitHub Action Polish

  • GitHub Action polish: enhanced packages/github-action with better error messages (::error:: annotations), badge integration (badge-url output, badge in PR comments), configurable formats (formats input), max-pages input, and generate: false audit-only mode. Updated README with badge embedding guide, new examples, and troubleshooting section.

Cross-Agent Observability

  • lib/trace.ts: TraceContext type, generateTraceId() (32-char hex, W3C-compatible), getOrCreateTraceId(), withTraceId()
  • routeQuery, executeWorkflow, handleA2ARequest accept optional traceId; emit structured Pino log entries per operation ({ traceId, operation, durationMs, status })
  • createMetaMcpServer(traceId?) pipes trace through to route_query and execute_workflow tool handlers
  • All 3 API routes extract/echo x-trace-id header; traceId in RouteResult, WorkflowExecutionResult, and A2A Task.metadata

Platform i18n (EN + 中文)

  • Added next-intl v3 for App Router locale routing
  • All user-facing pages restructured under app/[locale]/ segment
  • English stays at / (no prefix), Chinese at /zh/
  • Translated: homepage, directory, site header, site footer, stats bar, submit-site, directory-search
  • Language switcher in header (globe icon, EN/中文 toggle) — desktop + mobile
  • Locale-aware generateMetadata() on layout, homepage, directory pages
  • Sitemap updated with /zh/ alternates for translated pages
  • Message files: messages/en.json + messages/zh.json (~80 keys each)

E-commerce Audit Checks (OSS)

  • 3 new checks registered via SiteTypeCheckAdapter — only run when e-commerce site detected (confidence ≥ 0.5)
  • ecommerce-product-schema (structured-data, weight 2): % of product pages with complete Product JSON-LD (name + price + availability); fix snippet included
  • ecommerce-gtin-valid (structured-data, weight 1): GS1 modulo-10 check digit validation for GTIN-8/12/13/14; skips sites with no GTINs
  • ecommerce-checkout-accessible (bot-accessibility, weight 1.5): detects cart/checkout/bag/basket links, flags paths blocked by robots.txt
  • 19 new unit tests covering pass/partial/fail/skip for all 3 checks

E-commerce Detection (OSS)

  • New site-types/ module in w2agent-core: registry pattern parallel to adapters/
  • ecommerceDetector: confidence-scored heuristics — Shopify/WooCommerce/BigCommerce/Magento platform markers (0.8), Product JSON-LD (0.7), og:type=product (0.5), commerce URL paths (0.4), price microdata (0.4), Add to Cart text (0.3)
  • Confidence = 1 - product(1 - weight_i) with 0.5 threshold; signal dedup across multi-page crawls
  • AuditReport.siteType and GenerateResult.siteType fields added; detection runs after crawl in both engines
  • 21 unit tests covering all signal types, threshold edge cases, multi-signal combinations, false-positive prevention

Local Business Detection (OSS)

  • New localBusinessDetector in w2agent-core packages/core: confidence-scored heuristics for LocalBusiness schema, booking platform embeds (OpenTable, Calendly, Acuity, etc.), NAP microdata (streetAddress/telephone itemprop), Google Maps embeds, business hours (openingHours itemprop + text patterns), menu/services URL paths, phone tel: links
  • @graph flattening handles WordPress/Yoast JSON-LD wrapping pattern
  • Weighted probability union formula, 0.5 threshold; 7 signals; auto-registered in site-types registry
  • 26 unit tests covering all signal types, threshold boundary, deduplication, registry integration, @graph pattern
  • SiteType union extended: "ecommerce" | "local-business"

Local Business Generators (OSS)

  • generate/local-business.ts: extraction cascade (JSON-LD → microdata → HTML) for NAP, hours, menu, booking URL, geo, price range
  • Engine wiring: buildLocalBusinessArtifacts feeds schema-org (LocalBusiness + Speakable JSON-LD) and MCP server (business.json, get-hours/get-menu/get-services/book-appointment tools)
  • Outputs: business-info.md table, mcp-server/data/business.json
  • Vendor tarball rebuilt: vendor/w2agent-core-0.1.0.tgz

Directory API (v0)

  • Public REST API at GET /api/v0/servers — list/search directory agents with filtering by category, capability, hosting type, min score; pagination (limit/offset); 60 req/min per IP; edge-cached (s-maxage=60)
  • Single-server endpoint at GET /api/v0/servers/[slug] — full metadata including raw tools array
  • Extended lib/directory/search.ts: searchWebsitesWithCount() (pagination + total count), buildSearchConditions() helper, offset param on searchWebsites()
  • lib/rate-limit.ts: directoryApiLimiter (60/min sliding window)
  • 15 unit tests covering response shape, pagination defaults/overrides, all filter params, param validation (limit 1-100, offset ≥0, min_score 0-100), rate limiting, cache headers, 404, empty results

Bot Visit Tracking

  • lib/ai-bots.ts: canonical registry of 58+ AI bots (OpenAI, Anthropic, Google, Meta, ByteDance, Perplexity, and 50+ more) with regex patterns; matchBot(userAgent) function
  • bot_visits DB table: daily aggregation per bot per site — (site_id, date, bot_name, count), unique index on triple, secondary index on (site_id, date) for dashboard queries; migration 0017_nappy_red_skull.sql
  • lib/bot-tracking.ts: recordBotVisit(siteId, botName) upsert — increments daily count atomically, swallows errors to Sentry
  • Agent route (GET /api/agent/[slug] + POST /api/agent/[slug]): bot detection wired via after() on both MCP and A2A paths

Bot Analytics Dashboard

  • Owner-only "Bot Traffic" section on each site detail page
  • 30-day SVG bar chart of daily bot visits (server-rendered, no JS)
  • Top 10 bots by visit count with "NEW" badge for first-seen within 7 days
  • Total bot visit count as headline stat (computed from daily totals, no extra query)

Local Business Audit Checks (OSS)

  • 3 new checks registered via SiteTypeCheckAdapter — only run when local-business site detected (confidence ≥ 0.5)
  • local-business-nap-structured (structured-data, weight 2): % of NAP fields (name/address/phone) present in JSON-LD or microdata; fix snippet included
  • local-business-hours-jsonld (structured-data, weight 1.5): validates openingHoursSpecification present in LocalBusiness JSON-LD; skips non-JSON-LD sites
  • local-business-booking-accessible (bot-accessibility, weight 1.5): detects booking links/iframes (OpenTable, Calendly, Resy, etc.); flags same-origin booking paths blocked by robots.txt
  • 20 new unit tests covering pass/partial/fail/skip for all 3 checks

Score Segment History

  • Extended site_score_history table with 3 nullable real columns: quality_score, reliability_score, popularity_score (0-1 float each)
  • computeAgentScoreWithSegments() exported from lib/quality-score.ts — returns composite + per-axis scores in one call
  • Cron (/api/cron/quality-score) now stores per-axis segments alongside composite score on each upsert
  • Drizzle migration drizzle/0018_score_segments.sql; historical rows retain null for segment columns

GitHub Action Polish (OSS)

  • Enhanced packages/github-action with better error messages (::error:: annotations on audit/parse failures, null guards for jq output), badge integration (badge-url output, badge image in PR comments, leaderboard link), configurable formats (formats input), max-pages input, and generate: false audit-only mode
  • Updated README with badge embedding guide, 2 new example workflows (audit-only, custom formats), and troubleshooting section
  • Added audit-only test job to CI, badge-url output verification
  • Fixed slug derivation to use node -e "new URL().hostname" matching platform's generateSlug() exactly (avoids port/auth divergence from pure bash approach)

YAML Adapter Agents

  • Declarative agent definitions via data/adapters/{slug}.yaml — no crawling required
  • Pipeline steps: fetch (with perItem batching), map, filter, limit
  • Template expressions: ${{ args.x }}, ${{ item.field }}, boolean ops, comparisons, literals
  • lib/agent-adapter.ts: types, parseAdapterYaml, evaluateTemplate, loadAdapter
  • lib/agent-pipeline.ts: executePipeline, createMcpServerFromAdapter
  • app/api/agent/[slug]/route.ts: adapter fallback in POST handler (after loadSiteData returns null)
  • Example adapters: hackernews (top stories + Algolia search), jsonplaceholder (posts + comments)
  • 37 unit tests: parsing, template evaluation, pipeline steps, loadAdapter, MCP server creation

Adoption Dashboard (/adoption)

  • Public page tracking agent web growth over time
  • Stat cards: total agents, protocols detected, categories covered
  • SVG area chart: total agents over time (monthly snapshots)
  • Protocol breakdown + Tranco tier distribution side-by-side
  • Top categories horizontal bar chart
  • Empty state when no snapshot data exists
  • Linked from header Community section and footer

Audit Warnings — JS-Heavy Site Detection

  • AuditWarning type (OSS): New interface added to AuditReport. computeWarnings() in the audit engine detects JS-heavy sites (based on no-js-dependency and token-efficiency check scores) and populates report.warnings.
  • Warning banner (platform): JS-heavy sites now surface a prominent amber warning banner in the audit tool, shared audit pages, and leaderboard detail pages, surfacing above "Top Issues" when the engine detects JavaScript-dependent content (sites where AI crawlers would see empty pages).

API Surface Richness Scoring

  • classifyToolTier(name): infers tier from tool name patterns (submit-* → write, api-* → api, site-search → discover, default → read)
  • computeCapabilityDiversity: diversity bonus (0–1) based on presence of 4 capability types (FAQ, forms, native-search, API endpoints)
  • computeQuality now uses surfaceRichness = 0.6 * tierWeightedDepth + 0.4 * diversityBonus — sites with diverse capabilities score up to 40% higher on the quality axis
  • Backward-compatible: callers passing { name } (cron job, backfill script) auto-classify without changes
  • Sites with API/form tools will score higher on next cron run; run pnpm backfill:quality-scores --dry-run to preview

API Surface Richness Sub-Score

  • computeApiSurfaceRichness() in lib/quality-score.ts: scores 4 signals (search, pagination, form submission, API presence) + API depth (tool count, capped at 3) → 0–1
  • surfaceRichness rebalanced: 0.6/0.4 → 0.5/0.25/0.25 (tier depth / diversity / api richness)
  • Agents with search-*, list-*, submit-*, or api-* tools now score higher relative to generic read-only agents
  • Tests updated (5 expectations) + 5 new test cases in "API surface richness" suite

WordPress Plugin (OSS)

  • Serves /llms.txt dynamically from published posts, pages, and custom post types
  • Serves /.well-known/agent-card.json from site info
  • Adds AI discovery <link> tag to all pages; merges AI bot rules into robots.txt
  • Settings page (Settings → w2agent): view active endpoints, enter Site Slug + API Key for webhook notifications
  • Notifies w2agent.dev on post save (non-blocking) when API key + webhook slug configured
  • readme.txt formatted for WordPress.org Plugin Directory submission
  • Pure PHP, no build step required

JS Framework Detection in Audit Engine (OSS)

  • noJsDependency check now detects 8 JS framework markers (__NEXT_DATA__, ng-app, ng-version, data-reactroot, data-v-app, window.__nuxt__, __svelte, ember-application)
  • Word-count threshold raised from 50 → 100 when framework markers are present (SSR fallback often meets old threshold but most content is still client-rendered)
  • Detected framework names surfaced in check details field and the js-heavy-site warning details
  • computeWarnings() message updated: "Audit scores may be lower than actual quality" (more accurate framing)

[OSS] Mask webhookToken in CLI deploy output

  • Added --show-token flag to deploy and agentize commands to reveal plaintext token
  • maskToken() helper preserves the prefix (e.g. w2wh_) and replaces the rest with ****

Fix agent display names for Mailchimp, Twilio, CircleCI

  • scripts/fix-display-names.ts: targeted DB update script with hardcoded overrides for 3 missed slugs
  • pnpm fix:display-names:dry / pnpm fix:display-names script entries added to package.json

Auth Cascade Probing

  • lib/content-validity.ts: validateContent(html) — heuristics to classify fetched content as real vs blocked (length, Cloudflare challenges, CAPTCHA, access denied, JS-required patterns)
  • lib/auth-cascade.ts: probeAuthCascade(url) — cascades PUBLIC → COOKIE → intercept stub; returns AuthProbeResult with strategy, cookies, and details booleans
  • DB: auth_strategy (text) + auth_probe_result (jsonb) columns on sites; migration drizzle/0019_*.sql
  • Deploy route: background after() block probes each site after deploy, skips re-probe within 7 days (staleness guard)
  • Tests: lib/content-validity.test.ts (8 cases), lib/auth-cascade.test.ts (7 cases)
Changelog — Week 13 (2026-03-17 → 2026-03-27) | w2agent