mcp
run_audit
Strumento MCP che mette in coda un audit SEO completo con Core Web Vitals. Restituisce subito un audit_id, poi fai polling su get_audit fino a complete.
Cosa fa questo strumento
run_audit mette in coda un audit completo di SEO e leggibilità AI e restituisce immediatamente l’envelope dell’audit. È la versione autenticata e full-fat di run_audit_anonymous.
- Mette in coda l’audit in modo asincrono e restituisce
status: queuedpiù un veroaudit_idin 1-2 secondi. - Recupera i Core Web Vitals (LCP, CLS, INP) da Google PageSpeed Insights come parte del run.
- Se l’utente ha collegato Google Analytics 4 e Search Console, recupera anche i segnali di traffico organico, esposti separatamente tramite
get_organic_traffic. - Conta sulla disponibilità del piano dell’utente (Free 10/mese, Starter 50/mese, Pro illimitato) e rispetta i cooldown per dominio.
- Restituisce la stessa forma
McpAuditResponsediget_audit. I finding saranno vuoti finché l’audit non passa acomplete.
Perché è importante
run_audit è lo strumento giusto ogni volta che ti serve un audit persistente da recuperare in seguito, un PDF, dati di traffico organico o Core Web Vitals. Gli audit anonimi coprono ~90 check ma saltano PSI; questo strumento copre tutto.
Workflow concreti:
- Un bot di audit-su-PR chiama
run_auditquando viene rilasciato un preview deploy, cattura l’audit_id, fa polling suget_auditogni 5 s fino a 60 s e pubblica un commento delta rispetto all’ultimo audit dello stesso URL. - Un agente cron settimanale itera sulle landing page più visitate dell’utente e mette in coda un nuovo
run_auditper ciascuna, poi invia per email un digest dalist_audits.
Come usarlo
Lo strumento è asincrono per design. Tratta la risposta immediata come una conferma di ricezione, poi fai polling su get_audit con l’audit_id restituito ogni pochi secondi. Il completamento end-to-end tipico è 10-30 s; concedi fino a 90 s per target lenti.
Schema di input
{
"type": "object",
"properties": {
"url": { "type": "string", "format": "uri", "maxLength": 2000 }
},
"required": ["url"]
}
Esempio di schema di risposta
{
"audit_id": "aud_01HZ8X9YP7K3T2N6Q5",
"url": "https://example.com",
"status": "queued",
"total_score": null,
"module_scores": {},
"findings": [],
"report_url": "https://app.metricspot.com/audits/aud_01HZ8X9YP7K3T2N6Q5",
"created_at": "2026-05-13T10:18:04.000Z"
}
Quando l’audit si completa, la stessa forma viene restituita da get_audit con status: "complete", un total_score popolato, module_scores e l’array findings.
Claude Code
claude mcp add --transport http metricspot https://mcp.metricspot.com/mcp \
--header "Authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"
Prompt:
Esegui un audit MetricSpot completo su https://example.com, fai polling fino al completamento e riassumi i finding falliti di livello critico e major.
Cursor
.cursor/mcp.json:
{
"mcpServers": {
"metricspot": {
"url": "https://mcp.metricspot.com/mcp",
"headers": {
"Authorization": "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
Prompt:
Metti in coda un audit per questa pagina, aspetta il completamento e dimmi i miei punteggi Core Web Vitals.
Python (esegui + polling)
import httpx, time, json
URL = "https://mcp.metricspot.com/mcp"
HEADERS = {
"content-type": "application/json",
"accept": "application/json, text/event-stream",
"authorization": "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx",
}
def call(name, args):
r = httpx.post(URL, headers=HEADERS, json={
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": name, "arguments": args},
}, timeout=60.0)
return json.loads(r.json()["result"]["content"][0]["text"])
queued = call("run_audit", {"url": "https://example.com"})
audit_id = queued["audit_id"]
for _ in range(30):
time.sleep(3)
result = call("get_audit", {"audit_id": audit_id})
if result["status"] in ("complete", "failed"):
break
print(result["total_score"], len(result["findings"]))
Node / TypeScript (con @modelcontextprotocol/sdk)
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://mcp.metricspot.com/mcp"),
{
requestInit: {
headers: { authorization: "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx" },
},
},
);
const client = new Client({ name: "audit-on-pr", version: "1.0.0" });
await client.connect(transport);
const queued = await client.callTool({
name: "run_audit",
arguments: { url: "https://example.com" },
});
const auditId = JSON.parse(queued.content[0].text as string).audit_id;
console.log("queued", auditId);
Errori comuni
| Codice | Quando | Azione |
|---|---|---|
UNAUTHORIZED (401) | Bearer token mancante o non valido | Genera una chiave su https://app.metricspot.com/settings/api-keys |
QUOTA_EXCEEDED (402) | Disponibilità mensile del piano raggiunta | Aggiorna su https://app.metricspot.com/billing |
RATE_LIMITED (429) | Cooldown per dominio raggiunto | Aspetta la finestra indicata prima di rimettere in coda lo stesso dominio |
INVALID_URL (400) | URL non valido, host non pubblico o > 2000 caratteri | Passa un URL assoluto https:// |
UPSTREAM_FAILED (5xx) | Singhiozzo di PSI o del crawler upstream | Riprova una volta con backoff |
Domande frequenti
Quanto ci vuole perché l’audit sia complete?
10-30 secondi per siti tipici. Target lenti, pagine JS-heavy o siti con grandi quantità di dati strutturati possono richiedere fino a 90 secondi. Fai polling su get_audit ogni 3-5 secondi; l’audit è completamente calcolato quando status passa a complete.
run_audit costa un audit anche se fallisce?
Un audit failed non consuma disponibilità di piano. La quota decrementa solo quando il run si completa con successo e i finding sono salvati. I fallimenti per rate-limit PSI vengono riprovati internamente prima di essere esposti.
Posso ottenere PDF e traffico organico nella stessa chiamata?
No, sono strumenti separati per design. Dopo che run_audit si completa, chiama get_audit_pdf per l’URL PDF firmato e get_organic_traffic per lo snapshot GA4 + GSC. Entrambi fanno riferimento allo stesso audit_id.
Fonti
Ultimo aggiornamento 2026-05-13