The Ranking Factory is reached by agents in three ways: a read/write MCP server over one customer account, a free MCP server that needs no sign-in, and the same free site check as a plain REST endpoint with an OpenAPI document. Everything below is what those servers answer today.
Account server
com.therankingfactory/mcp
https://therankingfactory.com/api/mcp
One customer account: visibility runs, evidence gaps, cited sources, published evidence and the entity. Reads from the moment a credential connects; writes only with the write scope. Sign in with OAuth or send an agent key.
Free check server
com.therankingfactory/site-check
https://therankingfactory.com/api/mcp/check
No account and no sign-in. One tool, check_site, which changes nothing, asks no AI engine and stores nothing.
Free check REST API
OpenAPI 3.1
GET https://therankingfactory.com/api/public/site-check?url=
The same check as check_site for a client that does not speak MCP, with the same answer.
Both MCP servers speak JSON-RPC 2.0 over HTTP POST (streamable HTTP, no server-push stream: a GET answers 405). They speak MCP 2026-07-28 per request, and 2025-11-25 or 2025-06-18 through initialize. A request body over 64 KB is refused with 413.
Sign in (OAuth)
Add https://therankingfactory.com/api/mcp to a client that supports MCP authorization. An unauthenticated request gets 401 with WWW-Authenticate: Bearer resource_metadata="…" naming the protected-resource metadata; the client follows it to the authorization server. Authorization code with PKCE (S256) and theresource parameter; client identity by a Client ID Metadata Document or registration atPOST /api/oauth/register. Access tokens (rfa_) last one hour; refresh tokens (rfr_) last 30 days and rotate on every use. The customer chooses every project or one.
An agent key
For any MCP client. The customer creates a key under Settings → Agent access, chooses what it may read, and leaves or ticks “Let it make changes” (unticked by default). It is shown once; only its hash is kept. Send it on every request as Authorization: Bearer rft_…. A key sees every project in the account.
Both credentials work on every plan, Starter included, and in the 14-day trial, and only at the MCP endpoint: neither opens anything else on this API. The free check server takes no credential at all.
curl -s https://therankingfactory.com/api/mcp \
-H "Authorization: Bearer rft_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"example","version":"1.0"}}}'
curl -s https://therankingfactory.com/api/mcp \
-H "Authorization: Bearer rft_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'curl -s https://therankingfactory.com/api/mcp/check \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_site","arguments":{"url":"example.com"}}}'tools/list shows a credential only the tools its scopes unlock, and every tool carries the MCP annotations readOnlyHint, destructiveHint, idempotentHint andopenWorldHint. Every read tool answers across all of the account's projects unlessproject (a domain or a project's name) narrows it, and rates come with their sample sizes.
| Tool | Scope | What it does |
|---|---|---|
get_visibility_summary | visibility:read | Recent AI-visibility runs per engine, model and surface: answers back, and how many named, cited or recommended the business, with their denominators. |
get_topic_visibility | visibility:read | Per-topic measurement history: runs that measured each topic, runs that named the business, and runs that named it unprompted. |
list_cited_sources | visibility:read | The sites AI answers actually cited, grouped by site and kind, with declared versus extracted citations and naming rates. |
get_gaps | gaps:read | The evidence-gap list: counts by status, the open items with ids, and citations since each gap's evidence was published. |
get_published_evidence | evidence:read | The published-evidence ledger, newest first: what was published where and when, and which engine first cited it. |
get_topic_evidence_pool | evidence:read | The outside sources a writer may cite for one subject, each fetched and checked, with the refused ones listed as such. |
get_answerability | evidence:read | Whether pages published to the customer's own site answer the questions they are shown for. |
get_entity | entity:read | Who the business is, as asserted: name, type, what it does, where, its main topic and its sameAs links. |
get_claims | entity:read | The facts asserted about the business and its stated relationships, with their confidence. |
get_sources | entity:read | The sources behind the claims, each classed Owned, Controlled, Independent or Unattributable. |
list_waiting | evidence:read | What is written and waiting for the owner's approval, with whether approve_publish can send each item. |
write as well)| Tool | Scope | What it does |
|---|---|---|
update_entity | entity:read | Corrects one project's entity: description, main topic, location, tags and sameAs links. Only the fields passed change. |
confirm_product | entity:read | Says what one of the business's own named products is, from the owner's words or a page on its own site. |
close_gap | gaps:read | Asks the Evidence Engine to work one open gap now, with the same refusals as "Close it now" in the app. |
approve_publish | evidence:read | Approves one item from list_waiting, by id and version, on the owner's instruction. Publishes; cannot be undone from here. |
schedule_held_release | evidence:read | Plans spreading held Google files over N days; starts the schedule only with start: true, on the owner's word. |
run_visibility_now | visibility:read | Starts a visibility run for one project from its saved watchlist, on the account's own AI keys. |
Each write calls the same code as the app's own button, with the same refusals, names one project by its exact domain, and is recorded for the account owner under Settings → Agent access.
| Tool | Scope | What it does |
|---|---|---|
check_site | none | Checks one public website's readiness for AI search, free and without an account: finding titles and tiers, every check made, and a link to the full report. |
visibility:readAI-visibility measurements: runs, per-engine rates, per-topic history.gaps:readThe evidence-gap list: open, in flight, closed, abandoned, and waiting on a person.evidence:readThe published-evidence ledger: what was published where, when, and what AI answers cited.entity:readThe business itself: its identity, the facts asserted about it, and the sources behind them.recommendations:readThe project reviewer's recommendations, where the reviewer is switched on for the account. Reading only.writeMake changes through the six write tools. Never granted by default: a box that starts unticked on every connection and key.A write tool called without write answers 403 withWWW-Authenticate: Bearer error="insufficient_scope" and a scope naming the scopes the credential holds plus the ones the tool needs.
check_site and the REST endpoint, and 20 checks of one site a day.Every call to a write tool carries the IETF rate-limit headers (draft-ietf-httpapi-ratelimit-headers):RateLimit-Policy with the quota and the window in seconds, and RateLimit with what is left and the seconds until the oldest counted attempt leaves the hour. A call the ceiling refused also carriesRetry-After. The refusal itself is a tool error inside a 200, as every write refusal is.
RateLimit-Policy: "writes";q=30;w=3600 RateLimit: "writes";r=0;t=1260 Retry-After: 1260
Every error body is JSON.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://therankingfactory.com/.well-known/oauth-protected-resource/api/mcp", scope="…"
{"error":"This endpoint needs a credential: sign in from your AI client (OAuth), or send an agent key as \"Authorization: Bearer rft_…\". How to get either is described at https://therankingfactory.com/.well-known/auth.md"}HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope", resource_metadata="…", scope="…", error_description="…"
{"jsonrpc":"2.0","id":7,"error":{"code":-32001,"message":"close_gap changes the account, and this credential does not hold \"write\". …"}}{"jsonrpc":"2.0","id":8,"result":{"content":[{"type":"text","text":"Refused: … Nothing was changed."}],"isError":true}}Protocol errors are JSON-RPC errors: -32700 the body is not JSON, -32600 not a single request object (batches are not supported), -32601 unknown method, -32602 unknown tool. A 2026-07-28 request that is malformed, mismatched or names an unsupported version is answered 400, and an unknown method 404, each with a JSON-RPC error body.
HTTP/1.1 429 Too Many Requests
Retry-After: 2400
{"code":"site_limit","message":"That site has been checked many times today. …"}Codes: url_required and invalid_url and address_refused (400),busy and site_limit (429, with Retry-After), check_failed (502). The app's own API, behind its login, answers a missing or expired session with 401{"error":"unauthorized","message":"…"} and a refused one with 403{"error":"forbidden","message":"…"}; it is not a public API.
GET https://therankingfactory.com/api/public/site-check?url=example.com runs the free check and answers with the site checked, when, three scores (SEO, GEO and agent readiness, each 0-100 or null), each finding's tier and title (Blocker first), every check made with its result, and fullReport: where the person can have the full report emailed. No key, open to any origin. It is described by an OpenAPI 3.1 document, the only REST API we publish; the rest of our API serves our own app and is not documented for outside use.
curl -s "https://therankingfactory.com/api/public/site-check?url=example.com"
The account server described with its full tool and scope list, generated from the catalogue the server runs on.
The account server's MCP Server Card: name, version, remote and supported protocol versions.
The free check server's MCP Server Card.
How an agent authenticates, in prose (also at /auth.md).
OAuth protected-resource metadata (RFC 9728). Its resource is the account server's URL.
OAuth authorization-server metadata (RFC 8414).
OpenAPI 3.1 for the free site check's REST endpoint - the only REST API we publish (also at /openapi.json).
The API catalog (RFC 9727): one item per API, each with where it is described and documented.
Agentic Resource Discovery catalog listing both MCP servers (the same entries at /.well-known/ai-catalog.json).
What the product is, for AI systems summarising it (the same text at /llms-full.txt).
Every response also carries an RFC 8288 Link header naming llms.txt, the sitemap and the API catalog. Questions, or an interface you need that is not here: [email protected].