Tool reference · Utilities
Run a fair draw
Winners, or a shuffled order, from a list, with hardware randomness and a signed public receipt.
- MCP tool
- run_draw
- MCP endpoint
- /mcp/random
- REST
- POST /v1/tools/run_draw/jobs
- Price
- 10 credits per job
Overview
run_draw picks count winners (plus optional alternates, in order) from a list of entries, or shuffles the whole list. When the draw is created, the entries are fingerprinted (SHA-256) and stored, and the job is charged; then fresh hardware randomness is drawn and its fingerprint is committed on an Ed25519-signed receipt. At draw_at, or at once without it, the randomness is revealed and the result computed and signed. Each draw has a permanent page, receipt_url, that recomputes the result in the reader's browser; the signed receipt itself is GET /draws/{id} on the API, and GET /draws/key publishes the public key. Draws are numbered per organizer, so a re-run for the same list shows as a new number. The receipt proves the list was fixed before the randomness and lets anyone recompute the result; it cannot prove how the hardware randomness was produced.
- Randomness
- Hardware-generated, fresh for each draw
- Input
- entries (one per line), title, winners and alternates or a shuffle; no file
- Outputs
- A public page, the signed receipt (draw.json) and draw.txt
- Proof
- Entries locked first; Ed25519-signed receipt; recomputable by anyone
- Schedule
- Reveal now, or at a time up to 30 days ahead
Quickstart
Send the options as JSON. The response is the new job; poll it until its status is final, then download the files in result.files.
curl https://api.mcpbytes.com/v1/tools/run_draw/jobs \
-H "Authorization: Bearer $MCPBYTES_API_KEY" \
-H "Content-Type: application/json" \
-d '{"idempotency_key":"giveaway-example-001",
"options":{"title":"October giveaway",
"count":2,"alternates":1,"publish_entries":true,
"entries":"ticket-01\nticket-02\nticket-03\nticket-04\nticket-05\nticket-06\nticket-07\nticket-08\nticket-09\nticket-10\nticket-11\nticket-12"}}'{
"id": "j_ms3h6bzdpe8d4g5skh96a531cy",
"tool": "run_draw",
"status": "succeeded",
"input_kind": "parameters",
"draw": {
"id": "d_twh8fkzwkksxh7y6ykpfexdc4v",
"status": "drawn",
"receipt_url": "https://mcpbytes.com/draws/d_twh8fkzwkksxh7y6ykpfexdc4v",
"draw_at": "2026-09-24T18:24:12.644Z"
},
"options": {
"title": "October giveaway",
"mode": "pick",
"count": 2,
"alternates": 1,
"publish_entries": true,
"entries_count": 12,
"entries_sha256": "08b4ee8c7fa858181f549277d7bff2b65edd0baf252920884b0103272a5c587e",
"draw_id": "d_twh8fkzwkksxh7y6ykpfexdc4v"
}
}curl "https://api.mcpbytes.com/v1/jobs/$JOB_ID" \
-H "Authorization: Bearer $MCPBYTES_API_KEY"{
"id": "j_ms3h6bzdpe8d4g5skh96a531cy",
"tool": "run_draw",
"status": "succeeded",
"draw": {
"id": "d_twh8fkzwkksxh7y6ykpfexdc4v",
"status": "drawn",
"receipt_url": "https://mcpbytes.com/draws/d_twh8fkzwkksxh7y6ykpfexdc4v",
"draw_at": "2026-09-24T18:24:12.644Z"
},
"result": {
"draw_id": "d_twh8fkzwkksxh7y6ykpfexdc4v",
"status": "drawn",
"title": "October giveaway",
"receipt_url": "https://mcpbytes.com/draws/d_twh8fkzwkksxh7y6ykpfexdc4v",
"draw_at": "2026-09-24T18:24:12.644Z",
"files": [
{
"name": "draw.json"
},
{
"name": "draw.txt"
}
]
}
}A job can be canceled while it is queued: POST /v1/jobs/{id}/cancel.
More on statuses, downloads and retention in Jobs & files.
Input
No file. Send the options in a JSON body, {"options": {…}}, or as arguments of the MCP tool. Keep private text such as prompts out of URLs.
idempotency_key is required. Repeating a request with the same key returns the original job instead of starting and charging a new one; reusing a key for a different request returns 409 idempotency_conflict.Options
Put options in the options object of the JSON body, or pass them as arguments of the MCP tool. Leave an option out to use its default.
- entries
textOne entry per line; spaces around entries and empty lines are ignored; duplicates are refused.- title
1–120 charactersShown on the public page.- mode
pick | shufflepick: choose winners (default); shuffle: order every entry.- count
1–1000Winners to pick; default 1.- alternates
0–100Backup winners, in order; default 0.- draw_at
ISO 8601 timeReveal at this time, up to 30 days ahead; omit to draw now.- publish_entries
true | falsePublish the list on the page; default false.
Outputs
A succeeded job lists its files in result.files, each with a download url.
- draw.json
- The signed receipt: rules, the entries' count and fingerprint, the hardware randomness (its fingerprint, then its bytes once drawn), the seed and the result.
- draw.txt
- The result in words, returned inline over MCP.
A new draw returns HTTP 202 while its hardware randomness is drawn, usually within seconds; replaying a completed request returns HTTP 200. Every draw job also carries `draw`: its id, status (pending, committed, drawn or failed), receipt_url and draw_at. A scheduled draw's files are rewritten at the reveal. The page and receipt are permanent; the job's files follow output retention.
Result summary
Next to files, the job's result has a summary you can check without downloading anything:
- draw_id
- The draw's public id.
- status
- drawn, or scheduled until draw_at.
- title
- The title shown on the page.
- receipt_url
- The draw's public page.
- draw_at
- When the result is (or was) revealed.
Tips
- Put one entry per line: handles, ticket numbers or names, never emails. Winners appear on a public page.
- Share receipt_url with participants. The page shows the result and checks the receipt in the reader's browser.
- Set publish_entries to let anyone check the list itself. Otherwise the page shows only its size and fingerprint, and a shuffle shows positions instead of names.
- With draw_at, the job succeeds at once with status scheduled: the page is live and its randomness fixed, and the result appears at that time.
- Reuse the idempotency key to retrieve the same draw after a network failure. A new key for the same list is a new, numbered draw.
- If hardware randomness is unavailable, the draw fails with source_unavailable and costs nothing.
MCP
Your agent calls run_draw. Connect it to https://api.mcpbytes.com/mcp/random for this tool and the rest of its family (Get random numbers), or to https://api.mcpbytes.com/mcp for every tool.
Claude CodeOAuth or API key
The first form signs in through the browser when you run /mcp. In .mcp.json (project root), ${MCPBYTES_API_KEY} is read from the environment when Claude Code connects. Claude Code docs
claude mcp add --transport http mcpbytes \
https://api.mcpbytes.com/mcp/randomCodex (CLI, IDE extension, ChatGPT desktop)OAuth or API key
Codex reads the key from the environment variable each time it connects. The same table can go in ~/.codex/config.toml by hand; codex mcp add has no --header flag. Codex docs
codex mcp add mcpbytes --url https://api.mcpbytes.com/mcp/random \
--bearer-token-env-var MCPBYTES_API_KEYCursorOAuth or API key
~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). Remote servers take no "type". Without the header, the client signs you in with GitHub or an email link (OAuth). Cursor docs
{
"mcpServers": {
"mcpbytes": {
"url": "https://api.mcpbytes.com/mcp/random",
"headers": {
"Authorization": "Bearer ${env:MCPBYTES_API_KEY}"
}
}
}
}Arguments
The tool's options are flat arguments. Besides them:
- wait_seconds
0–45, default 30How long the call waits for the result. If the job is still running, the agent calls get_job.- max_length
16–100,000, default 20,000Bytes of draw.txt returned with the result; read the rest with read_job_file.- idempotency_key
RequiredReuse it with the same arguments when retrying after a network error.
What the agent sees
- run_draw
- Picks count winners (plus optional alternates) from entries, or shuffles them, using hardware randomness. The entries are locked before any randomness is drawn, and the result comes with a permanent public receipt (receipt_url) that anyone can use to recompute it. With draw_at, the page exists now and the result is revealed at that time. Returns draw.txt (inline) and the signed receipt, draw.json. Costs 10 credits per job. Requires idempotency_key; retain it when retrying the same request.
- get_job
- Status and results of a job; waits up to wait_seconds for it to finish.
- cancel_job
- Cancel a queued job or a workflow whose can_cancel is true; repeated calls never delete results.
- list_jobs
- Your most recent jobs, newest first.
- read_job_file
- Reads a text output (.txt .json .md .csv) of a succeeded job in chunks.
Setup for every client, and how agents upload files and read results: Connect over MCP.
Agent skill
The MCPBytes skill teaches agents this tool, in references/run_draw.md. Agents without MCP run it through the REST API with the skill's script, which reads your key from MCPBYTES_API_KEY:
python scripts/mcpbytes.py run run_draw \
-o title="October giveaway" \
-o entries="$(cat entries.txt)" \
-o count=2 -o alternates=1 --out draw/Pricing
10 credits per job. The price is charged before paid processing starts. A job that fails costs nothing: its charge is refunded.
- Per job
- 10 credits
One credit balance pays for every tool, and a new account starts with free credits. See Credits & prices or buy credits.
Limits
- Entries
- 2–10,000 per draw, unique, one per line
- Winners
- 1–1,000, plus up to 100 alternates
- At a time
- 1 job
- Results
- 24 hours by default
GET /v1/me returns your limits and current usage; Limits & errors explains what happens when one is reached.
Errors
A failed job comes back with error.code, error.message and often error.hint. Codes are stable. Inputs that fail with a validation error will fail again unchanged.
- source_unavailable
- Hardware randomness was unavailable, so the draw did not run. The charge is refunded.
- invalid_options
- Fewer than 2 or duplicate entries, count plus alternates above the number of entries, or draw_at more than 30 days ahead.
- unsupported_format
- The tool does not take this file type.
- insufficient_credits
- The job costs more than the balance, which is known once the input has been measured. Nothing was charged.
- timeout
- The job did not finish within its time limit.
- out_of_memory
- The file needs more memory than a job has.
Requests can also fail before a job starts, with an HTTP status: see HTTP errors.