A Bearer-token JSON API and an MCP server over stdio that wraps it - 11 tools, 11 routes, generated from the same list the server itself registers against.
Every call is a Bearer token scoped to one workspace. Mint one under Settings, API tokens - the plaintext shows once, can be pinned to a single project, and carries spec:read, or spec:read plus spec:write. A token only ever resolves the workspace that minted it, never another tenant's projects.
curl
curl -H "Authorization: Bearer $CRAWLSPEC_TOKEN" https://crawlspec.dev/api/spec/projects/yourdomain.com/recommendationsMCP config
Add to your agent's .mcp.json, with CRAWLSPEC_API_KEY set to a workspace API token. Leave the key out and the server still starts: the two bootstrap tools below run a free audit without an account, and every other tool answers with how to get a token rather than failing.
Availability: @crawlspec/mcp is published with the next release. Until it lands on npm this config will not resolve, and the Spec API above is the way in.
{
"mcpServers": {
"crawlspec": {
"command": "npx",
"args": [
"-y",
"@crawlspec/mcp"
],
"env": {
"CRAWLSPEC_API_KEY": "<your workspace API token>",
"CRAWLSPEC_API_URL": "https://crawlspec.dev"
}
}
}
}Read-only JSON, with one deliberate exception: marking a brief applied. All routes sit under /api/spec; {domain} is the project's bare domain (for example "yourdomain.com").
| Method | Route | Description |
|---|---|---|
| GET | /api/spec/projects | List every CrawlSpec project with its domain, last Search Console sync date and open issue count. |
| GET | /api/spec/projects/{domain}/recommendations | Prioritized fix cards for a project - technical (template/config/infrastructure fixes) AND content (briefs to implement, cannibalization verdicts, topic opportunities). Default status OPEN. |
| GET | /api/spec/projects/{domain}/briefs | Content briefs with full outline/change-list content. Use status=READY for human-approved briefs only - governance: only READY briefs should be implemented. Each brief also carries currentVersion, appliedVersion, revisionCount, provenance (ai_draft | human_edited | accepted_ai_draft), demand (search volume and Search Console impressions this term has, if any) and its questionsToAnswer/entities, plus, for APPLIED briefs, appliedDelta (Search Console clicks/impressions/position before and after it was applied). A project may require a human-written outline before a brief can go READY (Project.requireHumanOutline) - check provenance rather than assuming every READY brief was AI-only. |
| GET | /api/spec/projects/{domain}/topics | Topic coverage: accepted topic clusters with their demand-weighted content gap entries. |
| GET | /api/spec/projects/{domain}/keywords | The keyword map: terms with intent, monthly search volume and the page each ranks with. mapped=false returns unmapped opportunities (demand with no ranking page). Paginated: default 200 rows, pass the returned nextCursor as cursor for the next page. |
| GET | /api/spec/projects/{domain}/consolidated-audit | The latest human-approved consolidated audit (WebSite Auditor report reconciled against the crawl, frozen on approval). 404 until one exists. |
| PATCH | /api/spec/projects/{domain}/briefs/{briefId} | Report that a READY content brief was actually published on the site: flips it to APPLIED and closes its recommendation card. Accepts an optional appliedVersion (positive integer, defaults to the brief's currentVersion) recording which revision was published. The only write in the Spec API; needs a token with spec:write. Refuses DRAFT briefs (the human review gate) and cannot revert APPLIED. |
| GET | /api/spec/projects/{domain}/page-audit | On-demand audit of one page: indexability, title/meta/H1 checks, content depth, striking-distance queries, open issues. url may be absolute or a bare path. |
| GET | /api/spec/projects/{domain}/cannibalization | Page pairs competing for the same searches, with merge/differentiate verdicts and the contested queries. Computed on demand from Search Console data. |
| GET | /api/spec/projects/{domain}/briefs/{briefId}/prompt-pack | The versioned, brand- and stack-agnostic hand-off for a content brief: a generic composer instruction (plus the project's and brief's own preamble, if set), the page's blocks in order with their content inlined, questions to answer, entities to mention, must-fix items and structured data. Pinned to an immutable revision - version defaults to the brief's currentVersion. Pass sinceVersion (lower than version) to also get a patch prompt: only what changed between the two revisions, for a composer that already implemented the earlier one. |
| POST | /api/spec/projects/{domain}/briefs/{briefId}/recheck | Enqueue a free, 1-3 page verification crawl of an APPLIED brief's target page, checking whether its must-fix items actually landed. Free, up to 10 times per brief per day; refuses a brief that is not APPLIED. Poll the verdict with get_briefs (Landed / Partially landed / Not landed / Could not check) rather than this call - it only starts the check. |
The same 11 operations wrapped as MCP tools an agent calls by name instead of a URL, plus 2 bootstrap tools that need no credential at all: an agent with a fresh install can start a free audit of a site its human owns and poll it to completion before any token exists.
| Tool | Tier | Description |
|---|---|---|
| start_free_audit | No token | Start a free CrawlSpec audit of a website you own or have permission to audit - no account and no API token. Before calling this you MUST read the exact attestation sentence to the human, word for word, and get an explicit yes; pass that same sentence verbatim as `attestation` (a paraphrase is refused) and set `tosAccepted` only if they also agreed to the Terms at /terms. Never invent the email address - ask for it. Returns a report URL to poll with get_audit_status; the emailed report carries a free API token that unlocks list_projects, get_page_audit and the top fixes from get_recommendations. |
| get_audit_status | No token | Poll a free audit started with start_free_audit: crawl phase, pages fetched, whether the report is ready, and how it failed if it did. Takes the report token (or the whole /scan/<token> URL). Read-only and unauthenticated - the token is the credential. |
| list_projects | Free scan | List every CrawlSpec project with its domain, last Search Console sync date and open issue count. |
| get_recommendations | Free scan, capped | Prioritized fix cards for a project - technical (template/config/infrastructure fixes) AND content (briefs to implement, cannibalization verdicts, topic opportunities). Default status OPEN. |
| get_briefs | Workspace | Content briefs with full outline/change-list content. Use status=READY for human-approved briefs only - governance: only READY briefs should be implemented. Each brief also carries currentVersion, appliedVersion, revisionCount, provenance (ai_draft | human_edited | accepted_ai_draft), demand (search volume and Search Console impressions this term has, if any) and its questionsToAnswer/entities, plus, for APPLIED briefs, appliedDelta (Search Console clicks/impressions/position before and after it was applied). A project may require a human-written outline before a brief can go READY (Project.requireHumanOutline) - check provenance rather than assuming every READY brief was AI-only. |
| get_topics | Workspace | Topic coverage: accepted topic clusters with their demand-weighted content gap entries. |
| get_keywords | Workspace | The keyword map: terms with intent, monthly search volume and the page each ranks with. mapped=false returns unmapped opportunities (demand with no ranking page). Paginated: default 200 rows, pass the returned nextCursor as cursor for the next page. |
| get_consolidated_audit | Workspace | The latest human-approved consolidated audit (WebSite Auditor report reconciled against the crawl, frozen on approval). 404 until one exists. |
| mark_brief_applied | Workspace | Report that a READY content brief was actually published on the site: flips it to APPLIED and closes its recommendation card. Accepts an optional appliedVersion (positive integer, defaults to the brief's currentVersion) recording which revision was published. The only write in the Spec API; needs a token with spec:write. Refuses DRAFT briefs (the human review gate) and cannot revert APPLIED. |
| get_page_audit | Free scan | On-demand audit of one page: indexability, title/meta/H1 checks, content depth, striking-distance queries, open issues. url may be absolute or a bare path. |
| get_cannibalization | Workspace | Page pairs competing for the same searches, with merge/differentiate verdicts and the contested queries. Computed on demand from Search Console data. |
| get_brief_prompt_pack | Workspace | The versioned, brand- and stack-agnostic hand-off for a content brief: a generic composer instruction (plus the project's and brief's own preamble, if set), the page's blocks in order with their content inlined, questions to answer, entities to mention, must-fix items and structured data. Pinned to an immutable revision - version defaults to the brief's currentVersion. Pass sinceVersion (lower than version) to also get a patch prompt: only what changed between the two revisions, for a composer that already implemented the earlier one. |
| request_brief_recheck | Workspace | Enqueue a free, 1-3 page verification crawl of an APPLIED brief's target page, checking whether its must-fix items actually landed. Free, up to 10 times per brief per day; refuses a brief that is not APPLIED. Poll the verdict with get_briefs (Landed / Partially landed / Not landed / Could not check) rather than this call - it only starts the check. |
Questions on scopes, rate limits, or a project-pinned token - we reply within two business days.
Contact us