Prompt World · Model Context Protocol

Build a stage by talking to your AI.

Prompt World is a black-and-white 2D physics platformer where anyone's Claude can design a playable course as JSON and publish it as a URL. This is the MCP server that makes that possible — six tools, one endpoint, one hard rule: a real human must clear a stage before it goes live.

POST https://promptworldgame.org/mcp · JSON-RPC 2.0 over Streamable HTTP · no auth to connect

How it works

Six tools, front to back

The whole surface is six JSON-RPC methods behind tools/call. You learn the format, build the stage, hand a human a link to clear, then publish. Nothing reaches other players until a person has actually beaten it in the browser.

1
AI

get_toolbox

Read the stage schema, the full parts vocabulary, physics constants, and design guidance — always call this first.

2
AI · asks the human

create_stage

Save a new draft. Returns an id, a secret editKey, and a testUrl for the human to play.

3
AI · iterate

update_stage

Edit that same stage in place while tuning it — same URL, doesn't spend the daily create quota.

4
Human

Play the testUrl

The creator clears it in the browser. The run is replay-verified server-side and becomes the ghost + par time.

5
AI

stage_status

Poll until cleared: true — proof the human beat it.

6
AI · asks the human

publish_stage

Go live under a creator-approved name. Blocked until a verified clear exists.

Reference

The six tools

Every call is {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"…","arguments":{…}}}. Tags mark each tool read (safe, no writes), write (creates or changes data), or human-gate (needs a real human clear).

get_toolbox read

The single source of truth for the stage format: JSON schema, all 24 part types, physics constants, size/coordinate limits, background & music recipes, and design rules. Call it first, every session.

Arguments — none.

Returns — one long text document (the toolbox). Not machine-structured; it's written for the AI to read and follow.

create_stage write

Validate and save a new stage as a draft. Returns the id, a secret editKey (keep it), a testUrl for the human to clear, and a playUrl for after publishing.

Arguments
NameTypeDescription
stageobjectrequiredThe full stage JSON — playerStart, goal, parts, and optional bg / music / hideGhost. See the toolbox schema. Must include nameLoc and desc localized in all of en/ja/zh/es/ko — creation is rejected without them.
creatorTokenstringoptionalYour identity token from a previous create. Omit on first use — one is minted and returned (which then requires creatorName + creatorConfirmed).
creatorNamestringrequired*The "made by ___" credit (≤30 chars). *Required when no creatorToken is passed: always ask the human for it before creating.
creatorConfirmedbooleanrequired**Required (true) when no creatorToken is passed: asserts the human saw and explicitly approved the creator name that will be credited.

Returnsid, editKey, testUrl, playUrl, status: "draft", and on first use a creatorToken to reuse.

// request
{
  "name": "tools/call",
  "arguments": {
    "stage": {
      "schemaVersion": "0.3",
      "name": "Split Second",
      "timeLimit": 60,
      "playerStart": { "x": -12, "y": -2.5 },
      "goal": { "x": 20, "y": -2.3, "w": 1.4, "h": 2.6 },
      "parts": [ { "type": "solid", "x": 0, "y": -4, "w": 40, "h": 1 } ],
      "nameLoc": { "en": "Split Second", "ja": "一瞬の隙", "zh": "千钧一发", "es": "Fracción de segundo", "ko": "찰나의 순간" },
      "desc": { "en": "One jump, one chance.", "ja": "一度のジャンプに全てを懸けろ。", "zh": "一跳定胜负。", "es": "Un salto, una oportunidad.", "ko": "단 한 번의 점프." }
    },
    "creatorName": "Aki",
    "creatorConfirmed": true
  }
}
update_stage write

Edit an existing stage in place — same id, same URL — instead of minting a new draft. This is how you iterate on a course without burning the daily create quota.

Arguments
NameTypeDescription
idstringrequiredThe stage to update.
editKeystringrequiredThe editKey from create — only the creator holds it.
stageobjectrequiredThe full replacement stage JSON (same schema as create_stage).
creatorTokenstringoptionalAttributes the edit; for the operator, exempts it from rate limits.
Updating a published stage sends it back to draft. The content changed, so its old clear and ghost are discarded — it must be re-cleared and re-published. This keeps every published clear record honest.
delete_stage write

Permanently remove a stage you created — for pulling a draft or testbench arena you no longer want on the shelf. Requires the editKey.

Arguments
NameTypeDescription
idstringrequiredThe stage to delete.
editKeystringrequiredThe editKey from create — only the creator holds it.
creatorTokenstringoptionalThe operator admin token also authorizes deletion.
Only unpublished stages can be deleted. A published stage carries other players' scores, votes and play records, so it is refused (409) — removing it would erase their data. Deletion is irreversible; the AI confirms with the human first.
stage_status read

Check where a stage stands: draft or published, whether a clear has been recorded, and the clear time. Poll this after handing the human the testUrl.

Arguments
NameTypeDescription
idstringrequiredThe stage id.
// response text
{
  "id": "bda3rcez",
  "name": "Ukiyo-e Orbit",
  "status": "draft",
  "cleared": true,        // ← the human beat it
  "clearTimeMs": 14000,
  "playUrl": null       // set once published
}
publish_stage write human-gate

Make a cleared stage public. Blocked until a verified human clear exists. Before calling, the AI asks the human to confirm the final name and passes it as confirmedName.

Arguments
NameTypeDescription
idstringrequiredThe stage to publish.
editKeystringrequiredProof of authorship.
confirmedNamestringrequiredThe name the human explicitly approved (1–60 chars). The stage is renamed to this. Never invented by the AI.

Returnsstatus: "published", the public playUrl, plus share text and a search hint.

list_stages read

Return every published community stage with its play URL. Read-only.

Arguments — none. Returns — the published stage list.

The rule you can't skip

Publishing needs a human clear

An AI cannot bot-solve or auto-verify a stage. The only path to publish is: a real person opens the testUrl, beats it in the browser, and their run is re-simulated server-side against the exact deterministic physics. That verified run becomes the stage's ghost and par time. No clear, no publish — for everyone, including the operator.

Why it holds: the clear is a replay certificate re-run through the same 50 Hz deterministic sim the browser used. A forged or impossible run fails re-simulation and is rejected. Editing a live stage voids its clear precisely because the old certificate no longer matches the new layout.

Abuse controls

Limits & capacity

The endpoint is open — no key to connect — so limits are per-IP-per-day, with platform-wide circuit breakers behind them. Honest iteration is cheap; flooding is bounded.

30 /day
create — new drafts per IP
300 /day
update — edits to your own stage per IP
10 /day
publish — per IP
5 /day
publish — per creator identity
7 days
unpublished drafts auto-deleted
300 parts
max parts per stage
5,000
published-stage ceiling
15,000
draft pool (oldest evicted first)

Vocabulary

24 part types

Everything a stage is built from. Coordinates are world units (centres); sizes 0.05–100; up to 300 parts. Full behaviour, arguments, and limits live in get_toolbox.

solidhazardjumpPadboost movingPlatformcrumblefallerconveyor gravitySetgravityFliptimedGatekey doorlaunchercannoncheckpoint rotatingHazardteleporterfanswitch switchGateenemybossDoor

Plus three purely-decorative, sim-independent layers on any stage: