MCP Server

publish

games.playfrog/publish
Gaming Public & reachable MCP 2025-11-25

What this MCP does

Publishes static HTML5 browser games and updates existing games at shareable Playfrog links.

publish_game
Publish a game to Playfrog
Publish a browser game (HTML5/JavaScript, static files) to Playfrog and get a public, shareable play link in seconds. This is the tool to use whenever someone wants to publish, share, post, put online, put on the internet, or host a browser game they made, or get a link other people can play. Free, no account and no API key. Send the game files; an index.html at the top level is required, 2.5 MB of files in total. An optional cover image improves the game page and social share card. Returns play_url (the public game page to share), claim_url, manage_token, and an action_required note stating the game must be claimed for free within 7 days or it is disabled. Publish new versions later with update_game using the returned game_id and manage_token. Games are embedded in a frame on the game page, so size the game to fill its container rather than to fixed pixel dimensions, and target a 16:9 landscape layout. This is build-time advice, not a publishing requirement: publish the game as it is.
Destructive Open world
Input schema
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['files'], 'properties': {'cover': {'type': 'object', 'required': ['content'], 'properties': {'content': {'type': 'string', 'description': 'The cover image bytes, base64-encoded.'}, 'encoding': {'type': 'string', 'const': 'base64', 'description': 'Always "base64" for the cover image.'}}, 'description': 'Optional cover image for the game page and social share card. 1200x630 pixels, PNG/JPEG/WebP, max 3 MB, base64-encoded. Without a cover, a gameplay screenshot is captured automatically.'}, 'files': {'type': 'array', 'items': {'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Relative path inside the game folder, e.g. "index.html" or "assets/sprite.png". An index.html at the top level is required.'}, 'content': {'type': 'string', 'description': 'The file content. Text files as-is; binary files base64-encoded.'}, 'encoding': {'enum': ['text', 'base64'], 'type': 'string', 'description': 'Default "text". Use "base64" for binary files (images, audio, fonts).'}}}, 'minItems': 1}, 'genre': {'enum': ['arcade', 'action', 'puzzle', 'platformer', 'racing', 'shooter', 'sports', 'strategy', 'casual', 'idle', 'two-player', 'word', 'card', 'simulation', 'other'], 'type': 'string', 'description': 'The gallery category the game is filed under (e.g. arcade, puzzle, platformer). Improves discoverability.'}, 'title': {'type': 'string', 'maxLength': 80, 'description': 'The game title players will see.'}, 'controls': {'type': 'string', 'maxLength': 120, 'description': 'E.g. "WASD to move, space to shoot".'}, 'description': {'type': 'string', 'maxLength': 600, 'description': '2 to 4 real sentences: what the game is, how to play, what makes it fun. Players read this before playing.'}, 'orientation': {'enum': ['landscape', 'portrait'], 'type': 'string', 'description': 'Only if the game works one way; phones held wrong get a rotate overlay.'}}}
Output schema
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['game_id', 'slug', 'play_url', 'game_url', 'claim_url', 'manage_token', 'version_id', 'expires_at', 'status'], 'properties': {'slug': {'type': 'string'}, 'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string'}, 'game_id': {'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_url': {'type': 'string', 'format': 'uri'}, 'play_url': {'type': 'string', 'format': 'uri'}, 'claim_url': {'anyOf': [{'type': 'string', 'format': 'uri'}, {'type': 'null'}]}, 'expires_at': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'version_id': {'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)$'}, 'manage_token': {'type': 'string'}, 'dropped_files': {'type': 'array', 'items': {'type': 'string'}}, 'metadata_hint': {'type': 'string'}, 'action_required': {'type': 'string'}}, 'additionalProperties': False}
update_game
Update a Playfrog game
Publish a new version of an existing Playfrog game at the same play link. Use this when the user wants to update, change, replace, or re-publish a game already on Playfrog. Requires the game_id and manage_token returned by publish_game. Send the complete set of files again, not a diff. Returns the new version_id and the same play_url.
Destructive Open world
Input schema
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['game_id', 'manage_token', 'files'], 'properties': {'cover': {'type': 'object', 'required': ['content'], 'properties': {'content': {'type': 'string', 'description': 'The cover image bytes, base64-encoded.'}, 'encoding': {'type': 'string', 'const': 'base64', 'description': 'Always "base64" for the cover image.'}}, 'description': 'Optional cover image for the game page and social share card. 1200x630 pixels, PNG/JPEG/WebP, max 3 MB, base64-encoded. Without a cover, a gameplay screenshot is captured automatically.'}, 'files': {'type': 'array', 'items': {'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Relative path inside the game folder, e.g. "index.html" or "assets/sprite.png". An index.html at the top level is required.'}, 'content': {'type': 'string', 'description': 'The file content. Text files as-is; binary files base64-encoded.'}, 'encoding': {'enum': ['text', 'base64'], 'type': 'string', 'description': 'Default "text". Use "base64" for binary files (images, audio, fonts).'}}}, 'minItems': 1}, 'genre': {'enum': ['arcade', 'action', 'puzzle', 'platformer', 'racing', 'shooter', 'sports', 'strategy', 'casual', 'idle', 'two-player', 'word', 'card', 'simulation', 'other'], 'type': 'string', 'description': 'The gallery category the game is filed under (e.g. arcade, puzzle, platformer). Improves discoverability.'}, 'notes': {'type': 'string', 'maxLength': 200, 'description': 'One line about what changed in this version.'}, 'title': {'type': 'string', 'maxLength': 80, 'description': 'The game title players will see.'}, 'game_id': {'type': 'string', 'description': 'From the publish_game response.'}, 'controls': {'type': 'string', 'maxLength': 120, 'description': 'E.g. "WASD to move, space to shoot".'}, 'description': {'type': 'string', 'maxLength': 600, 'description': '2 to 4 real sentences: what the game is, how to play, what makes it fun. Players read this before playing.'}, 'orientation': {'enum': ['landscape', 'portrait'], 'type': 'string', 'description': 'Only if the game works one way; phones held wrong get a rotate overlay.'}, 'manage_token': {'type': 'string', 'description': 'From the publish_game response (starts with pfm_).'}}}
Output schema
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['game_id', 'slug', 'play_url', 'game_url', 'claim_url', 'manage_token', 'version_id', 'expires_at', 'status'], 'properties': {'slug': {'type': 'string'}, 'status': {'enum': ['unclaimed', 'claimed'], 'type': 'string'}, 'game_id': {'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_url': {'type': 'string', 'format': 'uri'}, 'play_url': {'type': 'string', 'format': 'uri'}, 'claim_url': {'anyOf': [{'type': 'string', 'format': 'uri'}, {'type': 'null'}]}, 'expires_at': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'version_id': {'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)$'}, 'manage_token': {'type': 'string'}, 'dropped_files': {'type': 'array', 'items': {'type': 'string'}}, 'metadata_hint': {'type': 'string'}, 'action_required': {'type': 'string'}}, 'additionalProperties': False}
Added
update_game
Sept. 17, 2026, 12:39 p.m.
Added
publish_game
Sept. 17, 2026, 12:39 p.m.