Skip to main content
Glama

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.

npm version MIT License

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

Install in Cursor Install in Cursor (light)

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

Install in VS Code

Install in VS Code Insiders

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-server

Replace 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-server

Then 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

get_balance

GET /api/v1/balance

Read-only. Hours and the calls wallet. Call this before proposing spend.

delegate_task

POST /api/v1/delegate

Files a brief. Idempotency-Key required. Spends real hours after the customer starts it on Work.

list_tasks

GET /api/v1/tasks

Read-only. Up to 50 tasks. Filter includes cancelled.

get_task

GET /api/v1/tasks/{taskId}

Read-only. Stop on completed, failed, or cancelled. awaitingCustomerConfirm means ask the human.

confirm_task

POST /api/v1/tasks/{taskId}/confirm

Accepts a delivery and settles tracked hours. Idempotency-Key required. Ask the human first.

cancel_task

POST /api/v1/tasks/{taskId}/cancel

Releases the hold and bills only tracked time. Idempotency-Key required. Ask the human first.

reopen_task

POST /api/v1/tasks/{taskId}/reopen

Sends the delivery back. reason required. Idempotency-Key required. Ask the human first.

place_call

POST /api/v1/calls

One human call. US and Canada only. record_call must be false or omitted. Idempotency-Key required.

validate_call

POST /api/v1/calls/validate

Checks the body. Creates nothing and places no hold. Returns hold_cents.

get_call

GET /api/v1/calls/{id}

Read-only. Includes needs_info or the final result.

update_call

PATCH /api/v1/calls/{id}

Fills missing fields while the call is needs_info.

cancel_call

POST /api/v1/calls/{id}/cancel

Asks ops to cancel. Stays cancel_pending until ops confirms. A confirm before any dial refunds the hold. After the dial starts, the error is cancel_too_late and the call bills normally.

get_transcript

GET /api/v1/calls/{id}/transcript.txt

VA wrap-up summary, not a recording. source is wrap_up_summary and recorded is false. Empty is transcript_not_ready. No dial is no transcript: call not placed. Cancel after the dial started is call_cancelled.

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)

https://taskbullet.com/api/agent-mcp

x-api-key: tb_live_…

get_balance, delegate_task, list_tasks, get_task, confirm_task, cancel_task, reopen_task, place_call, validate_call, get_call, update_call, cancel_call, get_transcript

Public site guide

https://taskbullet.com/api/mcp

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:

  1. No account → https://taskbullet.com/get-started?source=openclaw (10 hours, no card)

  2. Issue tb_live_… at https://taskbullet.com/dashboard/settings/api-keys (shown once)

  3. Paste it into the Gateway env TASKBULLET_API_KEY and point Agent MCP at https://taskbullet.com/api/agent-mcp with header x-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 --http

Endpoint: 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

TASKBULLET_API_KEY

yes

—

tb_live_… key. npm and Cursor read it from the environment. The Claude plugin reads the prompt value only. Never logged or copied into tool results.

TASKBULLET_API_BASE

no

https://taskbullet.com/api/v1

Override for staging

TASKBULLET_SOURCE_AGENT

no

mcp-client

Audit label stored on each brief

TASKBULLET_TRANSPORT

no

stdio

Set to http to serve streamable HTTP

TASKBULLET_HTTP_HOST

no

127.0.0.1

Bind address. Non-loopback requires a token

TASKBULLET_HTTP_PORT

no

3000

HTTP port

TASKBULLET_HTTP_TOKEN

when exposed

—

Local HTTP auth for npm and Cursor. The Claude plugin reads the prompt value only. Not the TaskBullet API key

TASKBULLET_HTTP_ALLOWED_ORIGINS

no

loopback origins

Extra browser Origin values, comma-separated

Completion

  1. Poll get_task until status is completed, failed, or cancelled. When awaitingCustomerConfirm is true, ask the human, then confirm_task, cancel_task, or reopen_task.

  2. Webhook — pass an https webhookUrl. TaskBullet POSTs a signed body when the customer closes the job, and task.awaiting_confirmation when a delivery is waiting. A customer cancel does not send task.completed. See the webhook docs.

  3. Calls — poll get_call until the call finishes, or pass an https callback_url. Read get_transcript when 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 tools
cancel_callCancel callA
DestructiveIdempotent
Inspect

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.

NameRequiredDescriptionDefault
call_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 taskA
DestructiveIdempotent
Inspect

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.

NameRequiredDescriptionDefault
reasonNoOptional note. Do not include secrets.
taskIdYesThe taskId returned by delegate_task.
idempotencyKeyYesSame value as the REST Idempotency-Key header. Required.

Output Schema

NameRequiredDescription
titleNo
amNoteNoAM or VA note.
resultNoFull VA result when completed. Never invent this.
statusNoStop polling on completed, failed, or cancelled.
taskIdNo
priorityNo
createdAtNo
completedAtNo
autoConfirmNoteNo
deliverableLinksNohttps links from the note.
awaitingCustomerConfirmNoTrue means ask the human, then confirm_task, cancel_task, or reopen_task.

