--- name: ai-citability-audit description: Audit a page for AI citability with Blockquote (blockquote.io) and fix it. Use when a page must be citable by ChatGPT, Perplexity or Google AI Overviews, when asked to raise a Blockquote score, when diagnosing why an answer engine does not cite a page, or when adding JSON-LD, llms.txt, a TL;DR or quotable structure for that purpose. Drives a scan, read the ranked fixes, apply the smallest one, re-scan loop over Blockquote's MCP server or its REST API. --- # AI Citability Audit Blockquote scores one public URL from 0 to 100 for AI citability. The score answers one question: how likely are ChatGPT, Perplexity and Google AI Overviews to cite this page? A scan runs 34 checks in three weighted categories. 29 checks are deterministic. 5 use a language model against a fixed rubric; the playbook below marks those "LLM-judged". Work one check at a time: **scan → read the ranked fixes → apply the smallest fix for the top recommendation → re-scan.** Do not rewrite the page. Each recommendation carries a copy-paste payload. Apply it, then take the next one. This skill is served from https://blockquote.io/.well-known/agent-skills/ai-citability-audit/SKILL.md. Fetch it fresh rather than working from a memorised copy. ## Step 1 — Scan the page The scan needs no account. Blockquote's MCP server accepts a stateless JSON-RPC call, so plain `curl` is enough: ```bash curl -s -X POST https://mcp.blockquote.io/mcp \ -H 'content-type: application/json' \ -H 'accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"start_scan","arguments":{"url":"https://example.com"}}}' ``` The answer is one Server-Sent Event. The tool payload is the JSON string in `result.content[0].text`: ```json { "scanId": "u4h7hxswu0lq", "status": "pending", "cached": false, "reportUrl": "https://blockquote.io/scan/u4h7hxswu0lq", "next": "Scan dispatched. Poll get_scan with scanId \"u4h7hxswu0lq\" every ~8 seconds until status is done." } ``` If the MCP server is already connected as a tool provider, call `start_scan` directly instead of shelling out. Setup: https://blockquote.io/docs/ai-agents. Four rules the scan enforces: - The URL must be HTTPS and reachable from the public internet. An `http://` URL is refused with `invalid_url`. A page on localhost cannot be scanned — scan a deployed preview URL instead. - Anonymous callers get 1 scan per day and 3 per month from one network. MCP and REST share those counters. - A URL scanned inside the 24-hour cache window answers from the cache. It returns `"status": "done"` and `"cached": true` at once, with the stored scan id. - `POST /api/v1/scan` over REST refuses an anonymous caller with `turnstile_failed`, because the browser form is behind Cloudflare Turnstile. The MCP route above is the no-account path. The REST route needs a Pro or Agency plan — an API key (`Authorization: Bearer bq_…`) or that plan's signed-in session. A free session is refused the same way, except on the `refresh: true` path of step 5. ## Step 2 — Fetch the report Poll until the report arrives. A scan takes about 15 to 45 seconds. A pending scan answers `{"id": "…", "status": "pending"}`. A failed scan answers `{"id": "…", "status": "error", "error": "…"}` with HTTP 500 — stop and report that string. The finished report carries no `status` field, so stop when the body carries `score`. Over MCP, `get_scan` with the default `view` `summary` sets `status` to `done` instead, which is what the `next` string of step 1 asks you to wait for. `view` `full` and `view` `markdown` carry no `status` field — poll with the default, then re-read with the view you want. Reading a report needs no account and spends no scan quota: ```bash SCAN_ID=u4h7hxswu0lq # the scanId from step 1 curl -s "https://blockquote.io/api/v1/scan/$SCAN_ID" ``` Three shapes of the same report: | What you want | Call | |---|---| | The full report as JSON | `GET /api/v1/scan/{id}` | | The full report as one Markdown document | `GET /api/v1/scan/{id}` with `Accept: text/markdown` | | The report wrapped in an instruction prompt | `GET /api/v1/scan/{id}/ai-instructions` | The Markdown document is the best single input when you plan the work yourself. The `ai-instructions` document is the best input when you apply the fixes straight away — it states the apply order and the verification step. Over MCP, `get_scan` with `view` `full` returns the JSON report, and `view` `markdown` returns the Markdown document. The default `view` `summary` returns the score, the category scores and the top recommendations only — it carries no check results. No `view` returns the ai-instructions document; the MCP prompt `fix_top_issues` plays that role. ## Step 3 — Read the report The report carries a score, three category scores, 34 check results and a ranked recommendation list. **Score.** Each category scores 0 to 100. The overall score weights them: schema 40%, structure 30%, citability 30%. **Category score.** Every check has a `weight` from 1 to 5 inside its category and a `score` from 0 to 1. The category score is the weighted mean of its check scores, rescaled to 0 to 100: the mean of the 0-to-1 scores, times 100, rounded. A check marked `notApplicable` leaves both sides of that mean — an FAQPage check on a navigational page neither helps nor hurts. **Check result.** One entry per check: ```json { "id": "schema-jsonld-present", "category": "schema", "weight": 5, "pass": false, "score": 0, "evidence": "No JSON-LD blocks found in the document.", "fix": { "kind": "jsonld", "title": "…", "payload": "…", "guidance": "…" } } ``` `pass` is the hard verdict. `score` is the graded one — a graded check can score 0.6 and still fail its threshold, so read `score` when you rank near-misses. `evidence` states what the scan found. `notApplicable: true` means the check did not apply. **Recommendations.** `report.recommendations` is the work list, highest `priority` first. Each entry names its `checkId` and carries `fix.payload`: the exact JSON-LD block or the content edit to make. `fix.kind` is `jsonld` or `content`. That payload is what you apply — the playbook below tells you what the check is about. **What a free caller sees.** All 34 check results, and fix content for the first 3 recommendations. The rest come back as `{"locked": true}` with only `checkId`, `category`, `priority` and `summary`, and the report sets `"gated": true` whenever it withheld anything. A Pro or Agency API key unlocks the complete fix list. Never guess a locked payload — read the check id in the playbook below and fix it from there. ## Step 4 — Fix playbook One line per check: the id you will see in a report, what it measures and the fix. The catalogue is also published at https://blockquote.io/checks, one anchor per check id (for example https://blockquote.io/checks#schema-jsonld-present). The block below is generated from Blockquote's check catalogue (`packages/types/src/check-catalog.ts`) and a test pins it there. Do not edit it by hand. ### Schema — 40% of the score - `schema-jsonld-present` — JSON-LD present. Whether the page embeds any JSON-LD structured data at all. **Fix:** Add a