Skip to content

Use case

Agents that ask people

An agent reaches a question only a person can answer. It calls escalate_and_wait like any other tool, a person answers in the dashboard, and the agent continues with the answer.

Surfaces: MCP · Dashboard

The moment

An agent is three steps into a job: download this week’s invoices from a supplier portal, match them against purchase orders, flag the mismatches. On step three the portal asks for a login. The stored connection was rotated last night.

The agent has options, and most of them are bad. It can give up and lose its progress. It can retry until it burns its budget. It can write “please provide credentials” into a log nobody reads.

What it needs is a person, for about thirty seconds, with a form that asks for exactly one thing. Then it needs to carry on from step three.

Two directions, one row

People and agents meet at the escalation row, from both sides:

Direction Who starts Who answers Where
An agent asks a person An agent running inside Long Tail A member of the target role Dashboard
A person sends their agent Claude Code, Claude Desktop, Cursor, any MCP client The agent, acting with that person’s roles The /mcp endpoint

Both directions use the same row, the same role checks and the same audit trail.

An agent that asks a person

Long Tail exposes its escalation queue as an MCP server, long-tail-human-queue. To an agent, a person is a tool. When an agent loop inside Long Tail needs input before it can continue, it calls escalate_and_wait with a form describing what it needs:

tool call: escalate_and_wait
{
"role": "engineer",
"message": "The supplier portal rejected the stored login. I need a current username and password to download this week's invoices.",
"form_schema": {
"type": "object",
"required": ["username", "password"],
"properties": {
"username": { "type": "string" },
"password": { "type": "string", "format": "password" }
}
},
"data": { "portal": "https://suppliers.acme.dev", "step": "download invoice batch 3 of 4" }
}

The call creates an escalation in the engineer queue and returns a signal id. The workflow parks on that signal. It does not poll, and it spends nothing while it waits. The next step in the run is the one that receives the person’s answer.

On the dashboard, an engineer sees the agent’s message, its context and a two-field form. They type the login and submit. Fields marked format: "password" are replaced with ephemeral credential tokens (eph:v1:...) before the payload reaches the agent. The agent passes the token into its next tool call exactly as received, and the raw secret never enters the agent’s context or its history.

The run continues from step three with the invoices it had already downloaded.

Tool What it does
escalate_and_wait Create an escalation and pause the workflow until a person responds
escalate_to_human Create an escalation and continue. Use it for notices that need no answer
check_resolution Read an escalation’s status and its resolver payload
get_available_work List the pending, unclaimed escalations for a role
claim_and_resolve Claim an escalation and resolve it in one call

Route the question to one person

Sometimes the right person is a specific person. Set assigned_to on escalate_and_wait and the item is pre-claimed for that user. Give them a membership in the role with read_self and write_self, and they see exactly that one item and nothing else in the queue. A contractor can approve one purchase order without seeing the rest of finance’s work.

Flag it back to an agent

The handoff also runs the other way. A reviewer looks at a failed extraction and sees the cause at once: page one was scanned upside down. They know what is wrong, but they cannot produce the data by hand. They resolve with a triage flag instead of an answer:

{
"resolverPayload": {
"_lt": { "needsTriage": true, "hint": "image_orientation" },
"notes": "Page 1 is upside down"
}
}

With the MCP escalation strategy turned on (escalation: { strategy: 'mcp' } in start()), that resolution routes to the triage workflow. It reads what happened upstream, calls the tools the hint points to, and re-runs the original step with corrected input. The parent workflow resumes as if the step had succeeded the first time. The triage workflows register when an ANTHROPIC_API_KEY or OPENAI_API_KEY is set.

Your agent, acting as you

It is 7 a.m. and a shift lead opens Claude Code before the stand-up. Connecting takes one command:

Terminal window
claude mcp add --transport http long-tail https://lt.acme.dev/mcp

They run /mcp, pick Authenticate, and sign in once in the browser. The consent page offers two choices:

Choice The client may
Allow read-only Read what you can read, and run workflows marked read-safe
Allow as me Do anything you can do: claim, resolve, invoke and administer wherever your roles allow

Then the work is a conversation:

  • “How many escalations are pending, by role?”
  • “Find the escalation where orderId is A-1042 and show me its status.”
  • “Claim it and resolve it as approved, with a note that the supplier confirmed by phone.”

Behind those sentences are ordinary tool calls: get_escalation_stats, find_by_metadata, claim_escalation, admin_resolve_escalation. Each one runs as the shift lead. Every result is limited to their roles, and every action is recorded under their name. An account that holds only the reviewer role can resolve reviewer escalations and nothing else, however the prompt is phrased.

Access tokens last five minutes and refresh silently. Every request reads the grant again, so a role removed this morning is gone from the agent’s next call. Disconnect a client under Connected apps in the user menu.

Agents that run unattended

A nightly agent has no browser to sign in with. Give it a service account instead: create one under Accounts → Service Accounts, assign the roles it acts under, and generate a key scoped mcp:read or mcp:full. Point the client at it with the key kept in the environment:

.mcp.json
{
"mcpServers": {
"longtail-prod": {
"type": "http",
"url": "https://lt.acme.dev/mcp",
"headers": { "Authorization": "Bearer ${LONGTAIL_PROD_KEY}" }
}
}
}

Give production a read key by default, and use a full key only when the agent is meant to change something there.

What the workflow does with the answer

Whoever answers, the answer lands in one place. When a person resolves the agent’s question, the waiting run resumes with the payload. When an agent resolves a person’s escalation, the workflow that raised it resumes with the agent’s payload. On a role that enforces its form, that payload passes the same validation a person’s submission does, and claim_and_resolve validates before it claims, so a rejected payload never leaves a claim stranded.

The row records who asked, who answered, what was decided and when. The next time the same question comes up, that record is the worked example.