Your first call, step by step
A test key, one tool call and one fetch. Simulated people answer in seconds, so you can see the whole road before anyone real is rung.
A preview. Simulated people for everyone. Real calls by invitation. No money is charged: every amount is test money.
1. Get a test key (optional)
Simulated calls work with no key at all; a key adds a balance and caps. No account and no human needed. It holds $100 of test money and reaches simulated people only.
curl -s -X POST https://api.person.tools/v1/keys \
-H "content-type: application/json" -d '{"class":"test"}'2. Connect the MCP server
Streamable HTTP. With no key it reaches simulated people; with a key, add an Authorization header. In Claude Code:
claude mcp add --transport http person-tools https://api.person.tools/mcp
# with a key:
claude mcp add --transport http person-tools https://api.person.tools/mcp \
--header "Authorization: Bearer test_YOUR_KEY"3. Price a call (nothing is spent)
Call ask_people_quote, or POST /v1/quotes, with the same fields as the call. The material can wait: without content the quote is priced from minutes (stated, or 2) and says so in defaults_used. It returns each line of the price, test_money: true, and for_your_user, a sentence to show your user.
curl -s https://api.person.tools/v1/quotes -H "authorization: Bearer test_YOUR_KEY" \
-H "content-type: application/json" -d '{"ask": "Listen once to the end. Then say what you felt, in your own words.", "kind": "listen", "content": "m_sample_melody30", "people": 3, "answer_fields": {"felt": "text", "would_play_again": "boolean"}}'4. Open the call
Call ask_people, or POST /v1/calls. Required: ask, kind, content (not for kind answer), people, max_total_usd. Send an idempotency_key too, so a retry returns the same call. It returns a call_id at once.
{
"ask": "Listen once to the end. Then say what you felt, in your own words.",
"kind": "listen",
"content": "m_sample_melody30",
"people": 3,
"answer_fields": {
"felt": "text",
"would_play_again": "boolean"
},
"max_total_usd": "0.00",
"idempotency_key": "first-try-1"
}5. Fetch the answers
Call ask_people_results, or GET /v1/calls/{call_id}/responses?wait_seconds=25. Look again after next_check_after_seconds. Simulated answers carry simulated: true and begin "[simulated] ".
curl -s "https://api.person.tools/v1/calls/CALL_ID/responses?wait_seconds=25" \
-H "authorization: Bearer test_YOUR_KEY"6. Tell your user what came back
Say that the answers are simulated, what was spent (test money), and what you will change. If the answers change the work, send one line back with ask_people_send_outcome.
Other ways in
- Claude Code plugin: /plugin marketplace add jonwashburn/person-tools, then /plugin install ask-people@person-tools
- Official MCP registry: the entry tools.person/ask-people (the same server)
- Source: https://github.com/jonwashburn/person-tools, under the Apache License 2.0
Real people
Real people are rung only on a panel whose owner invited them. Making a panel needs a live key, which only the owner of this service issues during the preview; a test key, or no key, cannot make a panel or ring a real person. The one exception is the front page's demo (Call me), which rings the visitor themselves with one of a few fixed asks. Real calls are by invitation; no request form is open yet.
Questions builders ask
Will a retry open a second call? No. The same idempotency_key with the same body returns the same call; the same key with a different body is the error idempotency_key_reused. With no idempotency_key, the same body within 10 minutes counts as the same call.
How long does a call stay open? Set deadline_minutes. Leave it out and defaults_used, in the quote and in the call, shows the deadline chosen. The longest allowed is under limits in the discovery file.
What can content be? A media id from GET /v1/media/samples (no key needed; m_sample_melody30 is one), an https address of the material, or {"text": "..."} for words to read (view and compare). For compare, a list of two to six of these. Uploading your own files is not open in the preview: the OpenAPI file lists POST /v1/media because the standard defines it, and this server does not offer it (media_upload is not among the features in its discovery file).
Which kinds of call, and which answers? Kinds: listen, watch, view, play, compare, answer. Answer fields: text, boolean, number (min, max), choice (choices, multiple) and scale (min, max, at most 11 values).
What are the limits? The discovery file lists them under limits: the most people on a call, the longest deadline and the longest wait for answers. Too many requests get rate_limited (HTTP 429) with retry_after_seconds.
A Python script gets "Error code: 1010" Python's built-in urllib gets "Error code: 1010" (HTTP 403) from the edge in front of the site and the API, before our code runs: its default User-Agent is refused for now. Send a User-Agent header of your own (for example "my-agent/1.0"); curl, httpx, requests and MCP clients are not affected.
How does the key reach the MCP server? As an Authorization header, as in step 2. Other MCP clients take the same header in their server settings.
What happens to what I send? It is shown to the people on the call and, if screening holds the call, to the operator who reviews it. A copy of your material is kept until the last call using it closes, plus 30 days. How long each kind of record is kept is listed under retention in the discovery file. A quote keeps only its lines and total, for one day, so the person who approves a call can see them; never the ask or the content.
Everything else
The tool text as served · price and terms · questions · OpenAPI file · discovery file · the standard (draft)