Reference
MCP tools
Every tool the MiraDock MCP server lists, generated from the server's tool registry.
Overview
Creators connect an AI agent to MiraDock over the Model Context Protocol, then build, validate, and publish Games with the tools below. Start with get_game_sdk_spec, loop on validate_game, then publish_game. The getting started guide walks through the full sequence, and the connection guides show how to configure each client.
Endpoint
| Property | Value |
|---|---|
| URL | https://miradock.com/mcp |
| Transport | Streamable HTTP, stateless. Send JSON-RPC with POST; GET and DELETE return 405. |
| HTTPS | Required in production. Plain HTTP requests are rejected with forbidden. |
| Request size | 1 MiB per request, or 16 MiB for publish_game, update_game, and validate_game. Larger bodies return HTTP 413. |
| Discovery | /.well-known/mcp, /.well-known/oauth-protected-resource, /auth.md |
POST https://miradock.com/mcp
Authorization: Bearer miradock_mcp_<token>
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "validate_game",
"arguments": { "html": "<!doctype html>..." }
}
}Authentication
Every request needs an Authorization: Bearer credential. Requests without one return HTTP 401 with a WWW-Authenticate header that points to the protected resource metadata. MiraDock accepts three kinds of credential:
| Credential | Format | Can call |
|---|---|---|
| MCP write token | miradock_mcp_<64 hex characters> | Every tool. Create one at /app/mcp. |
| OAuth access token | Opaque token from the MiraDock OAuth flow | Read tools with mcp:read; write tools also need mcp:write. report_issue is not available to OAuth tokens. |
| MCP read token | miradock_mcp_<64 hex characters> | Read tools only (get_game_sdk_spec and validate_game). |
Game tools always act as the authenticated Creator. Arguments that try to name an actor (for example user_id or creator_id) are rejected with validation_error. See Write tokens and OAuth for how credentials are issued and revoked.
Rate limits
| Limit | Default |
|---|---|
| Requests per credential | 300 per minute, with a burst allowance of 30 |
| Requests per account | 300 per rolling minute across all of the account's credentials |
| Requests with an invalid credential | 60 per minute per IP address |
| Game HTML writes | 30 per hour and 200 per day per Creator, shared by publish_game and update_game. Metadata-only updates are not counted. |
| Game storage | 500 MiB of sanitized Game HTML per account, across current and archived versions |
| Anonymous sandbox quota | Until the sandbox is claimed, also at most 3 Games (all drafts), 25 stored items, and 10 MiB of content |
| Anonymous sandbox writes | 60 per minute per unclaimed sandbox token |
Request limits return a JSON-RPC error with HTTP 200, code -32029, and error.data.code set to rate_limited, with retry_after_seconds or reset_at. Tool limits, such as the Game HTML write budget, return a tool error instead (see below).
Tools
18 tools are listed by tools/list. Game tools that change or read a Game identify it by gameId or slug and only work for the Game's Creator.
- get_game_sdk_spec
- validate_game
- publish_game
- update_game
- set_game_leaderboards
- set_game_skus
- set_game_monetization
- set_game_image
- get_game
- get_game_stats
- get_game_reports
- update_game_report
- publish_staged
- discard_staged
- set_game_access
- add_game_member
- remove_game_member
- report_issue
get_game_sdk_spec
Get Game SDK spec
Call this first to build a MiraDock game. Returns the complete Game SDK specification as Markdown text, including the minimal compliant HTML in section 12. No arguments; read credentials suffice. No game ownership, validation pass, or payout onboarding is required.
| Access | Error codes |
|---|---|
| Any MiraDock credential (read token, write token, or OAuth) | validation_error, internal |
No arguments.
The same text is published at /docs/game-sdk and /llms-full.txt.
Input JSON Schema
{
"type": "object",
"properties": {},
"$schema": "http://json-schema.org/draft-07/schema#"
}validate_game
Validate Game
Check one HTML file against the Game SDK without saving or publishing. Read the spec first, then repeat validate_game and fix errors until ok is true before publishing or updating. Returns { ok, errors: [{ code, message, line? }], warnings: [...], info: [...] }; warnings do not block publication and info holds optional hints such as snapshot_missing. Read credentials suffice; no existing game, ownership, prior validation pass, or payout onboarding is required. Static validation does not replace browser testing.
| Access | Error codes |
|---|---|
| Any MiraDock credential (read token, write token, or OAuth) | validation_error, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
html | string (max 4194304 chars) | yes |
Game SDK problems are returned in the result ({ ok: false, errors }) rather than as a tool error. A Game must be at most 2 MiB after sanitization.
Input JSON Schema
{
"type": "object",
"properties": {
"html": {
"type": "string",
"maxLength": 4194304
}
},
"required": [
"html"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}publish_game
Publish Game
Create a game owned by the authenticated creator from HTML and metadata. Requires a write token or OAuth mcp:write and HTML that passes validate_game; the server revalidates and rejects errors. Creates a draft unless publish is true; use a draft for browser testing and configuration. No payout onboarding or subscription is required to publish. Claimed accounts share 30 HTML writes per hour and 200 per day across Games, with 500 MiB of current and archived sanitized HTML storage. Errors name the limit and reset time or storage recovery steps. Returns { gameId, slug, status, playUrl, validation }, with an absolute play URL. Anonymous sandbox tokens may create at most 3 drafts within their sandbox size quota; publish: true requires claiming at /agent/auth/claim.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal, page_exists, storage_limit_exceeded |
| Argument | Type | Required | Description |
|---|---|---|---|
title | string (min 1, max 200 chars) | yes | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
description | string (max 5000 chars) | null | no | |
genreTags | string (min 1, max 64 chars)[] | no | |
coverImageUrl | string (uri) | null | no | |
orientation | "any" | "landscape" | "portrait" | no | |
minPlayers | integer (>= 1, <= 1000) | no | |
maxPlayers | integer (>= 1, <= 1000) | no | |
html | string (max 4194304 chars) | yes | |
publish | boolean | no |
page_exists means the slug is taken. rate_limited includes the reset time for the 30 per hour / 200 per day HTML write budget.
Input JSON Schema
{
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"description": {
"anyOf": [
{
"type": "string",
"maxLength": 5000
},
{
"type": "null"
}
]
},
"genreTags": {
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 64
}
},
"coverImageUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"orientation": {
"type": "string",
"enum": [
"any",
"landscape",
"portrait"
]
},
"minPlayers": {
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"maxPlayers": {
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"html": {
"type": "string",
"maxLength": 4194304
},
"publish": {
"type": "boolean"
}
},
"required": [
"title",
"html"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}update_game
Update Game
Update an existing game's HTML, metadata, or status. Owner only; requires a write token or OAuth mcp:write and a gameId or slug. Supplied or stored HTML must pass validation and is revalidated on every update; validate_game and fix changes first. HTML updates retain previous versions without a version-count cap. Claimed accounts share 30 HTML writes per hour and 200 per day with publish_game, and 500 MiB storage across current and archived versions. Metadata-only changes do not consume that write budget. Use gameId to rename the slug. Set status to draft, published, or unlisted; never combine status with publish or change suspended. For a live Game, pass stage: true: the HTML and metadata change is saved as the staged version, playable only by you at playUrl?version=staged, until publish_staged makes it live (discard_staged drops it); staged updates cannot change status, publish or slug. Without stage the change is live immediately. When MiraDock publish review is on, a first publish and title or description changes to a live Game wait for admin approval and the result includes review. No payout onboarding is required. Returns { gameId, slug, status, playUrl, validation, staged?, review? }. Anonymous sandbox updates must stay draft; published or unlisted requires claiming at /agent/auth/claim.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal, page_exists, storage_limit_exceeded |
| Argument | Type | Required | Description |
|---|---|---|---|
title | string (min 1, max 200 chars) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
description | string (max 5000 chars) | null | no | |
genreTags | string (min 1, max 64 chars)[] | no | |
coverImageUrl | string (uri) | null | no | |
orientation | "any" | "landscape" | "portrait" | no | |
minPlayers | integer (>= 1, <= 1000) | no | |
maxPlayers | integer (>= 1, <= 1000) | no | |
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
html | string (max 4194304 chars) | no | |
publish | boolean | no | |
status | "draft" | "published" | "unlisted" | no | |
stage | boolean | no | Stage the change instead of making it live: only the owner can preview it until publish_staged. Recommended for updates to a live Game. |
Use either publish or status, not both. Status transitions are draft, published and unlisted; suspended cannot be set or cleared by a Creator. stage: true saves a staged version instead of changing the live Game; it cannot be combined with status, publish or slug.
Input JSON Schema
{
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"description": {
"anyOf": [
{
"type": "string",
"maxLength": 5000
},
{
"type": "null"
}
]
},
"genreTags": {
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 64
}
},
"coverImageUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"orientation": {
"type": "string",
"enum": [
"any",
"landscape",
"portrait"
]
},
"minPlayers": {
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"maxPlayers": {
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"html": {
"type": "string",
"maxLength": 4194304
},
"publish": {
"type": "boolean"
},
"status": {
"type": "string",
"enum": [
"draft",
"published",
"unlisted"
]
},
"stage": {
"description": "Stage the change instead of making it live: only the owner can preview it until publish_staged. Recommended for updates to a live Game.",
"type": "boolean"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}set_game_leaderboards
Set Game leaderboards
Replace the complete leaderboard definitions for an existing game identified by gameId or slug. Owner only; requires a write token or OAuth mcp:write. No new HTML validation pass or payout onboarding is required. Send boards: [] to remove all boards. Kept boards retain entries; removed boards lose entries. Returns { gameId, boards, warnings }, including removed board IDs and entry counts when data is deleted. Anonymous sandbox tokens must claim at /agent/auth/claim before calling this tool.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
boards | object[] | yes |
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"boards": {
"maxItems": 64,
"type": "array",
"items": {
"type": "object",
"properties": {
"boardId": {
"type": "string",
"pattern": "^[a-z0-9_-]{1,64}$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"sort": {
"type": "string",
"enum": [
"asc",
"desc"
]
},
"period": {
"type": "string",
"enum": [
"alltime",
"weekly",
"daily"
]
}
},
"required": [
"boardId",
"name",
"sort",
"period"
]
}
}
},
"required": [
"boards"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}set_game_skus
Set Game SKUs
Replace the complete store SKU definitions and USD-cent prices for an existing game identified by gameId or slug. Owner only; requires a write token or OAuth mcp:write. Definitions can be saved without a new HTML validation pass or payout onboarding, even when payments are disabled. Enabling purchases separately requires payout onboarding and set_game_monetization. Removed SKUs become inactive; existing entitlements are kept. Use set_game_monetization for tips. Never place prices in game HTML. Returns { gameId, skus } with active database rows and stable IDs. Anonymous sandbox tokens must claim at /agent/auth/claim before calling this tool.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
skus | object[] | yes |
Prices are integers in USD cents. See Store and tips for how purchases work.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"skus": {
"maxItems": 64,
"type": "array",
"items": {
"type": "object",
"properties": {
"sku": {
"type": "string",
"pattern": "^[a-z0-9_-]{1,64}$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"description": {
"type": "string",
"maxLength": 5000
},
"kind": {
"type": "string",
"enum": [
"item",
"access",
"consumable",
"donation"
]
},
"priceCents": {
"type": "integer",
"minimum": 50,
"maximum": 2147483647
},
"sortOrder": {
"type": "integer",
"minimum": -2147483648,
"maximum": 2147483647
}
},
"required": [
"sku",
"name",
"kind",
"priceCents"
],
"additionalProperties": false
}
}
},
"required": [
"skus"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}set_game_monetization
Set Game monetization
Enable or disable tips (donations: true or false) and optionally the shop for an existing game identified by gameId or slug. Owner only; requires a write token or OAuth mcp:write. Enabling either requires completed payout onboarding with an active payout account at /app/earnings and platform payments enabled. Disabling both requires no payout onboarding. No new HTML validation pass is required. Configure paid SKUs with set_game_skus first; tip supporter SKUs are managed automatically. Returns { gameId, donations, shop }; the donations field is the tips setting. Reports validation_error if payments or onboarding block enabling. Anonymous sandbox tokens must claim at /agent/auth/claim before calling this tool.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
donations | boolean | yes | Turns tips on or off for this Game. Tips are for the Game being played. |
shop | boolean | no |
validation_error is returned when payout onboarding is incomplete or when the Store and tips are not open yet; in that case the message says SKUs and settings are kept for launch.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"donations": {
"type": "boolean",
"description": "Turns tips on or off for this Game. Tips are for the Game being played."
},
"shop": {
"type": "boolean"
}
},
"required": [
"donations"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}set_game_image
Set Game image
Upload the card and share image for an existing game identified by gameId or slug. Owner only; requires a write token or OAuth mcp:write. Pass imageBase64 (raw base64, no data: prefix) and mimeType image/png, image/jpeg or image/webp; SVG is not accepted. Input is at most 5 MB and at least 320x180 pixels. The server re-encodes it to WebP at 1280x720 and 640x360 (centered 16:9 crop) and strips all metadata. An uploaded image always replaces a MiraDock.snapshot() image, and snapshots never replace an upload. Returns { gameId, imageSource, imageUrl, thumbnailUrl }. Anonymous sandbox tokens must claim at /agent/auth/claim before calling this tool.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
imageBase64 | string (max 6990511 chars, pattern ^[A-Za-z0-9+/]+={0,2}$) | yes | |
mimeType | "image/png" | "image/jpeg" | "image/webp" | yes |
validation_error is returned for SVG or other types, input over 5 MB, images smaller than 320x180, or data that does not decode.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"imageBase64": {
"type": "string",
"maxLength": 6990511,
"pattern": "^[A-Za-z0-9+/]+={0,2}$"
},
"mimeType": {
"type": "string",
"enum": [
"image/png",
"image/jpeg",
"image/webp"
]
}
},
"required": [
"imageBase64",
"mimeType"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}get_game
Get Game
Read the current settings of a Game you own, identified by gameId or slug. Requires mcp:read. Read a Game before update_game, set_game_leaderboards, set_game_skus, or set_game_monetization so a change starts from what is stored. Returns { gameId, slug, title, description, genreTags, status, coverImageUrl, imageSource, imageUrl (1280), thumbnailUrl (640), orientation, minPlayers, maxPlayers, sdkVersion, leaderboards, skus, monetization: { donations, shop, economyEnabled }, currentVersionId, versionCount, playUrl, staged (null or { hasHtml, metadata, updatedAt, previewUrl }), accessMode, memberCount, review (null or { status, reason, pendingChanges, requestedAt }) }. versionCount includes the current version; currentVersionId is the version ID get_game_reports shows for the current HTML, or null until a report records it. leaderboards and skus use the shapes set_game_leaderboards and set_game_skus accept.
| Access | Error codes |
|---|---|
| Any MiraDock credential (read token, write token, or OAuth) | unauthorized, permission_denied, not_found, validation_error, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no |
Read a Game before changing it. leaderboards and skus come back in the shapes set_game_leaderboards and set_game_skus accept.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}get_game_stats
Get Game stats
Read private creator analytics for an existing game identified by gameId or slug. Owner only; requires a write token or OAuth mcp:write even though this tool is read-only. No new HTML validation pass or payout onboarding is required. Returns { playCount, uniquePlayers, leaderboards: [{ boardId, entries }], revenue: null, metrics }. uniquePlayers counts signed-in players; metrics includes seven-day plays, unique players including guests, duration, return rate, purchase/donation counts, and lifetime likes. Leaderboard entry counts cover all periods; revenue totals are not yet available. Anonymous sandbox tokens must claim at /agent/auth/claim before calling this tool.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no |
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}get_game_reports
Get Game reports
List Player reports for a Game you own, identified by gameId or slug. Requires mcp:read. Returns category, status, description, version played, technical details, and only 'a Player' or 'a guest' for the reporter. Use before updating a Game to address open bugs.
| Access | Error codes |
|---|---|
| Any MiraDock credential (read token, write token, or OAuth) | unauthorized, permission_denied, not_found, validation_error, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
status | "open" | "acknowledged" | "resolved" | "dismissed" | no | |
limit | integer (>= 1, <= 100) | no |
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"status": {
"type": "string",
"enum": [
"open",
"acknowledged",
"resolved",
"dismissed"
]
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}update_game_report
Update Game report
Acknowledge, resolve, or dismiss a report for a Game you own. Requires mcp:write. A resolution may include creatorNote, shown to the signed-in reporter. Resolve open bugs with a note after publishing the fix.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
reportId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | yes | |
status | "acknowledged" | "resolved" | "dismissed" | yes | |
creatorNote | string (max 2000 chars) | no |
Input JSON Schema
{
"type": "object",
"properties": {
"reportId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"status": {
"type": "string",
"enum": [
"acknowledged",
"resolved",
"dismissed"
]
},
"creatorNote": {
"type": "string",
"maxLength": 2000
}
},
"required": [
"reportId",
"status"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}publish_staged
Publish staged version
Make a Game's staged version (from update_game with stage: true) live, identified by gameId or slug. Owner only; requires mcp:write. The previous live HTML is archived as a version. Players only ever get the live version. When MiraDock publish review is on, staged title or description changes to a live Game wait for admin approval; the HTML goes live immediately. Returns { gameId, slug, status, playUrl, published, review? }.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no |
not_found when the Game has no staged version. Publishing archives the previous live HTML; restore an archived version from the Game page, which stages it again.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}discard_staged
Discard staged version
Delete a Game's staged version without publishing it, identified by gameId or slug. Owner only; requires mcp:write. The live version is unchanged. Returns { gameId, slug, discarded }.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no |
not_found when the Game has no staged version.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}set_game_access
Set Game access
Choose who can play a Game you own: mode everyone (default; anyone the status allows) or members (only signed-in members you add, plus you and MiraDock admins). Members-only Games are hidden from discovery, search, the sitemap, the homepage and your public profile, and multiplayer rooms reject non-members. Owner only; requires mcp:write. Returns { gameId, slug, accessMode }.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
mode | "everyone" | "members" | yes | everyone: anyone the status allows. members: only signed-in members you add. |
Members mode keeps the status: a published members-only Game is still hidden from every public listing and needs sign-in and membership to play.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"mode": {
"type": "string",
"enum": [
"everyone",
"members"
],
"description": "everyone: anyone the status allows. members: only signed-in members you add."
}
},
"required": [
"mode"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}add_game_member
Add Game member
Give a MiraDock member access to a Game you own in members mode, by username (profile handle). Owner only; requires mcp:write. Members see the Game under Shared with me in Play mode. Returns { gameId, status: added, username, displayName }; not_found when no member has that username.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
username | string (min 1, max 64 chars) | yes | The member's MiraDock username (profile handle), with or without @. |
not_found when no member has that username. Adding yourself is a validation_error.
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"username": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"description": "The member's MiraDock username (profile handle), with or without @."
}
},
"required": [
"username"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}remove_game_member
Remove Game member
Remove a member's access to a Game you own, by username. Owner only; requires mcp:write. Returns { gameId, removed }.
| Access | Error codes |
|---|---|
| Write token, or OAuth token with mcp:write | unauthorized, permission_denied, forbidden, not_found, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
gameId | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | |
slug | string (pattern ^[a-z0-9-]{3,64}$) | no | |
username | string (min 1, max 64 chars) | yes | The member's MiraDock username (profile handle), with or without @. |
Input JSON Schema
{
"type": "object",
"properties": {
"gameId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9-]{3,64}$"
},
"username": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"description": "The member's MiraDock username (profile handle), with or without @."
}
},
"required": [
"username"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}report_issue
Report an issue
Report a bug or unexpected behavior to MiraDock. Requires a MiraDock MCP write token; OAuth access tokens are rejected with permission_denied. title is 1-200 characters and body is 1-8000 characters; secrets in context are redacted before storage. Optional links (game_id and legacy content identifiers) are attached only when the caller can read them. Reports are rate limited per token; rate_limited includes retry_after_seconds. Returns { bug_report_id }.
| Access | Error codes |
|---|---|
| MiraDock MCP write token only | unauthorized, permission_denied, bad_request, validation_error, rate_limited, internal |
| Argument | Type | Required | Description |
|---|---|---|---|
category | "bug" | "unexpected_behavior" | "tool_error" | "permission" | "content" | "other" | yes | Issue category. |
title | string (min 1, max 200 chars) | yes | Short issue title (1-200 characters). |
body | string (min 1, max 8000 chars) | yes | Issue description and reproduction details (1-8000 characters). |
severity | "low" | "medium" | "high" | "critical" | no | Optional severity. |
context | object | no | Optional reproduction context. Secrets are redacted before storage. |
bucket | string | no | Optional legacy content collection slug or id to link, if readable. |
artifact_id | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | Optional legacy content item id to link, if readable. |
game_id | string (uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) | no | Optional Game id to link, if readable. |
Optional links are attached only when the caller can read the linked item.
Input JSON Schema
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": [
"bug",
"unexpected_behavior",
"tool_error",
"permission",
"content",
"other"
],
"description": "Issue category."
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Short issue title (1-200 characters)."
},
"body": {
"type": "string",
"minLength": 1,
"maxLength": 8000,
"description": "Issue description and reproduction details (1-8000 characters)."
},
"severity": {
"description": "Optional severity.",
"type": "string",
"enum": [
"low",
"medium",
"high",
"critical"
]
},
"context": {
"description": "Optional reproduction context. Secrets are redacted before storage.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"bucket": {
"description": "Optional legacy content collection slug or id to link, if readable.",
"type": "string"
},
"artifact_id": {
"description": "Optional legacy content item id to link, if readable.",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"game_id": {
"description": "Optional Game id to link, if readable.",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"category",
"title",
"body"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}Errors
Authentication, scope, HTTPS, and request rate problems are returned as JSON-RPC errors whose error.data.code is one of the codes below. Problems inside a tool are returned as a tool result with isError: true and the same code in structuredContent.code, plus any details such as limits or reset times.
{
"isError": true,
"content": [{ "type": "text", "text": "Game HTML write limit reached: ..." }],
"structuredContent": {
"code": "rate_limited",
"error_code": "rate_limited",
"retry_after_seconds": 1260,
"limit": 30,
"window": "hour",
"reset_at": "2026-09-24T18:00:00Z"
}
}| Code | JSON-RPC code | Meaning |
|---|---|---|
unauthorized | -32001 | Missing, invalid, expired, or revoked bearer credential, or a suspended account. Returned as HTTP 401 with a WWW-Authenticate challenge that points to /.well-known/oauth-protected-resource. |
forbidden | -32003 | HTTPS is required in production, or an unclaimed anonymous sandbox token tried an operation that requires claiming the sandbox first. |
permission_denied | -32003 | The credential cannot write (read token, or OAuth token without mcp:write), the caller does not own the Game, or the tool requires a MiraDock MCP write token. |
not_found | -32004 | The Game identified by gameId or slug does not exist. |
page_exists | -32602 | Another Game already uses the requested slug. |
validation_error | -32602 | Arguments failed validation: Game SDK validation errors, invalid status transitions, payout onboarding or platform payments required, an anonymous sandbox quota, or an argument that tries to set an actor identity field. |
storage_limit_exceeded | -32030 | The write would take the account over 500 MiB of stored Game HTML across current and archived versions. |
rate_limited | -32029 | A request, write, or report limit was reached. The error includes retry_after_seconds or reset_at when known. |
bad_request | -32600 | The request was malformed, for example an invalid report payload. |
internal | -32603 | Unexpected server error. Retry later, and use report_issue if it persists. |
Legacy tools
Older tools remain callable for existing integrations but are not listed by tools/list. See the legacy tools page.