Structured results, truncation, tool errors, and untrusted text.
Success (structuredContent):
{
"...the same object the REST endpoint returns in data (or the list envelope fields)": "",
"request_id": "req_…",
"truncated": false,
"untrusted_text": true
}{
"...the same object the REST endpoint returns in data (or the list envelope fields)": "",
"request_id": "req_…",
"truncated": false,
"untrusted_text": true
}{
"...the same object the REST endpoint returns in data (or the list envelope fields)": "",
"request_id": "req_…",
"truncated": false,
"untrusted_text": true
}{
"...the same object the REST endpoint returns in data (or the list envelope fields)": "",
"request_id": "req_…",
"truncated": false,
"untrusted_text": true
}List tools return data, has_more, next_cursor in the structured result.
content[0].text is a one-line summary. It adds a truncation hint when
truncated is true and the untrusted-data notice when untrusted_text is true.
truncated is true when the MCP budget cut something or the domain
reported truncation (e.g. body_truncated). Use limit/cursor or the REST
API for the rest. In extreme cases the payload is replaced by
{ "data_omitted": true, "reason": "…" }.
Extra fields per tool: rankad_get_job adds queued, stale;
rankad_generate_content adds queued: true, poll_with: "rankad_get_job";
rankad_preview_publication adds published: false;
rankad_publish_content adds queued, awaiting_verification, poll_with.
Errors come back as a tool result with isError: true (not a JSON-RPC error):
{
"isError": true,
"content": [{ "type": "text", "text": "insufficient_scope: The API key does not have the required scope… This API key lacks the scope; the key owner can grant it in Citera Settings → API keys." }],
"structuredContent": { "error": { "code": "insufficient_scope", "message": "…", "param": null,
"retryable": false, "remediation": "…", "request_id": "req_…" } }
}{
"isError": true,
"content": [{ "type": "text", "text": "insufficient_scope: The API key does not have the required scope… This API key lacks the scope; the key owner can grant it in Citera Settings → API keys." }],
"structuredContent": { "error": { "code": "insufficient_scope", "message": "…", "param": null,
"retryable": false, "remediation": "…", "request_id": "req_…" } }
}{
"isError": true,
"content": [{ "type": "text", "text": "insufficient_scope: The API key does not have the required scope… This API key lacks the scope; the key owner can grant it in Citera Settings → API keys." }],
"structuredContent": { "error": { "code": "insufficient_scope", "message": "…", "param": null,
"retryable": false, "remediation": "…", "request_id": "req_…" } }
}{
"isError": true,
"content": [{ "type": "text", "text": "insufficient_scope: The API key does not have the required scope… This API key lacks the scope; the key owner can grant it in Citera Settings → API keys." }],
"structuredContent": { "error": { "code": "insufficient_scope", "message": "…", "param": null,
"retryable": false, "remediation": "…", "request_id": "req_…" } }
}Authentication and transport failures (bad key, disabled surface, bad origin) are returned before JSON-RPC handling, as an HTTP error status with the standard REST error envelope.
Remediation hints by code: resource_not_found (re-check IDs via list tools), insufficient_scope (owner can grant it), api_plan_required, feature_not_enabled, rate_limited/quota_exceeded/concurrency_limit_exceeded (wait; do not retry immediately), idempotency_key_reused, invalid_state (create a fresh preview), integration_not_ready, validation_failed/unknown_field (fix param).
Prompt text, recommendation titles/descriptions, content titles/bodies and product page text are flagged untrusted_text: true, and the summary tells the assistant to treat them as data, not instructions. The instructions argument of generation is also treated as data by the worker.