Scripts and CI
Call RankX AI's MCP server directly with a bearer token. The JSON-RPC sequence in cURL, Node and Python, and why OAuth is not an option here.
For a script, a cron job or a CI pipeline, use a personal access token in an
Authorization header and speak JSON-RPC to POST /api/mcp directly. This is the
only supported path for an unattended caller, and it is not a legacy one.
OAuth cannot work here. RankX AI's authorisation server implements the authorisation-code flow with PKCE and nothing else, so every OAuth credential requires a human at a browser. Refresh tokens also rotate with theft detection: a daemon that fails to persist the new value is not degraded, it is disconnected.
Create a token for the job
In RankX AI's MCP settings (owner-only), create a token and give it only the
scopes the job needs. A nightly reporting script wants read and nothing more.
A tool outside a token's scopes is not listed and not callable, so a read-only
token cannot be made to write, spend or publish even by a bug in your script.
Store it wherever you store secrets. Never in the repository.
The sequence
Three calls, in order:
initialize, which is where the connection identifies itself.tools/list, which returns exactly the tools your token's scopes reach, with the current price already written into the description of every tool that spends.tools/call, one per tool.
RANKXAI_TOKEN="rxai_your_token_here"
ENDPOINT="https://app.rankxai.com/api/mcp"
# 1. initialize
curl -sS "$ENDPOINT" \
-H "Authorization: Bearer $RANKXAI_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "reporting-script", "version": "1.0.0" }
}
}'
# 2. tools/list
curl -sS "$ENDPOINT" \
-H "Authorization: Bearer $RANKXAI_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'
# 3. tools/call
curl -sS "$ENDPOINT" \
-H "Authorization: Bearer $RANKXAI_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": { "name": "list_projects", "arguments": {} }
}'What comes back
Every tool returns three things, and which one you want depends on the caller:
structuredContent, the machine-readable payload. This is what a script should read.content, a human-readable rendering for text-only clients._meta, which carries the Website acted on, a deep link into RankX AI, and for a tool that spends, the credits charged and the balance remaining.
Every tool also publishes an output schema in tools/list, so a strict client
can validate what it receives.
Rules a script has to respect
Poll the three dispatch-and-poll pairs. start_site_audit,
generate_article and get_keyword_trends return an id immediately and do the
work in the background. A script that treats the first response as the answer
will record an empty result as a failure. Poll with the matching status tool at a
sensible interval, and do not re-dispatch a job that is already in flight.
Read the rate limits as real limits. Two windows, both per account and shared
across every credential on it: 600 calls an hour, and a tighter 120 an
hour for every call whose scope is not read. A write consumes one of each, so
a publishing loop hits the second one first. Both fail closed: if the limiter
cannot be read, the request is denied. Back off rather than retrying
immediately.
Never treat null as zero. Any metric field can be null, and null means
unmeasured. A report that renders it as 0% is telling its reader they are
invisible when nothing was measured.
Handle a refusal by reading which one it is. There are four, with four different remedies, and only one of them is fixed by adding credits. See credits and metering.
Do not spend on a schedule without a ceiling. The spend tools exist so an
agent can act, not so a cron job can run a full sweep nightly by accident. Check
the balance first with get_credit_balance, which is free.
Identify your client
clientInfo in initialize is worth setting to something meaningful. RankX AI
records it per credential, so a connection that identifies itself as
reporting-script is distinguishable from one that does not identify itself at
all, which is what you want when you are working out where a spend came from.
Where to go next
- Authentication for scopes and rate limits.
- The tool reference for every tool and its inputs.
- Examples for the dispatch-and-poll pairs worked through.
Connect Cursor, VS Code and Windsurf
Add RankX AI to an editor's MCP configuration with a bearer token. The three config blocks, whose key names differ, and how to keep the token out of git.
Authentication and scopes
How RankX AI's MCP server authenticates. OAuth against personal access tokens, the scopes, client-scoped tokens, rate limits and revocation.