MCP tools: remote-agent-ops-handoff
remote-agent-ops-handoff
Registered when: platform: mcp.agentOps + browserHandoff.enabled covering the key's org (off by default, dark: off, all or a list of org ids; an operator switch); needs a key with a persona. The link goes to a person by DM, never to the agent. docs/design/browser-handoff.md.
handoff_cancel
Cancel a handoff you asked for (you no longer need the person): it ends as cancelled and their link stops working. Cancelling only ever makes things safer, so an agent may.
| Parameter | Type | Required | Description |
|---|---|---|---|
handoff_id | string | yes | The handoff (uuid). |
reason | string | no | Why, for the audit trail. |
Example call:
{"name":"handoff_cancel","arguments":{"handoff_id":"<handoff_id>"}}
Related: handoff_request, handoff_status.
handoff_request
Ask a person to do ONE step on the screen you are driving (sign in, a 2FA code, a captcha, a payment, a confirmation) when you must not or cannot do it yourself. GoodQA sends them a single-use link in a DM from your persona; they open a live view on GoodQA, act, and press Done or Skip. Poll handoff_status until result is set. Doing nothing returns skipped at the deadline. Never put a password or code in instructions (refused). Safe to retry with the same client_request_id. Needs a key with a persona. The answer is the handoff record; result is null while a person may still act and, once it ends, {outcome: signed_in | done | skipped | cancelled, by, reason}. The link itself is never shown to you: GoodQA DMs it to the person. Example: {"desktop_id":"machine:<uuid>","worker_id":"persona:ada-bot:turn-7","reason":"signin","url":"https://app.example.com/login","instructions":"Sign in with the shared QA account","person_id":"<user uuid>","client_request_id":"<uuid>"}.
| Parameter | Type | Required | Description |
|---|---|---|---|
desktop_id | string | yes | The screen: qacd: for the org desktop, or machine:. |
worker_id | string | yes | Who is driving it: commander:: or persona::. |
reason | "signin" \ | "2fa" \ | "captcha" \ |
url | string | yes | The https page that needs them (only its origin is shown to them). |
instructions | string | no | Plain text for the person, at most 500 characters. Never a secret. |
timeout | integer | no | Seconds before it ends as skipped (default 900). |
person_id | string | yes | The person to ask (uuid); must be a member of the org. |
thread_issue_id | string | no | A ticket to note it on (uuid); it gets a one-line comment, never the link. |
client_request_id | string | yes | Generate once per handoff; a retry with the same id returns the same record. |
Example call:
{"name":"handoff_request","arguments":{"desktop_id":"<desktop_id>","worker_id":"<worker_id>","reason":"signin","url":"<url>","person_id":"<person_id>","client_request_id":"<client_request_id>"}}
Related: handoff_status, handoff_cancel.
handoff_status
Read a handoff you asked for: its state (requested, link_issued, human_active, returned, timed_out, cancelled), who holds the screen, and result once it ended. The answer is the handoff record; result is null while a person may still act and, once it ends, {outcome: signed_in | done | skipped | cancelled, by, reason}. The link itself is never shown to you: GoodQA DMs it to the person.
| Parameter | Type | Required | Description |
|---|---|---|---|
handoff_id | string | yes | The handoff (uuid). |
Example call:
{"name":"handoff_status","arguments":{"handoff_id":"<handoff_id>"}}
Related: handoff_request, handoff_cancel.