TDQS

A4.1/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 taskA
DestructiveIdempotent
Inspect

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.

NameRequiredDescriptionDefault
taskIdYesThe taskId returned by delegate_task.
idempotencyKeyYesSame value as the REST Idempotency-Key header. Required.

Output Schema

NameRequiredDescription
titleNo
amNoteNoAM or VA note.
resultNoFull VA result when completed. Never invent this.
statusNoStop polling on completed, failed, or cancelled.
taskIdNo
priorityNo
createdAtNo
completedAtNo
autoConfirmNoteNo
deliverableLinksNohttps links from the note.
awaitingCustomerConfirmNoTrue means ask the human, then confirm_task, cancel_task, or reopen_task.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 taskA
DestructiveIdempotent
Inspect

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.

NameRequiredDescriptionDefault
titleYesConcise directive (max 5000 chars).
dueDateNoOptional human-readable due date (e.g. EOD Friday).
maxHoursNoSpend cap in hours (default 0.5). VA/AM stop and ask before exceeding. Actual tracked time is billed, not this cap. Max 8.
priorityNonormal
webhookUrlNoOptional public HTTPS callback URL.
descriptionNoDetailed context, instructions, and constraints (max 8000 chars). Never include passwords, OTP codes, recovery keys, cookies, or API keys.
sourceAgentNoOptional calling-agent label for the audit trail (e.g. grok-bot).
idempotencyKeyYesSame value as the REST Idempotency-Key header. Required. A repeat returns the original task.

Output Schema

NameRequiredDescription
statusNoawaiting_customer_start means the customer has not clicked Start on Work. received is a replay after start, a hold, or a sent card.
taskIdNoStable id for get_task.
messageNoHuman-readable result. Do not claim the VA has started unless the status says so.
successNoTrue when the brief was filed or replayed.

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 balanceA
Read-onlyIdempotent
Inspect

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
capRoomNoHours free for a new cap after open caps. Omitted when hours are unavailable.
addFundsUrlNoPOST /api/v1/billing/add-funds. This read does not create a Stripe session.
addHoursUrlNoBuy-hours URL. Use it only when a live read is not above zero.
canDelegateNoFalse when hours are unavailable, spendable hours are not above zero, or capRoom is below the minimum new cap.
holds_centsNoSum of unsettled call holds.
wallet_centsNobalance_cents plus holds_cents.
balance_centsNoSpendable calls-wallet cents after open holds.
can_place_callNoWhether the calls wallet can place a call.
hoursRemainingNoLive remaining hours when Ops returned a figure.
hoursUnavailableNoTrue when Ops did not return a live remaining figure. Not a buy-hours signal.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 callB
Read-onlyIdempotent
Inspect

Read one human phone call, including needs_info missing_fields or the final result.

NameRequiredDescriptionDefault
call_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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 taskA
Read-onlyIdempotent
Inspect

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.

NameRequiredDescriptionDefault
taskIdYesThe taskId returned by delegate_task.

Output Schema

NameRequiredDescription
titleNo
amNoteNoAM or VA note.
resultNoFull VA result when completed. Never invent this.
statusNoStop polling on completed, failed, or cancelled.
taskIdNo
priorityNo
createdAtNo
completedAtNo
autoConfirmNoteNo
deliverableLinksNohttps links from the note.
awaitingCustomerConfirmNoTrue means ask the human, then confirm_task, cancel_task, or reopen_task.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 transcriptA
Read-onlyIdempotent
Inspect

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.

NameRequiredDescriptionDefault
call_idYes

TDQS

A4.1/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 tasksA
Read-onlyIdempotent
Inspect

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.

NameRequiredDescriptionDefault
statusNoall

Output Schema

NameRequiredDescription
tasksNoUp to 50 recent tasks.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 callA
DestructiveIdempotent
Inspect

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.

NameRequiredDescriptionDefault
goalYes
phoneYesUS or Canada number. 801-414-4664, (801) 414-4664, and +1 801 414 4664 are accepted and stored as E.164.
scriptNo
purposeYes
deadlineYesISO-8601. Needs 60 minutes of weekday 09:00–17:00 recipient-local, unless allow_outside_business_hours is true.
languageNoen, fil, tl, war, or ceb. Default en.
extensionNoOptional digits. Passed into the VA instructions. Not billed.
questionsYesOne to 20 questions. Each item is {id, ask, type?}.
max_minutesNoDefault 5. Maximum 60. The hold covers this many minutes.
record_callNoFalse or omit. True is rejected: recording is not available.
script_modeNo
time_windowNoOptional 24-hour HH:MM-HH:MM in the recipient time zone. Example: 09:00-17:00. End must be after start.
callback_urlNo
instructionsNoOutranks script wording. The extension is appended for the VA.
max_attemptsNoDefault 3. Maximum 5.
on_behalf_ofYes
business_nameYes
idempotencyKeyYesSame value as the REST Idempotency-Key header.
retry_preferenceNo
shareable_contactNo
recipient_timezoneNoIANA zone. Omit it and TaskBullet infers a US or Canada area code. An uninferable number needs this field.
allowed_disclosuresNo
consent_attestationYesMust be true.
allow_outside_business_hoursNoSet 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

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 taskA
Idempotent
Inspect

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.

