VisualQ

MCP Response Contract

Structured JSON shape returned by POST /api/mcp/v1/invoke and consumed by @visualq/mcp.

Every tool invoked via POST /api/mcp/v1/invoke (or hosted POST /api/mcp) returns the same top-level JSON shape. The MCP client forwards this to the IDE agent as structured content.

Success response

{
  "ok": true,
  "tool": "get_run_failures",
  "summary": "3 of 12 checks failed.",
  "data": {
    "runId": "run_abc",
    "failed": 3,
    "total": 12,
    "failures": [
      {
        "scenarioLabel": "Homepage",
        "viewport": "desktop",
        "mismatchPercent": 4.2
      }
    ]
  },
  "warnings": [],
  "nextActions": [
    {
      "label": "Inspect Homepage desktop",
      "tool": "get_diff_stats",
      "args": {
        "scenarioLabel": "Homepage",
        "viewport": "desktop"
      }
    }
  ]
}

Fields

FieldTypeDescription
okbooleantrue when the tool executed successfully
toolstringTool name echoed from the request
summarystringOne-line human-readable result for the agent
dataobject | array | nullTool-specific payload
warningsstring[]Non-fatal issues (empty when none)
nextActionsarraySuggested follow-up tool calls for the agent

nextActions entries

FieldTypeDescription
labelstringShort description shown to the agent
toolstringTool name to call next
argsobjectOptional pre-filled arguments

get_run_failures automatically populates up to five nextActions pointing at get_diff_stats for each failed scenario.

Error response

{
  "ok": false,
  "tool": "approve_vrt_results",
  "summary": "confirm must be true to execute write tool approve_vrt_results",
  "data": null,
  "warnings": [],
  "nextActions": [],
  "error": {
    "code": "confirm_required",
    "message": "confirm must be true to execute write tool approve_vrt_results"
  },
  "recoverable": true
}

Error fields

FieldTypeDescription
error.codestringMachine-readable error category
error.messagestringHuman-readable explanation
recoverablebooleanWhether retrying with different args may succeed

Common error codes

CodeTypical cause
validation_errorMissing or invalid arguments
confirm_requiredWrite tool without confirm: true
scope_deniedAPI key scope insufficient
plan_gateFeature not on current billing plan
rate_limitToo many invoke calls (see retryAfterMs on 429 responses)
project_resolution_errorProject or environment not found
tool_errorExecutor or downstream failure
pipeline_blockedFRT scenario pipeline could not complete (missing startPath, empty goal, etc.)
save_failedFRT feature save or compile failed after pipeline
http_errorMCP client received non-JSON HTTP body (timeout, gateway error) — see error.message for status snippet
not_foundUnknown tool name

create_frt_scenario success variants

data.resolvedMeaning
existingfrt_find_scenarios resolve-first matched an existing feature — no duplicate created
createdNew feature persisted

When the user goal mentions tracking payload verification, the service strips that clause, creates the click scenario, and adds nextActions for tracking_get_plan and run_tracking.

For JIRA tracking proof (e.g. BN-470), use tracking_prove_jira_ticket — one async call that resolves ticket intent semantically. Poll get_job_status until status: completed, then read result.jiraMarkdown and result.proofVerdict. Do not manually chain frt_find_scenarios for proof workflows.

tracking_prove_jira_ticket proof fields

FieldMeaning
proofVerdictproven = eventStatus: pass and scenario.matchesTicketIntent: true; failed otherwise
proofOutcome{ proven, headline, reasons } — agent must quote headline (OUI/NON) to the user
jiraMarkdownPaste verbatim into the JIRA comment — do not paraphrase
warningse.g. intent-only proof (generic scenario), reused audit cache
nextActionsOn failure: create FRT scenario, re-prove, inspect proof — agent must propose these
matchesTicketIntentSemantic intent match (preferred over literal repro strings)

When proofVerdict is failed, the invoke response returns ok: false with error.code: proof_failed but still includes full data for the failure comment.

Async flow: first response { jobId, status: "queued" } → poll get_job_statusresult contains the proof object.

HTTP status mapping

StatusWhen
200ok: true
400Validation or confirm gate
403Scope or plan gate
404Unknown tool
422ok: false business/tool error
429Rate limit (retryAfterMs included in body)

CI tools

Tools routed through /api/ci/* (run_vrt, run_perf, get_run_status, etc.) return CI API shapes, not this contract. Only invoke tools use ToolResponse.

Async invoke tools return { jobId, status: "queued" } in data — poll with get_job_status.

On this page