Skip to content
MCPBytes
DocsRun a fair draw

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.

Start a jobcURL
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"}}'
Response200 OK · trimmed
{
  "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"
  }
}
Get the resultcURL
curl "https://api.mcpbytes.com/v1/jobs/$JOB_ID" \
  -H "Authorization: Bearer $MCPBYTES_API_KEY"
Response200 OK · trimmed
{
  "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.

Options
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.

Output files
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:

result
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 Code

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/random
Codex (CLI, IDE extension, ChatGPT desktop)

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_KEY
Cursor

~/.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

~/.cursor/mcp.json
{
  "mcpServers": {
    "mcpbytes": {
      "url": "https://api.mcpbytes.com/mcp/random",
      "headers": {
        "Authorization": "Bearer ${env:MCPBYTES_API_KEY}"
      }
    }
  }
}
11 more clients in the docs →

Arguments

The tool's options are flat arguments. Besides them:

run_draw arguments
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

MCP tools
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:

mcpbytes.py
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

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.

Job errors
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.