reason8_research_*
Tools
reason8_research_start
Start a research workflow. Returns immediately with a run_id and a status the agent can poll with reason8_research_status.
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
artifact | string | yes | The decision, claim, plan, PR summary, copy, or design under review. Paste the actual content — not a pointer to it. |
research_goal | string | yes | The decision this research must inform (e.g. "decide whether to ship billing-first onboarding"). |
target_audience | string | yes | Who the artifact is for (e.g. "B2B SaaS admins evaluating procurement"). |
context | string | no | Supporting evidence the agent already has: constraints, prior findings, links, or file excerpts. |
research_questions | string[] | no | Specific questions for Reason8 to answer. Omit to let Reason8 derive them from the goal. |
desired_output | string | no | The result shape you need back (e.g. "go/no-go memo with the top risks"). |
risk_level | "low" | "medium" | "high" | no | How costly a wrong decision is. Default "medium". Higher risk demands stronger evidence before a proceed verdict. |
client_idempotency_key | string | no | Stable key that makes retries safe. Reuse the same key to replay a prior start instead of creating a duplicate run. |
metadata | object | no | Public-safe key/value tags for the run. Exclude secrets, tokens, and internal identifiers. |
Returns:
{
"run_id": "r8run_abc...",
"status": "queued",
"poll_after_seconds": 15,
"message": "Reason8 is preparing the research brief…",
"input_request": null,
"research_plan": null,
"idempotency_replayed": false
}
status here is the initial workflow state — usually queued, sometimes needs_input if Reason8 immediately needs clarification, or brief_review on idempotent replay of an already-approved run.
curl:
curl -X POST https://api.reason8.io/mcp/tools/reason8_research_start \
-H "Authorization: Bearer $REASON8_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"artifact": "Launch announcement copy: <paste here>",
"research_goal": "Decide if framing lands with technical buyers",
"target_audience": "Mid-market CTOs evaluating AI tooling"
}'
TypeScript (via MCP SDK):
const result = await client.callTool({
name: "reason8_research_start",
arguments: {
artifact: "...",
research_goal: "...",
target_audience: "...",
},
});
Tracking progress
Call reason8_research_status to follow the run. It holds the connection open for up to 50 seconds and returns the moment the workflow state changes (backed by Postgres LISTEN/NOTIFY). On timeout it returns status: "running" with poll_again_in: 50 — call again immediately. There is no separate SSE channel; the long-poll is the canonical mechanism.
reason8_research_status
Get the current state of a run. Long-polls up to 50 seconds and returns as soon as the workflow status changes. Returns a slim payload tailored to the current state — the full memo is fetched separately with reason8_research_get_result.
Parameters: run_id (string, required).
Status enum: queued | launching | running | needs_input | brief_review | cancel_requested | completed | failed | cancelled | rate_limited.
rate_limited is a transient status here: it means this reason8_research_status call hit the per-credential status-polling DoS cap, not that the run failed. Back off for retry_after_seconds and poll again — the run is unaffected. This is a different surface from the 429 rate_limited start-quota error documented under Rate limits & concurrency, which rejects a reason8_research_start call; the two share a name but mean different things.
Response shapes per state:
// running, launching, queued, cancel_requested
{ "status": "running", "stage": "synthetic_interviews", "poll_again_in": 50, "next_action": "call reason8_research_status again" }
// needs_input or brief_review
{
"status": "needs_input",
"stage": "clarify",
"next_action": "call reason8_research_continue",
"input_request_id": "ir_abc...",
"input_request": { "questions": [/* ... */] }
}
// completed
{ "status": "completed", "stage": "finalised", "next_action": "call reason8_research_get_result" }
// failed
{ "status": "failed", "stage": "specialist", "next_action": "inspect error", "error_code": "...", "error_message": "..." }
// cancelled
{ "status": "cancelled", "stage": "cancelled", "next_action": "run terminated" }
// rate_limited (per-credential status DoS cap hit)
{ "status": "rate_limited", "retry_after_seconds": 5, "active_calls": 3, "next_action": "retry after delay" }
There is no result field on this tool — when status === "completed", call reason8_research_get_result.
reason8_research_get_result
Fetch the full research memo for a completed run. Call only after reason8_research_status reports status: "completed". Idempotent — call as many times as you like.
Parameters: run_id (string, required).
Returns:
{
"status": "completed",
"run_id": "r8run_abc",
"mode": "research",
"summary": "Short executive summary…",
"response_markdown": "# Full memo in markdown…",
"next_steps": ["Recommended follow-ups"],
"agent_action_summary": "What Reason8 did and why",
"synthetic_caveat": "Notes on synthetic-evidence limits",
"metadata": { "methods": [/* ... */], "artifact_uri": "gs://..." },
"response_truncated": false,
"response_full_bytes": 12345,
"created_at": "2026-05-28T16:00:00Z",
"completed_at": "2026-05-28T16:14:22Z"
}
Errors:
result_not_ready— run is still pre-terminal. Callreason8_research_status.not_found— run does not exist or belongs to another credential.result_unavailable— run completed but the response artifact is missing. Open a support ticket with therun_id.result_temporarily_unavailable— transient. Retry after a short delay.
reason8_research_continue
Send a follow-up to a run that is needs_input (clarification) or brief_review (approve / edit the research brief before paid methods run).
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
run_id | string | yes | The run_id from start or status. |
input_request_id | string | yes | Must match the pending input_request_id returned by status. |
answers | object | yes | Payload — shape depends on the pending state (see below). |
client_idempotency_key | string | no | Stable key that makes this continue call safe to retry. |
answers shape:
- needs_input — map each question id from
input_request.questionsto your answer:{ "audience_segment": "early-stage founders", "deadline": "before our 2026-06-15 launch" } - brief_review — approve or edit the brief Reason8 synthesized:
// approve as-is { "approved": true } // edit before approving { "approved": false, "brief": { "research_brief": "...", "target_audience": "...", "output_format": "..." } }
Answer truthfully from repository / agent context. If you do not know, say so explicitly ("not supplied" / "cannot infer") — do not fabricate.
reason8_research_cancel
Hard-stop a run.
Parameters: run_id.
Human-in-the-loop briefs
Reason8 may pause a run for two reasons: it needs more info from you (needs_input), or it wants you to approve the research brief before kicking off paid methods (brief_review).
start ──▶ needs_input ◄──▶ continue(answers)
│
▼
brief_review
│
continue(answers={approved: true})
▼
running ──▶ completed ──▶ get_result
When you see needs_input: call reason8_research_status to read input_request.questions and the input_request_id, then reason8_research_continue with answers mapping each question id to your answer.
When you see brief_review: call reason8_research_status to read the brief, then reason8_research_continue with answers: {approved: true} to accept — or answers: {approved: false, brief: {...}} to revise it.
This is the only place a run will wait on you. Once approved, Reason8 runs to completion (or failure) without further prompts.
Rate limits & concurrency
All limits enforce on reason8_research_start. Status/continue/cancel are not rate-limited.
| Limit | Value | Env override |
|---|---|---|
| Starts per hour per credential | 5 | DEFAULT_CREDENTIAL_HOURLY_START_LIMIT |
| Starts per day per user | 20 | DEFAULT_USER_DAILY_START_LIMIT |
| Starts per day per tenant | 100 | DEFAULT_TENANT_DAILY_START_LIMIT |
| Concurrent active runs per user | 5 | DEFAULT_USER_MAX_ACTIVE_RUNS |
Two distinct error families:
- Start quotas (hourly per credential, daily per user, daily per tenant) →
429 rate_limitedwith aRetry-Afterheader andretry_after_secondsin the body. Wait before retrying. - Active-runs cap (5 concurrent per user) →
409 concurrent_run_limit_exceeded. The error body includesactive_run_summaries(each withrun_id,status,stage,started_at,elapsed_seconds) andnext_actions. Cancel a stale run withreason8_research_cancelinstead of retrying.
Troubleshooting
401 invalid token — Token is wrong or revoked. Generate a fresh one in the portal.
403 scope missing — Token doesn't have the required scope. All tokens today have all three scopes; if you see this, the token may be from a future scoped-token feature. Regenerate.
409 concurrent_run_limit_exceeded — You hit the active-runs cap. Inspect active_run_summaries in the error body and call reason8_research_cancel on a run you no longer need before retrying start.
409 idempotency_conflict — You reused a client_idempotency_key with different inputs. Either use a fresh key or call reason8_research_status on the original run.
Run stuck in running — Runs hard-fail at the 60-minute max runtime; the watchdog inspects candidates after a 45-second silence grace. If yours has been silent for hours and is still running, file a bug with the run_id.
No structured progress in your client — Some MCP clients do not render the slim status payload. Call reason8_research_status directly and print the stage and next_action fields yourself; the human-readable progress message lives on start's message field.
FAQ
How is this different from the REST API? MCP exposes the same workflows as a set of agent tools with structured schemas — no client code to write. The REST API is for non-agent integrations (dashboards, scripts).
Can I use this without a paid account? Today, no — token issuance requires a workspace with billing configured. Contact support for evaluation access.
Are results cached? No. Each start triggers a fresh research run. Results are stored in your workspace's research history.
Can I tune the research specialist? Not via MCP today. Workspace-level prompt customization is on the roadmap.
Where do I report bugs? Email support@reason8.io with the run_id and a description.