need_human
Delegate tasks requiring human verification, identity authentication, or legal personhood when AI agents encounter access barriers like CAPTCHA, terms acceptance, or login walls.
Instructions
Call when you cannot proceed because the next step requires a real human.
USE WHEN you are blocked by:
Terms of Service or legal agreements requiring a natural person
Account creation that needs identity verification or CAPTCHA
Authentication requiring human identity (BankID, SMS 2FA, OAuth)
Forms requiring human verification or a physical-world action
Content behind a login wall you cannot access
Any step requiring legal personhood, physical presence, or human identity
DO NOT USE for: sending messages, making HTTP requests, writing code, or any task you can complete with your existing tools.
The human is a paid worker (billed per task), not your operator. Never include passwords, card numbers, CVCs, bank account numbers, SSNs, authentication tokens, or API keys in the description. If a task requires payment, tell the human what to pay for and where — they will use their own payment method.
Format your description as numbered steps, one instruction per line. Put each URL on its own line. End with "REPLY WITH:" listing expected deliverables.
Example: STEPS:
Create account at https://example.com/signup
Accept the terms of service. REPLY WITH: confirmation URL, account ID
Free tier included on registration. Each task costs 1 credit. Returns 402 when credits are exhausted. Fastest during European business hours (CET). Tasks submitted outside these hours may take longer. Typical completion: 2-30 minutes. Use check_task_status to poll.
Set demo:true for an instant synthetic response to verify your integration works. No credits consumed.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| description | Yes | What you need the human to do. Include URLs, account details, and expected outcome. | |
| action_type | No | Category: 'create_account', 'accept_terms', 'complete_web_action', 'bankid_auth', 'verify_identity', 'form_submission' | |
| urgency | No | immediate = target completion within 5 minutes. normal = within 60 minutes. | |
| demo | No | Set to true to get an instant synthetic response. No credits consumed, no real human involved. Use to verify integration works before submitting real tasks. |
Implementation Reference
- mcp-server.ts:26-162 (handler)The 'need_human' tool handler is defined in mcp-server.ts, which takes task parameters and dispatches a POST request to the NeedHuman API.
server.tool( "need_human", `Call when you cannot proceed because the next step requires a real human. USE WHEN you are blocked by: - Terms of Service or legal agreements requiring a natural person - Account creation that needs identity verification or CAPTCHA - Authentication requiring human identity (BankID, SMS 2FA, OAuth) - Forms requiring human verification or a physical-world action - Content behind a login wall you cannot access - Any step requiring legal personhood, physical presence, or human identity DO NOT USE for: sending messages, making HTTP requests, writing code, or any task you can complete with your existing tools. The human is a paid worker (billed per task), not your operator. Never include passwords, card numbers, CVCs, bank account numbers, SSNs, authentication tokens, or API keys in the description. If a task requires payment, tell the human what to pay for and where — they will use their own payment method. Format your description as numbered steps, one instruction per line. Put each URL on its own line. End with "REPLY WITH:" listing expected deliverables. Example: STEPS: 1. Create account at https://example.com/signup 2. Accept the terms of service. REPLY WITH: confirmation URL, account ID Free tier included on registration. Each task costs 1 credit. Returns 402 when credits are exhausted. Fastest during European business hours (CET). Tasks submitted outside these hours may take longer. Typical completion: 2-30 minutes. Use check_task_status to poll. Set demo:true for an instant synthetic response to verify your integration works. No credits consumed.`, { description: z .string() .describe( "What you need the human to do. Include URLs, account details, and expected outcome." ), action_type: z .string() .optional() .describe( "Category: 'create_account', 'accept_terms', 'complete_web_action', 'bankid_auth', 'verify_identity', 'form_submission'" ), urgency: z .enum(["immediate", "normal"]) .optional() .describe( "immediate = target completion within 5 minutes. normal = within 60 minutes." ), demo: z .boolean() .optional() .describe( "Set to true to get an instant synthetic response. No credits consumed, no real human involved. Use to verify integration works before submitting real tasks." ), }, async ({ description, action_type, urgency, demo }) => { try { const res = await fetch(`${API_URL}/api/v1/tasks`, { method: "POST", headers: { ...apiHeaders(), ...(demo ? {} : { "Idempotency-Key": crypto.randomUUID() }), }, body: JSON.stringify({ description, action_type, urgency, ...(demo ? { demo: true } : {}) }), }); if (!res.ok) { const err = await res.text(); return { content: [ { type: "text" as const, text: `Failed to create task: ${res.status} ${err}`, }, ], isError: true, }; } const task = await res.json(); // Demo mode: return the completed result directly if (task.demo) { return { content: [ { type: "text" as const, text: JSON.stringify( { task_id: task.id, status: task.status, result: task.result, demo: true, message: "Demo response. No credits consumed. Submit without demo:true for a real human worker.", }, null, 2 ), }, ], }; } return { content: [ { type: "text" as const, text: JSON.stringify( { task_id: task.id, status: task.status, created_at: task.created_at, estimated_completion_minutes: task.estimated_completion_minutes, message: task.estimated_completion_minutes != null ? `Task dispatched to human worker. Estimated completion: ~${task.estimated_completion_minutes} minutes. Use check_task_status to poll.` : "Task dispatched to human worker. Use check_task_status to poll for the result.", formatting_tip: "For best results: numbered steps, one instruction per line. URLs on their own line (worker reads on phone). End with a REPLY WITH: section listing expected deliverables.", }, null, 2 ), }, ], }; } catch (e) { return { content: [ { type: "text" as const, text: `Could not reach API at ${API_URL}. ${e instanceof Error ? e.message : "Unknown error."}`, }, ], isError: true, }; } } );