---
name: ecosystem-usage
description: "Measure agent-facing traffic to the evlog docs site (MCP transport, raw Markdown, discovery paths) with Vercel Observability, and read it without inflating it."
---

Use this skill when asked about MCP adoption, AI-agent traffic, raw Markdown consumption, curl usage, or which clients consume the evlog docs. Web Analytics sees browsers only; this skill measures the requests that never run a pageview script.

## Source of truth

Use the read-only `vercel__create_observability_query` tool, called through `connection_execute`.

- Metric: `vercel.request.count`, aggregation `sum`.
- Scope: `type: 'project'`, `ownerId`: the evlog team id, `projectIds`: the docs site project id (both pre-scoped in the connection description).
- Always filter to `environment eq 'production'`.
- Use ISO UTC timestamps for `startTime` and `endTime`.
- Because the result is read against a comparison, always query the requested window and the immediately preceding equal-length window with the same scope and filter, ungrouped.
- A tool-call concurrency limit is not a total-query budget: send further read-only calls until every requested metric is collected.

## Query recipes

Run independent queries in parallel, ungrouped first for the exact total, then grouped for the breakdown.

1. Agent-facing total:
   - Filter: `environment eq 'production'`
   - Group by `client_user_agent` (limit 25) and `bot_category` + `bot_name` (limit 20).
2. Explicit Markdown URLs:
   - Filter: `endswith(request_path, '.md') and environment eq 'production'`
   - Group by `request_path` (limit 10) and `client_user_agent` (limit 10).
3. Content-negotiated Markdown:
   - Filter: `contains(http_accept, 'text/markdown') and environment eq 'production'`
   - Group by `request_path` (limit 10) and `client_user_agent` (limit 10).
4. Agent discovery and intake:
   - Filter: `(request_path eq '/llms.txt' or request_path eq '/llms-full.txt' or request_path eq '/sitemap.md' or request_path eq '/.well-known/mcp/server-card.json') and environment eq 'production'`
   - Group by `request_path` (limit 10), `client_user_agent` (limit 10), or `bot_category` + `bot_name` (limit 10).
   - Keep these separate from content reads: fetching an index does not prove the client consumed a documentation page.
5. curl traffic, only when explicitly asked:
   - Filter: `contains(client_user_agent, 'curl/') and environment eq 'production'`
   - Group by `request_path` and `client_user_agent`; exclude asset paths from the interpretation.

## Interpretation rules

- Call the result **HTTP requests**, never tool calls, sessions, users, or unique agents. Initialization, discovery, tool calls, retries, and notifications each count separately.
- Use the ungrouped `summary` as the authoritative total. Do not add grouped rows or timeseries buckets to reconstruct it.
- Empty or generic user agents (`node`, `undici`, `Go-http-client`, `python-httpx`) identify a client stack, not an agent product. Never rename a generic or empty user agent into a specific product.
- Report at most five recognized product rows with exact counts, then at most three generic stack rows, then the empty-user-agent row when present. Never sum version variants.
- A `.md` path or a curl user agent alone does not prove AI usage: humans use "View as Markdown", scripts use curl. Treat explicit `Accept: text/markdown`, known AI bot categories, and MCP transport paths as the stronger signals.
- Top-N grouped rows are partial: describe them as top returned rows, never as all traffic.
- If a response says `truncated: true` or reports `truncation.omittedArrayItems`, only the returned timeseries was shortened; report the summary total and do not call it a data gap. Only label a real data gap when the API explicitly reports one after truncation is ruled out.
- If a query times out, shorten the window or drop a high-cardinality grouping; the ungrouped total stays authoritative.
- Browser traffic stays with `vercel__count_pageviews` and `vercel__aggregate_pageviews`; label it as browser pageviews and never present it as total readership when agent-facing traffic is in scope.

## Output

- Include the exact requested time window and every requested metric with its HTTP request count.
- When a number is shown against a comparison, take the change from the queried preceding window; if that query was not performed or failed, write "change unavailable: <reason>" instead of implying a delta.
- If a required query failed, show that metric as unavailable beside the successful totals, with the concrete error in one line.
- End with one short caveat that HTTP request volume is not logical tool-call volume.
