Agent MCP tools
Connect an agent to the Rankbox MCP server with an agent key or OAuth and use the full tool set: inputs, outputs, example calls and anonymous access.
On this page
The Rankbox MCP server at https://rankbox.xyz/mcp exposes the agent API as Model Context Protocol tools. An agent that speaks MCP can create an account, plan, write, publish and check billing without writing HTTP code. Each tool takes the same fields and returns the same JSON as the matching agent API endpoint.
Anonymous and authenticated access
The server answers both anonymous and authenticated clients, with different tools:
| Anonymous | Authenticated | |
|---|---|---|
| Credential | None | Authorization: Bearer rv_agent_…, or an OAuth access token |
| Tools | generate_ai_questions, generate_content_brief, write_meta_descriptions, create_account | Those four plus the full tool set below |
| Acts on | No account | The whole account and every site on it |
| Credits | None | The account's own, exactly as through the API |
The three public tools are the free research tools anyone can use. create_account lets an agent with no account create one; it then reconnects with the agent key it gets back. An authenticated client sees every tool in tools/list, including the four anonymous ones.
Server details
| Property | Value |
|---|---|
| URL | https://rankbox.xyz/mcp |
| Transport | Streamable HTTP |
| Server name | rankbox-mcp |
| Authentication | Bearer header, or OAuth 2.1 per the MCP authorization spec |
| Protected resource metadata | https://rankbox.xyz/.well-known/oauth-protected-resource |
Connect with an agent key
Pass the key as a header. Keep it in an environment variable rather than in a config file you might commit.
claude mcp add --transport http rankbox https://rankbox.xyz/mcp \
--header "Authorization: Bearer $RANKBOX_AGENT_KEY"{
"mcpServers": {
"rankbox": {
"url": "https://rankbox.xyz/mcp",
"headers": { "Authorization": "Bearer ${env:RANKBOX_AGENT_KEY}" }
}
}
}import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(new URL("https://rankbox.xyz/mcp"), {
requestInit: { headers: { Authorization: `Bearer ${process.env.RANKBOX_AGENT_KEY}` } },
});
const client = new Client({ name: "atlas", version: "1.0.0" });
await client.connect(transport);
const { structuredContent } = await client.callTool({ name: "get_account", arguments: {} });import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
headers = {"Authorization": f"Bearer {os.environ['RANKBOX_AGENT_KEY']}"}
async with streamablehttp_client("https://rankbox.xyz/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("get_account", {})
account = result.structuredContent["account"]The Cursor example goes in .cursor/mcp.json or ~/.cursor/mcp.json. For other clients, see Connect your AI tools and add the same header.
Connect with OAuth
MCP clients that implement the MCP authorization spec (Claude, ChatGPT and others) need only the URL. On the first call without a token, the server answers 401 with a WWW-Authenticate header that points to the protected resource metadata. The client registers itself, opens Rankbox's consent page in a browser and stores the tokens.
- Add
https://rankbox.xyz/mcpas a custom connector or remote MCP server in the app. - The app opens
https://rankbox.xyz/oauth/consent. The owner signs in if needed. - The page says "{app} wants to use your Rankbox account" and lists what it can do: everything in the account.
- The owner clicks Connect. The app receives an access token and a refresh token and lists the full tool set.
The connection appears under Dashboard → Settings → Agent access with the app's name, and the owner can disconnect it there. The details of the flow are in the OAuth 2.1 walkthrough.
Create an account from MCP
An agent with no account connects anonymously and calls create_account:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_account",
"arguments": {
"email": "maya@northwind.example",
"site_url": "https://northwind.example",
"site_name": "Northwind Analytics",
"agent": { "name": "Atlas", "operator": "Northwind Analytics" },
"idempotency_key": "0f7c1d52-create-northwind"
}
}
}The result's structuredContent is the POST /accounts response: account, site, scan_job_id, agent_key (with the secret key) and claim_url. Store agent_key.key, then reconnect with the Authorization header to get the full tool set. The same limits and duplicate-email rules apply as in Create an account as an agent.
How the tools behave
- Same data as the API. Each tool's
structuredContentis the JSON body the matching endpoint returns, for example{ "article": { … } }. Thecontenttext block is a short readable summary for the model. - Snake_case inputs. Inputs use the API's field names. Path parameters become inputs:
site_id,article_id,job_id,thread_id. - Errors. A failed call returns a result with
isError: trueandstructuredContentset to the API error envelope, for example{ "error": "…", "code": "insufficient_credits" }. The codes are the same as in Errors. - Long work. Tools that start a job (
run_scan,run_research,generate_article,sync_integration,run_reddit_sweep) return the job at once. Callget_jobwithwait: 30until it ends. No tool blocks for minutes. - Retries. Tools that spend credits or money take an optional
idempotency_key, which works like theIdempotency-Keyheader. - Annotations. Read tools carry
readOnlyHint: true.delete_article,remove_siteandrevoke_agent_keycarrydestructiveHint: true. Clients that confirm destructive tools ask before running these.
Tool reference
Optional inputs are marked with ?. Every site tool needs site_id; it is listed once per table.
Public tools
| Tool | Inputs | Output |
|---|---|---|
generate_ai_questions | topic (2 to 200 characters) | groups: [{ intent, questions[] }], intents Informational, Commercial, Comparison, Transactional |
generate_content_brief | keyword (2 to 200 characters) | brief: title, outline[{ heading, points[] }], questions[], entities[] |
write_meta_descriptions | topic (2 to 600 characters) | options: three meta descriptions of 120 to 160 characters |
create_account | email, site_url, site_name?, site_description?, agent { name, operator?, contact_url? }, idempotency_key? | account, site, scan_job_id, agent_key, claim_url |
These three public tools spend no credits and don't touch an account, even when called by an authenticated client. See MCP tool reference for their full behavior.
Account tools
| Tool | Inputs | Output | API |
|---|---|---|---|
get_account | none | account | GET /account |
resend_claim_email | none | sent, claim_url | POST /account/resend-claim |
list_agent_keys | none | agent_keys[] | GET /agent-keys |
create_agent_key | name, operator?, contact_url? | agent_key with key | POST /agent-keys |
revoke_agent_key | id | revoked, id | DELETE /agent-keys/{id} |
list_activity | actor_id?, site_id?, since?, limit?, cursor? | activity[], next_cursor | GET /activity |
Site tools
| Tool | Inputs | Output | API |
|---|---|---|---|
list_sites | none | sites[] | GET /sites |
get_site | site_id | site | GET /sites/{site_id} |
create_site | site_url, site_name, site_description?, logo_url?, proration_date?, idempotency_key? | site, scan_job_id, charged | POST /sites |
update_site | brand_name?, website_url?, product_description?, avatar_url?, writing? { tone, writing_style, audience, brand_voice } | site | PATCH /sites/{site_id} |
remove_site | site_id | site with removes_at | DELETE /sites/{site_id} |
restore_site | proration_date?, idempotency_key? | site, charged | POST /sites/{site_id}/restore |
get_scan | site_id | scan | GET /sites/{site_id}/scan |
run_scan | site_id | job | POST /sites/{site_id}/scan |
create_site and restore_site charge the card on file. Ask the owner first unless they told you to go ahead.
Research and plan tools
| Tool | Inputs | Output | API |
|---|---|---|---|
run_research | seed?, ideas? (0 to 30), save? | job (result: keywords, ideas, saved) | POST /sites/{site_id}/research |
list_keywords | source? (library or discovered) | keywords[] | GET /sites/{site_id}/keywords |
add_keyword | name, intent?, search_volume?, tag?, trend? | keyword | POST /sites/{site_id}/keywords |
delete_keyword | keyword_id | deleted, id | DELETE /sites/{site_id}/keywords/{keyword_id} |
Article tools
| Tool | Inputs | Output | API |
|---|---|---|---|
list_articles | status?, updated_since?, include_body?, limit?, cursor? | articles[], next_cursor | GET /sites/{site_id}/articles |
create_article | title, keyword?, description?, status?, scheduled_date?, queue_position?, body?, tags?, notes? | article | POST /sites/{site_id}/articles |
get_article | article_id | article with all bodies | GET …/articles/{article_id} |
update_article | article_id, then any of title, keyword, description, body, tags, notes, status, scheduled_date, queue_position | article | PATCH …/articles/{article_id} |
delete_article | article_id | deleted, id | DELETE …/articles/{article_id} |
generate_article | article_id, word_count? (800 to 6,000), idempotency_key? | job | POST …/generate |
get_job | job_id, wait? (0 to 30 seconds) | job | GET /jobs/{job_id} |
list_jobs | status?, type?, site_id? | jobs[] | GET /jobs |
rewrite_section | article_id, selection, action, apply? | rewrite, article | POST …/rewrite-section |
score_article | article_id | analysis | GET …/score |
finish_article | article_id | article, deliveries | POST …/finish |
publish_article | article_id, published_url? | article, deliveries | POST …/publish |
generate_article spends 1 article credit. get_job is an account tool and takes no site_id.
Autopilot and publishing tools
| Tool | Inputs | Output | API |
|---|---|---|---|
get_autopilot | site_id | autopilot | GET /sites/{site_id}/autopilot |
set_autopilot | enabled?, weekly_cadence? (1 to 7) | autopilot | PATCH /sites/{site_id}/autopilot |
list_integrations | site_id | integrations[] | GET /sites/{site_id}/integrations |
get_integration | integration_id, webflow_site_id?, collection_id? | integration, options | GET …/integrations/{integration_id} |
connect_integration | integration_id | connection (authorize_url, install_url or site_key) | POST …/connect |
configure_integration | integration_id, then the platform's fields | integration | PATCH …/integrations/{integration_id} |
sync_integration | integration_id | job | POST …/sync |
disconnect_integration | integration_id | integration | DELETE …/integrations/{integration_id} |
list_site_api_keys | site_id | site_keys[] | GET /sites/{site_id}/keys |
create_site_api_key | name? | site_key with key | POST /sites/{site_id}/keys |
revoke_site_api_key | key_id | site_key | DELETE /sites/{site_id}/keys/{key_id} |
Credits, Rank and growth tools
| Tool | Inputs | Output | API |
|---|---|---|---|
get_credits | site_id | credits | GET /sites/{site_id}/credits |
get_rank | site_id | rank | GET /sites/{site_id}/rank |
get_backlinks | site_id | backlinks | GET /sites/{site_id}/backlinks |
update_backlink_settings | opted_in?, max_links_per_article?, niche?, topic_tags?, blocked_categories? | backlinks | PATCH /sites/{site_id}/backlinks |
set_backlink_domain | domain | verification | POST …/backlinks/domain |
verify_backlink_domain | site_id | verification | POST …/backlinks/domain/verify |
list_backlink_targets | site_id | targets[] | GET …/backlinks/targets |
add_backlink_target | url, anchors (3 to 5), topic_tags?, priority?, max_new_links_per_month? | target | POST …/backlinks/targets |
list_backlinks | direction? (inbound or hosted), status? | placements[] | GET …/backlinks/placements |
get_reddit | site_id | reddit | GET /sites/{site_id}/reddit |
update_reddit_settings | any field of PATCH /sites/{site_id}/reddit | reddit | PATCH /sites/{site_id}/reddit |
run_reddit_sweep | site_id | job | POST …/reddit/sweeps |
list_reddit_threads | status? | threads[] | GET …/reddit/threads |
draft_reddit_reply | thread_id, instructions?, idempotency_key? | draft | POST …/reddit/threads/{thread_id}/drafts |
submit_reddit_permalink | thread_id, draft_id?, permalink? | reply | POST …/reddit/replies |
draft_reddit_reply spends 1 Reddit reply credit. There is no tool that posts to Reddit. A person posts the draft from their own account, then you call submit_reddit_permalink.
Billing and event tools
| Tool | Inputs | Output | API |
|---|---|---|---|
get_billing | none | billing | GET /billing |
create_checkout_link | none | checkout with checkout_url | POST /billing/checkout |
create_portal_link | none | portal with portal_url | POST /billing/portal |
activate_plan | idempotency_key? | billing, charged | POST /billing/activate |
get_studio_quote | none | studio_quote | GET /billing/studio-quote |
list_events | since?, cursor?, types?, site_id?, limit? | events[], next_cursor, has_more | GET /events |
Webhooks need an HTTPS endpoint, so they are managed through the API only. An MCP agent follows events with list_events.
Example: plan and write one article
A typical session with an authenticated client, as tool calls:
list_sites→ takesites[0].idassite_id.list_articleswith{ "site_id": "6f1c2a9e-4b7d-4e2a-8c3f-1d9e5b7a2c64", "status": "opportunity" }→ pick an idea.generate_articlewith the idea'sarticle_id→ returns a job.get_jobwith{ "job_id": "9a7e5c3b-1d2f-4e6a-8b9c-0d1e2f3a4b5c", "wait": 30 }, repeated untilstatusiscompleted.score_article→ readanalysis.checksand fix anything markedfailwithrewrite_section.
The generate_article call and its result:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "generate_article",
"arguments": {
"site_id": "6f1c2a9e-4b7d-4e2a-8c3f-1d9e5b7a2c64",
"article_id": "f2b8c1d4-7e3a-4b9c-a6d5-3e8f1a2b4c76",
"word_count": 2000,
"idempotency_key": "gen-f2b8c1d4"
}
}
}{
"jsonrpc": "2.0",
"id": 7,
"result": {
"content": [
{ "type": "text", "text": "Started writing “How to choose a product analytics tool for B2B SaaS” (1 article credit). Job 9a7e5c3b-1d2f-4e6a-8b9c-0d1e2f3a4b5c is queued; call get_job with wait 30." }
],
"structuredContent": {
"job": {
"id": "9a7e5c3b-1d2f-4e6a-8b9c-0d1e2f3a4b5c",
"type": "article.generate",
"status": "queued",
"site_id": "6f1c2a9e-4b7d-4e2a-8c3f-1d9e5b7a2c64",
"resource": { "type": "article", "id": "f2b8c1d4-7e3a-4b9c-a6d5-3e8f1a2b4c76" },
"result": null,
"error": null,
"created_at": "2026-10-02T15:22:05Z",
"started_at": null,
"finished_at": null
}
}
}
}The same call on an account without a trial:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"isError": true,
"content": [
{ "type": "text", "text": "Start the free trial to generate articles. Create a checkout link with create_checkout_link and send it to the account owner." }
],
"structuredContent": {
"error": "Start the free trial to generate articles. Create a checkout link with create_checkout_link and send it to the account owner.",
"code": "subscription_required"
}
}
}Limits for MCP calls
Authenticated tool calls count against the account's API limits, exactly like REST requests: one tool call is one request, and tools that call an AI model also count toward the AI limit. get_job with wait counts once however long it waits. create_account follows the account creation limits. All numbers are in Billing, credits and limits.
Troubleshooting
- Only four tools are listed. The client is connected anonymously. Check that the
Authorizationheader reaches the server; some clients only send headers configured for remote servers, and some need a restart after a config change. - The tools disappeared after an hour. An OAuth access token expired and the client didn't refresh it. Reconnect the server in the client, which runs the OAuth flow again.
401after the owner disconnected the app. Expected: disconnecting revokes the tokens at once. Ask the owner to connect again if they want you back.- A tool call times out. Use
get_jobwithwaitof 30 or less; a higher value can outlast the client's own timeout. create_sitefailed withhuman_required. The bank asked the cardholder to approve the charge. Send the owneraction_urlfrom the error.
Related
- The Rankbox MCP server: the server for people, with the public tools.
- Agent authentication: agent keys and OAuth in depth.
- Agent API reference: the endpoint behind each tool.
- Events and webhooks: what
list_eventsreturns. - Agent playbooks: end-to-end recipes.