TaskBullet
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
Your AI agent can place a real phone call.
A person dials the number. Your agent gets the answers back. The server is @taskbullet/mcp-server.
Pricing
$2.50 for the first minute, then $1 per additional minute. The charge comes from the calls wallet, not from prepaid VA hours. US and Canada numbers only. Recording is not available. A system failure that never dials is fully refunded.
get_balance shows balance_cents (spendable after open holds), holds_cents, and wallet_cents. The default max_minutes is 5. At the rate above, five minutes is $6.50. validate_call returns hold_cents for the body you are about to send, and it places no hold. Use hold_cents.
HTTP 402 payment_required means the wallet cannot cover the hold. Add funds at addFundsUrl. That read does not create a Stripe session. Calls are pay-as-you-go. There is no trial.
Related MCP server: humanrail-mcp-server
Example prompts
Copy one of these into the agent after the server is installed. Put the real US or Canada number in the prompt. Do not put a password, a one-time code, or the API key in it.
Book an appointment:
Call the dentist and book me the earliest appointment next Tuesday after 1pm. The office is Bright Smile Dental at (801) 555-0148. Ask which times they have, book one, and bring back the time and any confirmation number. Confirm the hold with me before you place the call. Do not record it.Call a vendor to check an order:
Call Northwind Supply at (415) 555-0199 and check order NW-10442. Ask whether it shipped, the carrier, and the tracking number. Confirm the hold with me before you place the call. US number, no recording.Confirm a reservation:
Call Harbor Grill at (206) 555-0177 and confirm the reservation for Alex Chen, party of 4, this Friday at 7:00pm. Ask them to say the name, time, and party size back. Confirm the hold with me before you place the call. Do not record it.Install
Create a key at taskbullet.com/dashboard/settings/api-keys. It is shown once. The buttons below install a placeholder tb_live_your_key_here. Replace that placeholder in the client config before the first call. Do not paste the real key into chat.
The config runs npx -y @taskbullet/mcp-server on your machine. Cloud agents that cannot run npx should use the hosted URL in Cursor and cloud agents.
Cursor
GitHub does not open cursor:// links. Copy this into a browser:
cursor://anysphere.cursor-deeplink/mcp/install?name=taskbullet&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkB0YXNrYnVsbGV0L21jcC1zZXJ2ZXIiXSwiZW52Ijp7IlRBU0tCVUxMRVRfQVBJX0tFWSI6InRiX2xpdmVfeW91cl9rZXlfaGVyZSJ9fQ==Decoded config:
{
"command": "npx",
"args": ["-y", "@taskbullet/mcp-server"],
"env": {
"TASKBULLET_API_KEY": "tb_live_your_key_here"
}
}VS Code
vscode:mcp/install? and vscode-insiders:mcp/install? carry the same URL-encoded JSON. The name is inside that JSON:
{"name":"taskbullet","command":"npx","args":["-y","@taskbullet/mcp-server"],"env":{"TASKBULLET_API_KEY":"tb_live_your_key_here"}}Claude Code
claude mcp add taskbullet --env TASKBULLET_API_KEY=tb_live_your_key_here -- npx -y @taskbullet/mcp-serverReplace tb_live_your_key_here before you run it. From a marketplace, after this repo is on the default branch:
/plugin marketplace add GriffMurder/taskbullet-mcp-serverThen install taskbullet@taskbullet. The plugin prompts for the key. It does not read a key out of the shell.
JSON
Claude Desktop and any other stdio client:
{
"mcpServers": {
"taskbullet": {
"command": "npx",
"args": ["-y", "@taskbullet/mcp-server"],
"env": {
"TASKBULLET_API_KEY": "tb_live_your_key_here"
}
}
}
}claude_desktop_config.json locations are in the MCP quickstart. Restart the app after you save the file.
Tools
Names, arguments, and limits below match the code in src/server.ts.
Tool | Calls | Notes |
|
| Read-only. Hours and the calls wallet. Call this before proposing spend. |
|
| Files a brief. |
|
| Read-only. Up to 50 tasks. Filter includes |
|
| Read-only. Stop on |
|
| Accepts a delivery and settles tracked hours. |
|
| Releases the hold and bills only tracked time. |
|
| Sends the delivery back. |
|
| One human call. US and Canada only. |
|
| Checks the body. Creates nothing and places no hold. Returns |
|
| Read-only. Includes |
|
| Fills missing fields while the call is |
|
| Asks ops to cancel. Stays |
|
| VA wrap-up summary, not a recording. |
delegate_task arguments: title (required, max 5000), description (max 8000), priority (low | normal | high | urgent, default normal), dueDate, sourceAgent, webhookUrl (https), maxHours (default 0.5, max 8), idempotencyKey (required). The same value is sent as the Idempotency-Key header and is not put in the JSON body. A repeat returns the original task.
A tb_live_ key files the brief. The customer starts VA hours on Work. awaiting_customer_start means the job has not started. Do not say the assistant has started. Poll get_task until completed, failed, or cancelled, or pass webhookUrl. When get_task shows awaitingCustomerConfirm, ask the human, then confirm_task, cancel_task, or reopen_task. Do not confirm, cancel, or reopen without the human. Customer cancel is cancelled and does not send the completion webhook. If nobody confirms, an agent-created task confirms itself after 3 days.
maxHours is a spend cap. Tracked time is what is billed (15-minute rounding). HTTP 402 means a live read is not above zero. Buy hours at the addHoursUrl (the packages page, not a new trial). HTTP 422 means the cap does not fit open caps: hours remain, lower maxHours to capRoom or wait. HTTP 503 means hours were unavailable. That is not a buy-hours error.
Never put passwords, OTP codes, recovery keys, cookies, or API keys in a brief or a call. The server drops those locally and the API rejects them.
Human phone calls use place_call, not delegate_task. Required fields are phone, business_name, purpose (info, scheduling, account_servicing, or vendor_ops), goal (max 4000), questions (1 to 20 items of {id, ask, type?}, id max 80, ask max 1000), on_behalf_of, deadline (ISO-8601), consent_attestation (true), and idempotencyKey. max_attempts defaults to 3 and maxes at 5. max_minutes defaults to 5 and maxes at 60. language is en, fil, tl, war, or ceb.
Only US and Canada numbers can be placed. record_call must be false or omitted. True is rejected locally and nothing is sent. The hold is the full call: the first minute is the tier minimum, then the per-minute rate. A tier 1 call at the default 5 minutes holds $6.50. validate_call is the same body without idempotencyKey, and its hold_cents is the figure to trust. valid stays true when the wallet is short. warnings then include insufficient_balance. place_call is pay-as-you-go from the calls wallet. Poll get_call, or pass an https callback_url. A call outside weekday 09:00–17:00 in the recipient's time zone needs allow_outside_business_hours: true after the customer confirms. The deadline then needs 60 minutes of clock time.
update_call takes call_id plus any of the same body fields. get_call, cancel_call, and get_transcript take call_id.
TaskBullet Hub
TaskBullet Hub is one MCP connection for agents, with human backup.
There are two servers:
Server | URL | Auth | What it can do |
Agent (this package, and the hosted remote) |
|
|
|
Public site guide |
| none | Read-only marketing info: services, pricing, hire vs job-seeker routing |
The public site server does not see customer accounts, emails, work history, or internal docs. Task delegation is only on the agent server.
Cursor and cloud agents
Cloud agents (Cursor cloud, Grok, hosted Claude) should use the hosted agent URL. They cannot run npx.
{
"mcpServers": {
"taskbullet": {
"url": "https://taskbullet.com/api/agent-mcp",
"headers": {
"x-api-key": "tb_live_your_key_here"
}
}
}
}OpenClaw
The lobster cannot create the account or mint a key. Tell the human, in order:
No account → https://taskbullet.com/get-started?source=openclaw (10 hours, no card)
Issue
tb_live_…at https://taskbullet.com/dashboard/settings/api-keys (shown once)Paste it into the Gateway env
TASKBULLET_API_KEYand point Agent MCP athttps://taskbullet.com/api/agent-mcpwith headerx-api-key. Restart. Never put the key in chat.
Install the skill with openclaw skills install @griffmurder/taskbullet. A single human phone call is place_call on the calls wallet. Other unfinished work is get_balance, confirm spend, then delegate_task. No key → the trial URL above. A keyed HTTP 402 on hours is the packages page, not a second trial. A keyed HTTP 402 on a call is add funds, not a trial.
A local Gateway can also launch this package over stdio (npx -y @taskbullet/mcp-server) with TASKBULLET_API_KEY in the environment.
Public site guide (no key)
Read-only. Safe to add beside the agent server.
{
"mcpServers": {
"taskbullet-site": {
"url": "https://taskbullet.com/api/mcp"
}
}
}Call understand_site, then match_intent. Job seekers are not hire conversions.
Local streamable HTTP
Stdio is the default. --http serves streamable HTTP on loopback:
export TASKBULLET_API_KEY="tb_live_your_key_here"
npx -y @taskbullet/mcp-server --httpEndpoint: http://127.0.0.1:3000/mcp. The key stays in this process. Clients on that machine do not send it.
The process binds to 127.0.0.1 only. It checks Host and Origin so a browser page cannot use DNS rebinding to spend the key. Listening on any other address requires TASKBULLET_HTTP_TOKEN. Send that token as Authorization: Bearer …. It is not the TaskBullet API key.
There is no server-initiated SSE stream. GET returns 405. Responses are JSON. Requests are limited to 60 per minute per client address, and upstream calls follow the Agent API ceiling of 60 per minute. Bodies over 32 KiB are rejected.
Plugins
Cursor: plugins/taskbullet bundles this MCP server, rules/delegate-call-or-task.mdc, and skills/place-call-or-delegate/SKILL.md. Those tell the agent when to use place_call and when to use delegate_task. The repo marketplace is .cursor-plugin/marketplace.json. Submission to the Cursor Marketplace is still manual at cursor.com/marketplace/publish.
Claude Code: .claude-plugin/marketplace.json lists the same plugin. Users add it with /plugin marketplace add GriffMurder/taskbullet-mcp-server. Claude Code loads the skill. It does not load the Cursor rule. Claude starts the vendored server with node and ${CLAUDE_PLUGIN_ROOT}/server/index.js. The prompt supplies the API key and the local HTTP token, and the vendored server reads only those values. Cursor keeps using npx.
Environment
Variable | Required | Default | Purpose |
| yes | — |
|
| no |
| Override for staging |
| no |
| Audit label stored on each brief |
| no | stdio | Set to |
| no |
| Bind address. Non-loopback requires a token |
| no |
| HTTP port |
| when exposed | — | Local HTTP auth for npm and Cursor. The Claude plugin reads the prompt value only. Not the TaskBullet API key |
| no | loopback origins | Extra browser |
Completion
Poll
get_taskuntilstatusiscompleted,failed, orcancelled. WhenawaitingCustomerConfirmis true, ask the human, thenconfirm_task,cancel_task, orreopen_task.Webhook — pass an https
webhookUrl. TaskBullet POSTs a signed body when the customer closes the job, andtask.awaiting_confirmationwhen a delivery is waiting. A customer cancel does not sendtask.completed. See the webhook docs.Calls — poll
get_calluntil the call finishes, or pass an httpscallback_url. Readget_transcriptwhen the call has a transcript.
delegate_task, confirm_task, cancel_task, reopen_task, and place_call require idempotencyKey. The package sends that value as the Idempotency-Key header and does not put it in the JSON body. The same account and key returns the original result.
How TaskBullet bills hours
Hours are prepaid buckets. They roll over for 90 days.
Delegated tasks route to the virtual assistant on the account.
The API call is free. Hours deduct when work is tracked, not when the brief is filed.
Phone calls do not spend those hours. They spend the calls wallet.
Docs: agent API · OpenAPI · site
Registry
mcpName in this release is io.github.GriffMurder/taskbullet. That is the live registry listing. Publishing 0.2.1 updates it. The preferred name com.taskbullet/mcp needs a DNS TXT record or an HTTP proof on taskbullet.com. That proof is not published yet, so this package does not switch names. Commands, the TXT record, and the directory submissions are in PUBLISHING.md.
License
MIT — see LICENSE.
Available Tools
13 toolscancel_callCancel callADestructiveIdempotentInspect
Cancel a call. Status stays cancel_pending until ops confirms. A confirm before any dial refunds the hold and the status becomes cancelled. If the dial already started, the error is cancel_too_late and the call bills normally. A dial after a confirmed cancel is a full refund and the VA is unpaid.
| Name | Required | Description | Default |
|---|---|---|---|
| call_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses the intermediate cancel_pending state pending ops confirmation, the refund behavior for a confirm before dialing, the specific cancel_too_late error when the dial already started, and the billing/VA-payment consequence of a dial after a confirmed cancel. None of this is derivable from destructiveHint/idempotentHint/openWorldHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five short sentences, front-loaded with the action, then packed with state, refund, error, and billing facts. No filler sentences and no repetition of the title or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, and the description covers lifecycle states, the failure mode, and financial consequences thoroughly. Minor gap: no mention of permissions/ownership or who may cancel, which for a destructive operation would be useful context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one required parameter (call_id) with 0% schema description coverage, and the description never mentions it. The parameter is largely self-evident from the name, but the description adds no meaning (format, whether it is a UUID, whether the call must be in a particular state).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Cancel a call') and immediately elaborates the state the call lands in, so the agent knows exactly what operation this is. It does not explicitly contrast itself with the call-vs-task siblings (cancel_task, confirm_task), but the resource is unambiguous from the name and first sentence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than routed: the description explains what happens depending on call state (pre-dial refund, dial-started failure), which helps the agent predict outcomes, but it never names an alternative tool or states prerequisite conditions for choosing this over cancel_task or update_call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_taskCancel taskADestructiveIdempotentInspect
Customer never mind. Releases the hold and bills only tracked time. Does not send the completion webhook. Ask the human first. Idempotency-Key is required.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional note. Do not include secrets. | |
| taskId | Yes | The taskId returned by delegate_task. | |
| idempotencyKey | Yes | Same value as the REST Idempotency-Key header. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| title | No | |
| amNote | No | AM or VA note. |
| result | No | Full VA result when completed. Never invent this. |
| status | No | Stop polling on completed, failed, or cancelled. |
| taskId | No | |
| priority | No | |
| createdAt | No | |
| completedAt | No | |
| autoConfirmNote | No | |
| deliverableLinks | No | https links from the note. |
| awaitingCustomerConfirm | No | True means ask the human, then confirm_task, cancel_task, or reopen_task. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, but the description goes well beyond them by spelling out the concrete effects: the hold is released, billing is limited to tracked time, and no completion webhook fires. That is exactly the 'what gets destroyed' context an agent needs before a destructive call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five short, front-loaded sentences with no filler; each effect (hold release, billing, webhook suppression) earns its place. The ambiguous 'Customer never mind' opener costs a point because it reads as noise rather than usable instruction.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With rich annotations, a full output schema, and 100% parameter coverage, the description only needs to add behavioral context, which it does for effects and preconditions. The unexplained 'Customer never mind' phrase is the one loose end that keeps it from fully closing the loop.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (reason, taskId, idempotencyKey) are already documented in the schema. The description only restates that Idempotency-Key is required, adding no syntax or format detail beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (cancel a task) and adds concrete business semantics: releases the hold, bills only tracked time, suppresses the completion webhook. The opening fragment 'Customer never mind' is an odd preamble but the remainder clearly distinguishes this from confirm_task/reopen_task, which move a task forward rather than ending it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit precondition ('Ask the human first'), which is real when-to-use guidance for a destructive operation. It does not name alternatives such as confirm_task or reopen_task, so an agent must still infer the surrounding workflow, keeping it short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
confirm_taskConfirm taskADestructiveIdempotentInspect
Accept a delivery that is awaitingCustomerConfirm. Settles tracked hours, releases the board and ledger hold, and marks the task completed. If the human does not respond, the job confirms itself after 3 days. Ask the human first. Idempotency-Key is required. A repeat of the same key returns the same result.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | The taskId returned by delegate_task. | |
| idempotencyKey | Yes | Same value as the REST Idempotency-Key header. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| title | No | |
| amNote | No | AM or VA note. |
| result | No | Full VA result when completed. Never invent this. |
| status | No | Stop polling on completed, failed, or cancelled. |
| taskId | No | |
| priority | No | |
| createdAt | No | |
| completedAt | No | |
| autoConfirmNote | No | |
| deliverableLinks | No | https links from the note. |
| awaitingCustomerConfirm | No | True means ask the human, then confirm_task, cancel_task, or reopen_task. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint and idempotentHint, but the description adds substantial context beyond them: the precise state transition, that tracked hours are settled and the board and ledger hold released, the 3-day auto-confirmation fallback, and the human-approval expectation. The idempotency note explains the mechanism ('a repeat of the same key returns the same result') rather than merely restating the hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with what the tool does and the state it applies to, then effects, then the human-approval caution and idempotency contract. No filler or redundant restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and annotations cover the safety profile. The description still supplies everything an agent needs to decide and act: precondition, side effects, human-approval expectation, timing fallback, and the required idempotency key contract.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented, and the baseline would be 3. The description adds genuine value on idempotencyKey by stating it is required and describing its repeat-call semantics, though taskId gets no description-level elaboration beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Accept a delivery') plus the exact precondition state ('awaitingCustomerConfirm'), and enumerates the resulting effects (settles hours, releases board and ledger hold, marks completed). This distinguishes it from siblings like cancel_task and reopen_task, which operate on different lifecycle states, without needing to name them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operating context: only applies to tasks in awaitingCustomerConfirm, and instructs 'Ask the human first.' It also explains the fallback ('the job confirms itself after 3 days'), which tells the agent this is not always strictly necessary. It stops short of explicitly contrasting with sibling alternatives such as cancel_task or reopen_task, so it's clear context rather than full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delegate_taskDelegate taskADestructiveIdempotentInspect
Call get_balance first, then confirm with the user before sending (real hours) unless they already said to send it. Delegate a task to a real human virtual assistant when the AI cannot complete it autonomously. Use this for phone calls, owner-authorized login or captcha steps (never send passwords or OTP), physical-world actions, subjective QA, manual data entry, or anything else outside the model's reach. Returns a taskId for tracking. The job is NOT started until the customer clicks Start on Work. The receipt status is awaiting_customer_start.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Concise directive (max 5000 chars). | |
| dueDate | No | Optional human-readable due date (e.g. EOD Friday). | |
| maxHours | No | Spend cap in hours (default 0.5). VA/AM stop and ask before exceeding. Actual tracked time is billed, not this cap. Max 8. | |
| priority | No | normal | |
| webhookUrl | No | Optional public HTTPS callback URL. | |
| description | No | Detailed context, instructions, and constraints (max 8000 chars). Never include passwords, OTP codes, recovery keys, cookies, or API keys. | |
| sourceAgent | No | Optional calling-agent label for the audit trail (e.g. grok-bot). | |
| idempotencyKey | Yes | Same value as the REST Idempotency-Key header. Required. A repeat returns the original task. |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | No | awaiting_customer_start means the customer has not clicked Start on Work. received is a replay after start, a hold, or a sent card. |
| taskId | No | Stable id for get_task. |
| message | No | Human-readable result. Do not claim the VA has started unless the status says so. |
| success | No | True when the brief was filed or replayed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations (readOnlyHint=false, destructiveHint=true, idempotentHint=true, openWorldHint=true) by disclosing the asynchronous lifecycle: the job is not started until the customer clicks Start, and the receipt status is awaiting_customer_start, plus a taskId is returned. It also adds a spend/confirmation policy and a secrets-handling prohibition that the annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but nearly waste-free, with each sentence carrying a distinct rule (prerequisite, purpose, use cases, safety, return, lifecycle). It loses a point for leading with the get_balance/confirmation precondition before stating what the tool actually does, which weakens front-loading of the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, destructive, open-world creation tool with an output schema, the description supplies everything needed to invoke it correctly: prerequisites, confirmation policy, scope of use, secret-handling limits, the returned taskId, and the fact that work does not begin until customer activation. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 88% and 8 parameters are present, so the schema already documents fields such as maxHours, idempotencyKey, and description in detail. The description only indirectly touches the spend-cap parameter via the get_balance/confirm-for-real-hours guidance and does not explain any parameter format beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (delegate) and resource (task to a real human VA) and adds the governing condition (when the AI cannot complete it autonomously). This cleanly separates it from siblings like list_tasks, get_task, cancel_task, and place_call, which are retrieval/control operations rather than task creation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use categories (phone calls, owner-authorized login/captcha, physical-world actions, subjective QA, manual data entry) and explicit exclusions (never send passwords or OTP). It also names the prerequisite sequence: call get_balance first, then confirm with the user before sending, unless already authorized.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balanceGet balanceARead-onlyIdempotentInspect
Return remaining VA hours, capRoom, and whether a new cap can be filed. Also returns the calls wallet: balance_cents is spendable after open holds, wallet_cents is that amount plus holds_cents, and holds_cents is the sum of unsettled holds. addFundsUrl is POST /api/v1/billing/add-funds and this read does not create a Stripe session. canDelegate is false when hours are unavailable, when spendable hours are not above zero, or when open caps leave no room. canDelegate false while hoursRemaining is above zero means lower maxHours to capRoom or wait. It is not a buy-hours signal. Call this before proposing spend. Does not create a task.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| capRoom | No | Hours free for a new cap after open caps. Omitted when hours are unavailable. |
| addFundsUrl | No | POST /api/v1/billing/add-funds. This read does not create a Stripe session. |
| addHoursUrl | No | Buy-hours URL. Use it only when a live read is not above zero. |
| canDelegate | No | False when hours are unavailable, spendable hours are not above zero, or capRoom is below the minimum new cap. |
| holds_cents | No | Sum of unsettled call holds. |
| wallet_cents | No | balance_cents plus holds_cents. |
| balance_cents | No | Spendable calls-wallet cents after open holds. |
| can_place_call | No | Whether the calls wallet can place a call. |
| hoursRemaining | No | Live remaining hours when Ops returned a figure. |
| hoursUnavailable | No | True when Ops did not return a live remaining figure. Not a buy-hours signal. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent and non-destructive, and the description adds genuinely new behavioral facts: addFundsUrl is POST /api/v1/billing/add-funds yet this read creates no Stripe session, and canDelegate semantics for the zero-hours / no-room cases. It does not cover auth requirements or rate limits, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource and its returns, then the canDelegate rules and the invocation cue. Efficient overall, though the field-by-field wallet breakdown and the addFundsUrl/Stripe detail are somewhat dense and partly overlap with the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema has no params, annotations carry the safety profile, and an output schema exists so return values needn't be re-specified. The description still supplies the non-obvious semantics an agent needs: how canDelegate false should be interpreted, and that this read has no billing side effect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero input parameters, so there is nothing parameter-side to compensate for; baseline is 4. The description instead spends its detail on return-field semantics (balance_cents vs wallet_cents vs holds_cents), which sits outside this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource, naming exactly what comes back: remaining VA hours, capRoom, whether a new cap can be filed, and the calls wallet breakdown. It also disambiguates itself from siblings by asserting 'Does not create a task' and 'not a buy-hours signal', so an agent can separate it from place_call/delegate_task without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear invocation context: 'Call this before proposing spend.' It also sets two boundaries — not a buy-hours signal, and it does not create a task. It stops short of naming an alternative tool for the buy-hours or cap-filing paths, so it is strong context rather than full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_callGet callBRead-onlyIdempotentInspect
Read one human phone call, including needs_info missing_fields or the final result.
| Name | Required | Description | Default |
|---|---|---|---|
| call_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true. The description adds useful context that the response may include needs_info missing_fields or the final result, but it does not discuss permissions, rate limits, or other operational behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no wasted wording. It immediately states the action and resource, then adds the most relevant result detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, annotations are rich, and an output schema exists, so the description does not need to explain return values. Still, it leaves gaps around call_id sourcing and does not distinguish this tool from get_transcript, which an agent may need to choose correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one required parameter, call_id, but the schema description coverage is 0% and the description does not explain where call_id comes from, its format, or any constraints. The description adds essentially no meaning beyond the schema's parameter name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Read one human phone call.' It also names the kind of content available, such as needs_info missing_fields or the final result. However, it does not distinguish this from sibling tools like get_transcript or update_call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for retrieving a single call by ID, but gives no explicit when-to-use guidance, prerequisites, or alternatives. It does not say when to choose this over get_transcript or other call-related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_taskGet delegated taskARead-onlyIdempotentInspect
Get the current status, title, completion timestamp, and full result notes for a specific delegated task. awaitingCustomerConfirm true means ask the human, then confirm_task, cancel_task, or reopen_task. amNote is the AM or VA note. deliverableLinks lists https links. Stop when status is completed, failed, or cancelled. Customer cancel is cancelled, not pending or in_progress, and it does not send the completion webhook.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | The taskId returned by delegate_task. |
Output Schema
| Name | Required | Description |
|---|---|---|
| title | No | |
| amNote | No | AM or VA note. |
| result | No | Full VA result when completed. Never invent this. |
| status | No | Stop polling on completed, failed, or cancelled. |
| taskId | No | |
| priority | No | |
| createdAt | No | |
| completedAt | No | |
| autoConfirmNote | No | |
| deliverableLinks | No | https links from the note. |
| awaitingCustomerConfirm | No | True means ask the human, then confirm_task, cancel_task, or reopen_task. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive, but the description adds non-obvious behavior: a customer cancel lands as 'cancelled' rather than pending/in_progress and does not fire the completion webhook. Those are side effects an agent could not infer from the annotations or schema. It stops short of covering rate limits or response shape beyond the listed fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the returned data and then layers the interpretation rules (awaitingCustomerConfirm, amNote, deliverableLinks, terminal statuses, cancel semantics) in short, terse sentences. A couple of the field glosses ('amNote is the AM or VA note') are near-redundant given the output schema, but overall every sentence carries usable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read tool with an output schema and full annotation coverage, this description supplies everything an agent needs: what is returned, how to read key fields, what to do on awaitingCustomerConfirm, when to stop, and the webhook quirk for customer cancels. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter, and the schema already documents it at 100% coverage ('The taskId returned by delegate_task'). The description adds no extra syntax, format, or sourcing guidance for taskId beyond what the schema says, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Get the current status, title, completion timestamp, and full result notes for a specific delegated task') and enumerates the returned fields, so it is immediately distinguishable from list_tasks or get_call. The scope is a single task identified by taskId, and that is stated plainly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing: when awaitingCustomerConfirm is true, ask the human and then call confirm_task, cancel_task, or reopen_task, naming the sibling tools by name. It also states the stopping condition (status completed, failed, or cancelled), so the agent knows when not to keep polling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transcriptGet transcriptARead-onlyIdempotentInspect
Read the VA wrap-up summary for one call. This is not a recording. Once the call is wrap_up or completed, the result is that summary plus any question answers, with source wrap_up_summary and recorded false. Before a wrap-up summary exists, the result is transcript_not_ready. A call that ended without a dial (system failure or refund) is "no transcript: call not placed". A cancel after the dial started is call_cancelled. A recorded transcript may be a separate paid feature later and is not returned.
| Name | Required | Description | Default |
|---|---|---|---|
| call_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/openWorld, and the description goes beyond them by enumerating the distinct outcome states (transcript_not_ready, 'no transcript: call not placed', call_cancelled) and the source/recorded fields. It also pre-empts a likely false expectation by stating a recorded transcript is not returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose and the negative ('not a recording') in the first two sentences, then uses short sentences for each state. Dense with information and mostly waste-free, though the trailing 'may be a separate paid feature later' is speculative roadmap detail rather than call guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully explains what the result contains and its error/edge states. The remaining gap is the call_id parameter's semantics, which nothing else in the structured data supplies.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single required call_id has no description, so the description must compensate. 'For one call' implies the parameter is a call identifier but adds no format, source, or where-to-find-it guidance, leaving the agent to guess acceptable values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (read) and resource (VA wrap-up summary for one call) and explicitly negates the confusable interpretation: 'This is not a recording.' That distinguishes it from a recording/audio retrieval, though it does not explicitly contrast with sibling get_call, which also takes a call_id.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear conditional context: usable once the call is wrap_up or completed, otherwise transcript_not_ready. It does not, however, route the agent between this and sibling get_call/update_call, leaving the tool-selection question partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tasksList delegated tasksARead-onlyIdempotentInspect
List recently delegated tasks for this account (id, title, status, short result). awaitingCustomerConfirm true means the delivery is done and the human must confirm, cancel, or reopen. amNote is the delivery note and deliverableLinks are https links from that note. pending and in_progress omit customer-cancelled jobs. cancelled is terminal.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| tasks | No | Up to 50 recent tasks. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, so the description correctly spends its words elsewhere: it explains the awaitingCustomerConfirm gate (delivery done, human must confirm/cancel/reopen) and the terminal nature of 'cancelled'. It does not mention any bound on 'recently' (result cap or pagination), which is the one behavioral trait still missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences with the operation and returned fields front-loaded, followed by the interpretive notes an agent needs to read the flags correctly. No filler, though the field-by-field gloss overlaps with the output schema and could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering the safety profile, the description only needs to add interpretation the structured data cannot: what awaitingCustomerConfirm means, how status buckets exclude cancelled jobs, and that 'cancelled' is terminal. For a one-parameter list tool this is sufficient, with pagination bounds the only minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across the single status parameter, so the description carries the burden and partially meets it by defining the semantics of 'pending', 'in_progress' (both omit customer-cancelled jobs) and 'cancelled' (terminal). 'completed', 'failed', and the 'all' default remain unaddressed, so the enum is not fully covered.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('List recently delegated tasks for this account') plus the shape of each returned row, which cleanly separates it from single-task siblings like get_task or confirm_task. An agent can identify both the operation and the scope without consulting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'recently delegated tasks for this account', but the description never states when to prefer this over get_task or the mutation siblings (confirm_task, cancel_task, reopen_task), nor does it mention any prerequisite. Adequate for a simple listing tool, but no explicit routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
place_callPlace callADestructiveIdempotentInspect
Place one human phone call. The hold is the full call: the tier minimum for the first minute, then the per-minute rate for each additional minute. Default max_minutes is 5, so a tier 1 US or Canada call holds $6.50. Raise max_minutes on that call to hold more. record_call must be false or omitted. Only US and CA are live. A question is {"id","ask","type"?}: id up to 80 characters, ask up to 1000 characters, at most 20 questions. goal is at most 4000 characters. Idempotency key is required. Poll get_call, or pass callback_url. validate_call checks the body and places no hold.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | Yes | ||
| phone | Yes | US or Canada number. 801-414-4664, (801) 414-4664, and +1 801 414 4664 are accepted and stored as E.164. | |
| script | No | ||
| purpose | Yes | ||
| deadline | Yes | ISO-8601. Needs 60 minutes of weekday 09:00–17:00 recipient-local, unless allow_outside_business_hours is true. | |
| language | No | en, fil, tl, war, or ceb. Default en. | |
| extension | No | Optional digits. Passed into the VA instructions. Not billed. | |
| questions | Yes | One to 20 questions. Each item is {id, ask, type?}. | |
| max_minutes | No | Default 5. Maximum 60. The hold covers this many minutes. | |
| record_call | No | False or omit. True is rejected: recording is not available. | |
| script_mode | No | ||
| time_window | No | Optional 24-hour HH:MM-HH:MM in the recipient time zone. Example: 09:00-17:00. End must be after start. | |
| callback_url | No | ||
| instructions | No | Outranks script wording. The extension is appended for the VA. | |
| max_attempts | No | Default 3. Maximum 5. | |
| on_behalf_of | Yes | ||
| business_name | Yes | ||
| idempotencyKey | Yes | Same value as the REST Idempotency-Key header. | |
| retry_preference | No | ||
| shareable_contact | No | ||
| recipient_timezone | No | IANA zone. Omit it and TaskBullet infers a US or Canada area code. An uninferable number needs this field. | |
| allowed_disclosures | No | ||
| consent_attestation | Yes | Must be true. | |
| allow_outside_business_hours | No | Set true only after the customer confirms the call may happen outside weekday 09:00–17:00 in the recipient time zone. The deadline then needs 60 minutes of clock time. Omit or false keeps the weekday business-hour rule. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the billing/hold model (first-minute tier minimum, per-minute thereafter, $6.50 hold at the 5-minute default), the interaction between max_minutes and the hold, the hard rejection of record_call=true, and the live-market restriction. These are exactly the operational facts (cost exposure, irreversible spend, geographic limits) an agent needs before a destructive, open-world write.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then the cost model, then constraints and alternatives. Nearly every sentence carries a distinct fact, though the terse fragment style ("Only US and CA are live.") makes the block dense to parse at 24 params.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations carry the safety profile, so the description needn't cover returns. It covers the highest-risk constraints (spend, idempotency, recording rejection, market and business-hour rules), leaving only peripheral fields undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 24 params at 58% schema coverage, the description compensates by specifying the questions object shape, its 80/1000-char and 20-item limits, the 4000-char goal cap, required idempotency key, and the pricing/semantics of max_minutes. It leaves several lower-risk params (script, purpose, language, script_mode, shareable_contact, etc.) to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ("Place one human phone call") plus scope limits (US and CA only, one call, human VA). It also explicitly contrasts itself with sibling validate_call, so an agent can distinguish the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the polling path (get_call) and callback_url alternative, and clarifies that validate_call checks the body without placing a hold, which is clear routing guidance. It stops short of an explicit when-not/preconditions statement (e.g. that consent_attestation must be true before placing).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reopen_taskReopen taskAIdempotentInspect
Send a delivery that is awaitingCustomerConfirm back to the account manager with a reason. Does not settle hours. Ask the human first. Idempotency-Key is required.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | What should happen next. Required. Do not include secrets. | |
| taskId | Yes | The taskId returned by delegate_task. | |
| idempotencyKey | Yes | Same value as the REST Idempotency-Key header. Required. |
Output Schema
| Name | Required | Description |
|---|---|---|
| title | No | |
| amNote | No | AM or VA note. |
| result | No | Full VA result when completed. Never invent this. |
| status | No | Stop polling on completed, failed, or cancelled. |
| taskId | No | |
| priority | No | |
| createdAt | No | |
| completedAt | No | |
| autoConfirmNote | No | |
| deliverableLinks | No | https links from the note. |
| awaitingCustomerConfirm | No | True means ask the human, then confirm_task, cancel_task, or reopen_task. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a non-readonly, idempotent, non-destructive, open-world mutation. The description adds real behavioral context beyond them: 'Does not settle hours' rules out a side effect an agent might otherwise assume, the required Idempotency-Key is called out, and human confirmation is mandated before invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, each carrying a distinct fact: the state transition, the destination, the side-effect exclusion, the human gate, and the idempotency requirement. The precondition and action are front-loaded with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the safety profile is covered by annotations. For a 3-parameter mutation the description covers precondition, side effects, human approval, and idempotency; it stops short only of describing failure behavior when the task is not in awaitingCustomerConfirm.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (taskId, reason, idempotencyKey) are already documented in the schema, including the required markers and 'do not include secrets' on reason. The description only echoes the Idempotency-Key requirement, adding no new parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (send back / reopen), the resource (a delivery), and the precise precondition state (awaitingCustomerConfirm) plus the destination (account manager). An agent can distinguish this from confirm_task or cancel_task without opening either schema, because the state and direction of the transition are named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Ask the human first' gives an explicit gating condition, and the awaitingCustomerConfirm state narrows when the tool applies. It does not explicitly name the sibling alternatives (confirm_task, cancel_task) that an agent might otherwise pick, so it falls short of a full when-not/alternative statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_callUpdate callBIdempotentInspect
Fill missing_fields on a call in needs_info. Same result shapes as place_call.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | ||
| phone | No | ||
| script | No | ||
| call_id | Yes | ||
| purpose | No | ||
| deadline | No | ||
| language | No | ||
| extension | No | Optional digits. Passed into the VA instructions. | |
| questions | No | ||
| max_minutes | No | ||
| record_call | No | ||
| script_mode | No | ||
| time_window | No | ||
| callback_url | No | ||
| instructions | No | ||
| max_attempts | No | ||
| on_behalf_of | No | ||
| business_name | No | ||
| retry_preference | No | ||
| shareable_contact | No | ||
| recipient_timezone | No | ||
| allowed_disclosures | No | ||
| consent_attestation | No | ||
| allow_outside_business_hours | No | Set true only after the customer confirms the call may happen outside weekday 09:00–17:00 in the recipient time zone. The deadline then needs 60 minutes of clock time. Omit or false keeps the weekday business-hour rule. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, destructiveHint=false, and openWorldHint=true. The description usefully clarifies that this only fills MISSING fields (partial, non-overwriting) and that results mirror place_call, which is consistent with the idempotent, non-destructive profile. It adds little else about auth, side effects, or limits, so it earns a moderate score against an already-covered annotation baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly worded sentences with the core action front-loaded and zero filler. It is efficient, though the extreme brevity is arguably under-specification given the 24-parameter surface.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 24 properties at 8% coverage and a mutation tool, the description is far too thin on inputs; it does not explain which fields are actually fill-able or their formats. It does offload return-value explanation to the output schema and place_call, but the input side remains largely unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 8% across 24 parameters, so the description must carry the load and it does not: beyond 'missing_fields', it explains no parameter names, formats, or constraints. The result-shapes reference to place_call gives no input guidance, leaving the bulk of parameters undocumented in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('Fill missing_fields on a call') and adds a state precondition ('in needs_info'). It also ties output to the sibling place_call ('Same result shapes as place_call'), so the agent can tell it apart from place_call and cancel_call. It stops short of full sibling differentiation, so not a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The precondition 'on a call in needs_info' implies when to reach for this tool versus place_call (new call) or cancel_call, but it never explicitly states when to use it or when another tool is preferred. Guidance is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_callValidate callARead-onlyIdempotentInspect
Check a phone-call body without creating a call or placing a hold. Same fields as place_call, without idempotencyKey. A ready body includes hold_cents for the full call (tier 1 default $6.50 at 5 minutes) and whether recipient_timezone was inferred. valid stays true when spendable balance is below the hold. warnings then includes insufficient_balance with needed_cents and addFundsUrl.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | ||
| phone | No | ||
| script | No | ||
| purpose | No | ||
| deadline | No | ||
| language | No | ||
| extension | No | ||
| questions | No | ||
| max_minutes | No | ||
| record_call | No | False or omit. | |
| script_mode | No | ||
| time_window | No | HH:MM-HH:MM, 24-hour, end after start. | |
| callback_url | No | ||
| instructions | No | ||
| max_attempts | No | ||
| on_behalf_of | No | ||
| business_name | No | ||
| retry_preference | No | ||
| shareable_contact | No | ||
| recipient_timezone | No | ||
| allowed_disclosures | No | ||
| consent_attestation | No | ||
| allow_outside_business_hours | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false, openWorldHint), so the bar is lower. The description adds genuinely non-obvious behavior: the response carries hold_cents (with a concrete tier-1 default), whether recipient_timezone was inferred, and the counter-intuitive rule that valid stays true when spendable balance is below the hold, with an insufficient_balance warning instead.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences, front-loaded with the core distinction from place_call before moving to response semantics. Dense but every sentence carries information; the tier-1 pricing detail is slightly incidental but supports cost reasoning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be fully explained, yet the description helpfully covers the key conditional fields (hold_cents, valid, warnings.insufficient_balance). Given the high parameter count and near-zero schema coverage, the main remaining gap is parameter-level guidance, which the place_call cross-reference only partially bridges.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are 23 parameters at only 9% schema description coverage, so the description carries the burden of explaining them. It only notes the absence of idempotencyKey and cross-references place_call for the rest, leaving nearly all fields (purpose enum, time_window, consent_attestation, retry_preference, etc.) undocumented in either place.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Check a phone-call body') and immediately distinguishes itself from the sibling place_call by stating it does not create a call or place a hold. An agent can tell validate_call apart from place_call without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The dry-run framing ('without creating a call or placing a hold') gives clear context for when this tool is appropriate versus place_call. It stops short of an explicit instruction such as 'call this before place_call to preview cost and validity', so the routing is strongly implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
13 tool updates
v0.2.0- Added
cancel_call - Added
cancel_task - Added
confirm_task - Changed
delegate_task14 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / description / descriptionPrevious value: -"Detailed context, instructions, and constraints."New value: +"Detailed context, instructions, and constraints (max 8000 chars). Never include passwords, OTP codes, recovery keys, cookies, or API keys." - added
Input schema / properties / description / maxLengthAdded value: +8000 - added
Input schema / properties / dueDateAdded value: +{ + "description": "Optional human-readable due date (e.g. EOD Friday).", + "maxLength": 120, + "type": "string" +} - added
Input schema / properties / idempotencyKeyAdded value: +{ + "description": "Same value as the REST Idempotency-Key header. Required. A repeat returns the original task.", + "type": "string" +} - added
Input schema / properties / maxHoursAdded value: +{ + "description": "Spend cap in hours (default 0.5). VA/AM stop and ask before exceeding. Actual tracked time is billed, not this cap. Max 8.", + "maximum": 8, + "minimum": 0.01, + "type": "number" +} - changed
Input schema / properties / priority / enumPrevious value: -[ - "low", - "normal", - "high" -]New value: +[ + "low", + "normal", + "high", + "urgent" +] - added
Input schema / properties / sourceAgentAdded value: +{ + "description": "Optional calling-agent label for the audit trail (e.g. grok-bot).", + "maxLength": 80, + "type": "string" +} - changed
Input schema / properties / title / descriptionPrevious value: -"Concise directive (max 500 chars)."New value: +"Concise directive (max 5000 chars)." - changed
Input schema / properties / title / maxLengthPrevious value: -500New value: +5000 - changed
Input schema / properties / webhookUrl / descriptionPrevious value: -"Optional HTTPS callback URL."New value: +"Optional public HTTPS callback URL." - changed
Input schema / requiredPrevious value: -[ - "title" -]New value: +[ + "title", + "idempotencyKey" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "message": { + "description": "Human-readable result. Do not claim the VA has started unless the status says so.", + "type": "string" + }, + "status": { + "description": "awaiting_customer_start means the customer has not clicked Start on Work. received is a replay after start, a hold, or a sent card.", + "type": "string" + }, + "success": { + "description": "True when the brief was filed or replayed.", + "type": "boolean" + }, + "taskId": { + "description": "Stable id for get_task.", + "type": "string" + } + }, + "type": "object" +}
- Changed
get_balance3 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "addFundsUrl": { + "description": "POST /api/v1/billing/add-funds. This read does not create a Stripe session.", + "type": "string" + }, + "addHoursUrl": { + "description": "Buy-hours URL. Use it only when a live read is not above zero.", + "type": "string" + }, + "balance_cents": { + "description": "Spendable calls-wallet cents after open holds.", + "type": "number" + }, + "canDelegate": { + "description": "False when hours are unavailable, spendable hours are not above zero, or capRoom is below the minimum new cap.", + "type": "boolean" + }, + "can_place_call": { + "description": "Whether the calls wallet can place a call.", + "type": "boolean" + }, + "capRoom": { + "description": "Hours free for a new cap after open caps. Omitted when hours are unavailable.", + "type": "number" + }, + "holds_cents": { + "description": "Sum of unsettled call holds.", + "type": "number" + }, + "hoursRemaining": { + "description": "Live remaining hours when Ops returned a figure.", + "type": "number" + }, + "hoursUnavailable": { + "description": "True when Ops did not return a live remaining figure. Not a buy-hours signal.", + "type": "boolean" + }, + "wallet_cents": { + "description": "balance_cents plus holds_cents.", + "type": "number" + } + }, + "type": "object" +}
- Added
get_call - Changed
get_task3 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "amNote": { + "description": "AM or VA note.", + "type": "string" + }, + "autoConfirmNote": { + "type": "string" + }, + "awaitingCustomerConfirm": { + "description": "True means ask the human, then confirm_task, cancel_task, or reopen_task.", + "type": "boolean" + }, + "completedAt": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "deliverableLinks": { + "description": "https links from the note.", + "items": { + "type": "string" + }, + "type": "array" + }, + "priority": { + "type": "string" + }, + "result": { + "description": "Full VA result when completed. Never invent this.", + "type": "string" + }, + "status": { + "description": "Stop polling on completed, failed, or cancelled.", + "type": "string" + }, + "taskId": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" +}
- Added
get_transcript - Changed
list_tasks4 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / status / enumPrevious value: -[ - "pending", - "in_progress", - "completed", - "failed", - "all" -]New value: +[ + "pending", + "in_progress", + "completed", + "failed", + "cancelled", + "all" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "tasks": { + "description": "Up to 50 recent tasks.", + "items": { + "additionalProperties": true, + "properties": { + "amNote": { + "type": "string" + }, + "awaitingCustomerConfirm": { + "description": "True means the human must confirm, cancel, or reopen.", + "type": "boolean" + }, + "completedAt": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "deliverableLinks": { + "items": { + "type": "string" + }, + "type": "array" + }, + "priority": { + "type": "string" + }, + "result": { + "description": "Short result snippet when completed.", + "type": "string" + }, + "status": { + "description": "pending, in_progress, completed, failed, or cancelled.", + "type": "string" + }, + "taskId": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" +}
- Added
place_call - Added
reopen_task - Added
update_call - Added
validate_call
4 tool updates
v0.1.1- First observed
delegate_task - First observed
get_balance - First observed
get_task - First observed
list_tasks
TDQS
Scored across 13 tools
Most tools target distinct resources and actions (call vs task lifecycle, validate vs place, get vs cancel). However, delegate_task's description explicitly says to use it for phone calls, which overlaps with the dedicated place_call tool and could cause misselection between the two.
All 13 tools follow a consistent snake_case verb_noun pattern (place_call, validate_call, get_balance, confirm_task, cancel_task, reopen_task, get_transcript, etc.) with predictable verbs for each action.
13 tools is well within a healthy range. The set cleanly splits into a phone-call lifecycle and a task-delegation lifecycle without redundancy, so each tool earns its place.
Both domains have solid lifecycle coverage: calls support place/validate/get/update/cancel/transcript/balance, and tasks support delegate/list/get/confirm/cancel/reopen. The main gap is the absence of a list_calls tool to enumerate calls (only single-call get_call exists), forcing agents to track IDs themselves.
Maintenance
Related MCP Connectors
Human-as-a-Service for AI agents. Delegate tasks that need a real human, get results via API.
Human-in-the-loop API for AI agents. CAPTCHA, OTP, KYC, and approvals by real humans.
Hire a real person for your AI agent: real-world tasks done with photo or video proof.
Hand phone calls to vetted humans. Agents create call tasks; people dial and report outcomes.
Related MCP Servers
- AlicenseAqualityCmaintenanceHuman-as-a-Service for AI agents. When your agent is blocked by a task that requires a real human — accepting ToS, creating accounts, submitting forms, identity verification — it calls NeedHuman. A human completes the task and returns the result with proof.350 npm1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to route tasks requiring human judgment (e.g., content moderation, refund decisions, data verification) to a vetted worker pool, with verified results returned via Lightning Network payments.MIT
- AlicenseNot gradedqualityDmaintenanceLets AI agents natively discover and hire human experts for tasks they can't do themselves, such as research, verification, and expert calls.MIT

humanforaiofficial
AlicenseAqualityBmaintenanceEnables AI agents to hire real human operators for tasks requiring physical presence, human perception, or judgment, such as verification, testing, data collection, and physical-world tasks.451 npm1MIT