NameRequiredDescriptionDefault
reasonYesWhat should happen next. Required. Do not include secrets.
taskIdYesThe taskId returned by delegate_task.
idempotencyKeyYesSame value as the REST Idempotency-Key header. Required.

Output Schema

NameRequiredDescription
titleNo
amNoteNoAM or VA note.
resultNoFull VA result when completed. Never invent this.
statusNoStop polling on completed, failed, or cancelled.
taskIdNo
priorityNo
createdAtNo
completedAtNo
autoConfirmNoteNo
deliverableLinksNohttps links from the note.
awaitingCustomerConfirmNoTrue means ask the human, then confirm_task, cancel_task, or reopen_task.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 callB
Idempotent
Inspect

Fill missing_fields on a call in needs_info. Same result shapes as place_call.

NameRequiredDescriptionDefault
goalNo
phoneNo
scriptNo
call_idYes
purposeNo
deadlineNo
languageNo
extensionNoOptional digits. Passed into the VA instructions.
questionsNo
max_minutesNo
record_callNo
script_modeNo
time_windowNo
callback_urlNo
instructionsNo
max_attemptsNo
on_behalf_ofNo
business_nameNo
retry_preferenceNo
shareable_contactNo
recipient_timezoneNo
allowed_disclosuresNo
consent_attestationNo
allow_outside_business_hoursNoSet 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

NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 callA
Read-onlyIdempotent
Inspect

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.

NameRequiredDescriptionDefault
goalNo
phoneNo
scriptNo
purposeNo
deadlineNo
languageNo
extensionNo
questionsNo
max_minutesNo
record_callNoFalse or omit.
script_modeNo
time_windowNoHH:MM-HH:MM, 24-hour, end after start.
callback_urlNo
instructionsNo
max_attemptsNo
on_behalf_ofNo
business_nameNo
retry_preferenceNo
shareable_contactNo
recipient_timezoneNo
allowed_disclosuresNo
consent_attestationNo
allow_outside_business_hoursNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 13 tool updatesv0.2.0
    • Addedcancel_call
    • Addedcancel_task
    • Addedconfirm_task
    • Changeddelegate_task14 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / description / description
        Previous 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."
      • addedInput schema / properties / description / maxLength
        Added value: +8000
      • addedInput schema / properties / dueDate
        Added value: +{
        +  "description": "Optional human-readable due date (e.g. EOD Friday).",
        +  "maxLength": 120,
        +  "type": "string"
        +}
      • addedInput schema / properties / idempotencyKey
        Added value: +{
        +  "description": "Same value as the REST Idempotency-Key header. Required. A repeat returns the original task.",
        +  "type": "string"
        +}
      • addedInput schema / properties / maxHours
        Added 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"
        +}
      • changedInput schema / properties / priority / enum
        Previous value: -[
        -  "low",
        -  "normal",
        -  "high"
        -]New value: +[
        +  "low",
        +  "normal",
        +  "high",
        +  "urgent"
        +]
      • addedInput schema / properties / sourceAgent
        Added value: +{
        +  "description": "Optional calling-agent label for the audit trail (e.g. grok-bot).",
        +  "maxLength": 80,
        +  "type": "string"
        +}
      • changedInput schema / properties / title / description
        Previous value: -"Concise directive (max 500 chars)."New value: +"Concise directive (max 5000 chars)."
      • changedInput schema / properties / title / maxLength
        Previous value: -500New value: +5000
      • changedInput schema / properties / webhookUrl / description
        Previous value: -"Optional HTTPS callback URL."New value: +"Optional public HTTPS callback URL."
      • changedInput schema / required
        Previous value: -[
        -  "title"
        -]New value: +[
        +  "title",
        +  "idempotencyKey"
        +]
      • changedOutput 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"
        +}
    • Changedget_balance3 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput 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"
        +}
    • Addedget_call
    • Changedget_task3 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput 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"
        +}
    • Addedget_transcript
    • Changedlist_tasks4 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / status / enum
        Previous value: -[
        -  "pending",
        -  "in_progress",
        -  "completed",
        -  "failed",
        -  "all"
        -]New value: +[
        +  "pending",
        +  "in_progress",
        +  "completed",
        +  "failed",
        +  "cancelled",
        +  "all"
        +]
      • changedOutput 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"
        +}
    • Addedplace_call
    • Addedreopen_task
    • Addedupdate_call
    • Addedvalidate_call
  2. 4 tool updatesv0.1.1
    • First observeddelegate_task
    • First observedget_balance
    • First observedget_task
    • First observedlist_tasks

TDQS

A3.9/5.0

Scored across 13 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Human-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.
    3
    50 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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
  • A
    license
    A
    quality
    B
    maintenance
    Enables 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.
    4
    51 npm
    1
    MIT