MCP / GUIDE 09
Create a mission with MCP
This recipe shows the safe sequence for authoring a mission through MCP. The AI client should read the live schemas and campaign state before composing writes. The server applies the same document rules used by the visual editor.
1. Read access and schema
Call studio_get_context for scope and limits, then studio_get_schema for the operation schemas and examples. Pass nodeType when you need a specific node configuration. Call studio_list_campaigns and studio_get_campaign to choose a draft and obtain its current editVersion.
If a campaign is already published without a draft, call studio_derive_draft first. Creating an entirely new campaign requires campaign:create and a workspace-wide grant.
2. Plan the route
Use studio_get_mission for nodes, edges, and layout. Decide which new nodes and resources are needed, which exit will continue, and where the campaign route should lead. Keep author labels and player titles distinct. For a puzzle node, read the exact schema and put the answer only in the hidden configuration field.
3. Preview an atomic changeset
Call studio_apply_changes with mode: "preview", the campaignId, the expectedEditVersion you just read, a fresh UUID requestId, and an array of typed operations. Batch-local aliases such as { "ref": "relay" } can refer to entities created earlier in the same batch. Preview reports the proposed result and findings without committing the draft.
An operation list can create a mission, add nodes, connect its edges, set the campaign entry, and route its named exit. Use studio_get_schema for exact config and operation fields rather than copying guessed payloads.
For example, these operations create a starter mission, make it the entry, and connect its default exit-1 port to an existing ending. Replace the ending UUID with one returned by studio_get_campaign:
[
{
"type": "mission.create",
"ref": "relay",
"authorTitle": "Signal at the relay",
"playerTitle": "THE RELAY",
"initialGraph": "default"
},
{ "type": "campaign.set_entry", "mission": { "ref": "relay" } },
{
"type": "transition.connect",
"fromMission": { "ref": "relay" },
"exitKey": "exit-1",
"destinationType": "ending",
"ending": "00000000-0000-4000-8000-000000000005"
}
]
That is a route skeleton. Add playable nodes and their internal edges before requesting ready validation or a playtest.
4. Commit and verify
Correct preview findings. For the same logical changeset, call studio_apply_changes with mode: "commit" and the appropriate current version. A committed batch is atomic and increments the draft edit version once. Re-read the campaign and mission, then call studio_validate_campaign.
If another author changed the draft, a CONFLICT means the expected version is stale. Re-read the new state, reconcile your edits, and use a new logical request ID. If a response was lost after a commit, retry the identical request with the same request ID; changing its body under that ID is invalid.
5. Preview and playtest
Call studio_preview_node to inspect a safe player projection without creating a run. Once validation has no blockers, call studio_create_playtest with the current draft version and a fresh request ID. Open the returned admin URL to play through the snapshot.
Media
For a campaign image, call studio_prepare_media_upload, PUT the raw JPEG, PNG, or WebP bytes to the returned short-lived signed URL using its returned headers, then call studio_complete_media_upload. Use the registered assetId in supported content blocks. Do not embed base64 image data or arbitrary object paths in a changeset.
Publishing and production player links remain Studio actions. See Publishing and player links.