reason8_ask
Overview
reason8_ask runs a fast, synchronous persona-panel reaction over a single artifact and returns the verdict in one round. Hand it a decision, a piece of copy, a PR summary, or a UI screenshot with a goal, and it answers in ~18–30s — no run_id, no polling.
Use it when you want an immediate read before you ship. For multi-method, human-in-the-loop deep research, use the async reason8_research_* track instead.
Contract. This page documents
reason8_askas the contract the MCP implementation matches. The response shapes are frozen bybackend/src/backend/personas/contract.py(PanelResponse). Field names below are sourced field-for-field from that module.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
artifact | object | yes | The thing under review: content (the text, copy, plan, or PR summary) plus a goal (the decision this reaction must inform). |
artifact.content | string | yes | The actual content to react to. Paste it — not a pointer to it. |
artifact.goal | string | yes | The decision this reaction informs (e.g. "decide whether this onboarding copy lands with first-time admins"). |
artifact.artifact_type | "text" | "ui_image" | no | Defaults to "text". Set "ui_image" to react to a design. |
artifact.image_b64 | string | no | Base64-encoded image, required when artifact_type is "ui_image". |
audience | string | yes | Free-text description of who the artifact is for (e.g. "mid-market ops leads evaluating procurement"). Auto-routes to a grounded persona set if one matches; otherwise the panel runs ungrounded. |
grounding | "auto" | "ungrounded" | "grounded" | no | The grounding axis. Default "auto" — uses a matching grounded set when one exists, else ungrounded. "grounded" requires a matching set; "ungrounded" skips real evidence entirely. |
The account is resolved from your API key — there is no account parameter. A request made without a key (or without a grounded set for the audience) reacts ungrounded only. There is no depth knob: reason8_ask is the fast, one-round path. Multi-round "thorough" research is the reason8_research_* workflow.
Behavior
reason8_ask is synchronous and returns a PanelResponse in a single round (~18–30s). Because the call can run longer than a default MCP client tool-timeout, the tool emits streaming progress while it works so compatible clients do not time out — treat any progress events as informational and wait for the final PanelResponse.
Two honesty distinctions run through every response, conveyed as labels (and an optional Material-Symbols icon), never by color alone:
- Verified vs Inferred — the
verifiedobject carries only math and counts; theinferredobject carries only prose and labels. They are kept structurally separate so a counted fact is never confused with a judgment. - supported vs speculative — a reaction's
verified.is_speculativeflag marks a persona that was grounded-but-thin, so the firewall surfaces it rather than presenting a thin read as solid.
Returns
reason8_ask returns a PanelResponse: a list of per-persona reactions plus a synthesis. Values below are illustrative; the shape is the contract.
{
"reactions": [
{
"persona_id": "p_2",
"persona_card": "Mid-market ops lead, evaluated three tools this quarter",
"verified": {
"evidence_count": 4,
"coverage_score": 0.62,
"grounding_refs": ["review#34", "ticket#12"],
"is_speculative": false
},
"inferred": {
"why": "Reads the pricing as per-seat and stalls on procurement approval.",
"leaning": "edit",
"trust_signal": "skeptical until ROI is explicit",
"act_signal": "would forward to finance, not sign today",
"what_id_do_next": "look for a usage-based tier"
}
}
],
"synthesis": {
"effective_n": 4.0,
"reaction_summary": "3 of 5 stall at pricing clarity",
"leaning": "edit",
"why": "The value lands but the pricing model blocks self-serve.",
"gaps": ["no signal from enterprise buyers"],
"grounding": "grounded",
"grounding_fell_back": false,
"grounding_used": { "set_id": "set_abc", "name": "Ops buyers", "match_confidence": 0.81 },
"alternatives": [{ "set_id": "set_def", "name": "Founders", "match_confidence": 0.55 }],
"evidence_version": 7
}
}
reactions[] — one entry per persona. Each entry holds:
verified(math / counts only):evidence_count(int),coverage_score(float | null),grounding_refs(string list of the evidence this reaction leaned on),is_speculative(bool —truemeans grounded-but-thin, flagged by the firewall).inferred(prose / labels only):why,leaning("ship" | "edit" | "rewrite"),trust_signal,act_signal,what_id_do_next.
synthesis — the panel-level read:
- Verified side:
effective_n(float) andreaction_summary. - Inferred side:
leaning("ship" | "edit" | "rewrite"),why,gaps(string list of what the evidence did not cover). - Routing / grounding metadata:
grounding(which axis ran),grounding_fell_back(bool —trueif a grounded request degraded to ungrounded),grounding_used(the set that was matched, or null),alternatives(other sets that could match),evidence_version(int | null — the grounding snapshot the read used).
The leaning enum is the machine-actionable verdict: ship, edit, or rewrite.
curl
curl -X POST https://api.reason8.io/mcp/tools/reason8_ask \
-H "Authorization: Bearer $REASON8_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"artifact": {
"content": "Onboarding copy: <paste here>",
"goal": "Decide whether this lands with first-time admins",
"artifact_type": "text"
},
"audience": "Mid-market ops leads evaluating procurement",
"grounding": "auto"
}'
TypeScript (via MCP SDK)
const result = await client.callTool({
name: "reason8_ask",
arguments: {
artifact: {
content: "...",
goal: "Decide whether this lands with first-time admins",
artifact_type: "text",
},
audience: "Mid-market ops leads evaluating procurement",
grounding: "auto",
},
});
For how grounding routing, the provenance ladder, and persona status work, see Grounding.