MCPity
MCPity Studio

Overview

MCPity Studio connects Claude AI to your game engine or 3D tool in real time. You describe what you want in plain English, Claude generates the code, and the MCPity plugin pushes it directly into your running engine instance. No copy paste required.

🎮

Unity

C#

⚡

Unreal

C++

🟠

Blender

Python

How it works

  1. Install the MCPity plugin in your engine
  2. Enter your Claude API key in the web app
  3. Type a prompt and Claude generates engine specific code
  4. The plugin receives the code and executes it live in the engine

Code your game

Every plan can build a game by hand in the Web Engine, with no AI and no install. Open Studio, pick "Code it yourself" (or "Start from a blank game" in the Code tab), and edit the code while the preview reloads on every save. Having MCPity build it for you needs a paid plan.

Files and the entry file

  • The game runs from src/index.ts. A blank game starts it as an empty lit stage with a camera and a render loop.
  • Write TypeScript or plain JavaScript. The browser bundles it on every save.
  • Add more files under src/ and import them with relative paths (import { spawn } from "./enemies").
  • The only packages you can import by name are three (and its three/addons/), @babylonjs/*, cannon-es and @dimforge/rapier3d-compat.

Three.js or Babylon.js

There is no switch to flip: the preview reads your imports. A game that imports from @babylonjs/core runs on Babylon.js, and anything else runs on Three.js.

typescript
import * as THREE from "three";

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 500);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

// Tell MCPity where the player is, for the heatmap and Play together.
const player = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshStandardMaterial());
scene.add(player);
(window as any).MCPityPlayer = player;

Runtime helpers

These are on window. The first three are always there in the Studio preview and on your /play link. The rest arrive when you add their free No-AI pattern from Build Steps or the Editor tab panels.

MCPityAssetsalways there

Models, textures and sounds wired into the game's asset-manifest.json, by slot name. getModel returns null for an empty slot, so `MCPityAssets.getModel("hero") ?? makeMyOwnHero()` always works.

  • MCPityAssets.ready: Promise
  • MCPityAssets.getModel(slot): THREE.Object3D | null
  • MCPityAssets.getClips(slot): { name, role, loop }[]
  • MCPityAssets.getTexture(slot): string | null
  • MCPityAssets.getAudio(slot): string | null
  • MCPityAssets.playAudio(slot, { loop?, volume? }): HTMLAudioElement | null
  • MCPityAssets.stopAudio(slot)
MCPityAgentalways there

Debug commands a playtest or the trailer maker may call to reach a moment. The name is snake_case, up to 40 characters.

  • MCPityAgent.command(name, description, fn(args))
MCPityPlayEventsalways there

Tells MCPity where players get to, fail and quit, which feeds "Where players quit" and the heatmap. pos is { x, y, z }.

  • MCPityPlayEvents.levelEnter(index, name)
  • MCPityPlayEvents.levelComplete(index, name)
  • MCPityPlayEvents.levelFail(index, name, pos)
  • MCPityPlayEvents.waveStart(wave)
  • MCPityPlayEvents.waveClear(wave)
  • MCPityPlayEvents.gameOver(pos)
  • MCPityPlayEvents.playerDied(pos, index, name)
  • MCPityPlayEvents.playerAt(pos)
MCPityInputpattern runtime.control-remap-web

Named actions bound to keys, gamepads and on-screen touch controls. The Editor tab's Controls panel adds it.

  • MCPityInput.action(name): boolean
  • MCPityInput.actions(): { [action]: string[] }
  • MCPityInput.vector(): { x, y }
MCPityLevelspattern tools.gameplay.level-system-web

Ordered levels. The live editor's level bar, level takes and per-level heatmaps read it.

  • MCPityLevels.define(name, { onEnter, onExit, goal })
  • MCPityLevels.start()
  • MCPityLevels.complete()
  • MCPityLevels.fail()
  • MCPityLevels.next()
  • MCPityLevels.goto(indexOrName)
  • MCPityLevels.restart()
  • MCPityLevels.count(): number
  • MCPityLevels.names(): string[]
  • MCPityLevels.currentIndex(): number
  • MCPityLevels.currentName(): string | null
MCPitySavepattern save.cloud-save-web

One save document per player, kept in the browser and synced to the cloud.

  • MCPitySave.ready: Promise
  • MCPitySave.set(key, value)
  • MCPitySave.get(key, fallback)
  • MCPitySave.all(): object
  • MCPitySave.replace(object)
  • MCPitySave.flush(): Promise<{ ok }>
  • MCPitySave.on("loaded" | "synced" | "conflict", fn)
MCPityLeaderboardpattern tools.leaderboard.leaderboard-web

Submit scores and read the boards you set up in the Progression panel.

  • MCPityLeaderboard.submit(boardId, score, options?)
  • MCPityLeaderboard.top(boardId, n?, options?)
  • MCPityLeaderboard.myRank(boardId, options?)
  • MCPityLeaderboard.nearMe(boardId, radius?, options?)
MCPityLiveOpspattern tools.net.liveops-web

Values, events and store prices you publish from the Ship tab's Live ops, read without a rebuild.

  • MCPityLiveOps.ready: boolean
  • MCPityLiveOps.get(key, fallback)
  • MCPityLiveOps.isActive(eventKey): boolean
  • MCPityLiveOps.price(sku)
  • MCPityLiveOps.purchased(sku)
  • MCPityLiveOps.on("change", fn)
MCPityUnlockspattern tools.net.newfans-unlocks-web

Levels and items a fan's NewFans tap card opens. Off NewFans it is empty and never throws.

  • MCPityUnlocks.has(key): Promise<boolean>
  • MCPityUnlocks.list(): Promise<string[]>

Set window.MCPityPlayer to your player object (a Three.js object, a Babylon.js node, or anything with a position). The heatmap reads where players died or stopped from it, and Play together draws teammates from it.

Edits made in the live editor

When you move, recolour or hide an object in the Editor tab, the change is saved into your code as a block between MCPITY_TWEAKS_BEGIN and MCPITY_TWEAKS_END. Leave that block in place: it applies your edits wherever the game runs.

From your own editor

On a paid plan, the MCPity CLI streams files you edit locally into a Studio project's live preview. Coding in the Studio Code tab stays free.

bash
npx @mcpity/cli auth login
npx @mcpity/cli push --watch --studio <project id>

Blender Add-on Setup

There is no automated installer. The add-on must be installed manually as a .zip file via Edit → Preferences → Add-ons. Do not unzip the file.

Step 1: Download

Download the correct file for your Blender version from the Setup Wizard inside the app, or directly below:

FileBlender VersionNotes
mcpity_blender_addon_4_2.zip4.2+Extensions system (recommended)
mcpity_blender_addon_legacy.zip3.6, 4.1Classic Add-ons installer

Step 2: Install

Blender 4.2+ (Extensions system)

  1. 1Open Blender
  2. 2Go to Edit → Preferences → Add-ons
  3. 3Click Install from Disk… (top-right of the Add-ons panel)
  4. 4Select mcpity_blender_addon_4_2.zip
  5. 5Click Install from Disk to confirm
  6. 6Find MCPity in the list and enable the checkbox next to it
In Blender 4.2+ add-ons installed this way appear under the User filter tab in Preferences.

Blender 3.6, 4.1 (Legacy)

  1. 1Open Blender
  2. 2Go to Edit → Preferences → Add-ons
  3. 3Click Install… (top-right of the Add-ons panel)
  4. 4Select mcpity_blender_addon_legacy.zip
  5. 5Click Install Add-on to confirm
  6. 6Find MCPity in the list and enable the checkbox next to it

Step 3: Configure

Expand the add-on's preferences by clicking the arrow next to MCPity in the Add-ons list. Set these two fields:

FieldValue
MCPity Web URLThe URL of this web app. Copy from the Setup Wizard or your browser address bar. Use only the origin with no trailing path, e.g.
https://your-app.tempo.build
Auth TokenFrom the Setup Wizard → Generate Token tab. Tokens are shown once only.
You will need to re-enter these values if you use the add-on on a different machine or after reinstalling Blender.

Step 4: Connect

  1. 1In Blender, open the 3D Viewport
  2. 2Press N to open the N-Panel (right sidebar)
  3. 3Click the MCPity tab
  4. 4Click Connect
  5. 5The status indicator turns green
Switch back to the web app. The status bar at the bottom should show Connected with a green breathing indicator.

Unity Plugin Setup

  1. 1Open Window → Package Manager in Unity
  2. 2Click + → Add package from git URL
  3. 3Paste:
    https://github.com/mcpity/unity-plugin.git
  4. 4Wait for the import to complete
  5. 5Go to Window → MCPity to open the plugin panel
  6. 6Paste your Auth Token in Plugin Settings

Troubleshooting

"Install from Disk" button is missing

Make sure you are on Blender 4.2+. On 4.1 and older, use the Install… button instead.

Add-on does not appear in the list after install

  • Check that the .zip matches your Blender version
  • Search for "MCP" in the Add-ons search bar
  • Try disabling and re-enabling the add-on

Status bar shows "Disconnected" after clicking Connect

  • Verify MCPity Web URL in Blender Preferences is exactly the app URL with no trailing slash
  • Check that your Auth Token is correct. Regenerate from the Setup Wizard if needed
  • Make sure the web app browser tab is open and not sleeping

Token is invalid or expired

Go to the Setup Wizard → Generate Token to create a new one. Tokens are single-use and engine-specific.

"Install Add-on" button grayed out (legacy Blender)

Ensure you selected the .zip file, not an extracted folder. The .zip must be the original unmodified download.

SaaS Animation API

The MCPity Animation API lets you integrate AI-powered animation code generation directly into your SaaS product. Your application sends prompts and receives engine-specific code (C# or Python) that can be pushed to a live engine via the MCPity plugin.

🔑

API Key Auth

x-mcpity-api-key header

⚡

BYOK Support

Bring your own Claude key

🔗

Webhooks

Async callbacks via HMAC

Base URL

https://YOUR_PROJECT.supabase.co/functions/v1/supabase-functions-animation-api

Authentication

All API requests must include your MCPity API key in the x-mcpity-api-key header. Optionally, include your Claude API key in x-claude-api-key for BYOK (Bring Your Own Key), available at Growth tier and above.

http
POST /functions/v1/supabase-functions-animation-api?action=generate
x-mcpity-api-key: mcp_live_abc123...
x-claude-api-key: sk-ant-...           ← optional BYOK
Content-Type: application/json
Key prefixTierRate limit
mcp_test_...Sandbox / Free10 req/min
mcp_live_...Paid (Startup+)100 req/min
mcp_ent_...Enterprise1 000 req/min
Create and manage your API keys in the Developer Dashboard.

POST /generate: Generate animation code

POST?action=generate

Generate engine-specific animation code from a natural language prompt. Supports synchronous streaming and asynchronous mode with webhook delivery.

Request body

FieldTypeReq.Description
promptstringreqNatural language description of the desired animation.
enginestringopt"unity" | "blender". Defaults to "unity".
contextstringoptOptional scene/project context to inject into the prompt.
webhook_urlstringoptTriggers async mode. MCPity POSTs the result to this URL on completion.
asyncbooleanoptForce async mode even without a webhook URL.
json
// Sync request
{
  "prompt": "Create a smooth walk cycle for a humanoid character",
  "engine": "unity"
}

// Sync response
{
  "generation_id": "gen_abc123",
  "engine": "unity",
  "animation_type": "skeletal",
  "files": [
    {
      "filename": "WalkCycleController.cs",
      "language": "csharp",
      "content": "using UnityEngine;\npublic class WalkCycleController : MonoBehaviour { ... }"
    }
  ],
  "preview_data": { "format": "threejs_compatible", "scene": { ... } },
  "metadata": {
    "tokens_input": 312,
    "tokens_output": 748,
    "generation_time_ms": 2340,
    "model": "claude-3-5-sonnet-20241022"
  }
}
json
// Async request
{
  "prompt": "Create an explosion particle system",
  "engine": "unity",
  "async": true,
  "webhook_url": "https://your-app.com/webhooks/mcpity"
}

// Async response (immediate)
{
  "generation_id": "gen_xyz789",
  "status": "pending",
  "message": "Generation queued. Poll /status or wait for webhook."
}

POST /refine: Refine a previous generation

POST?action=refine

Iterate on a previous generation by passing a refinement instruction. The original code and context are automatically included so the AI understands what to change.

Request body

FieldTypeReq.Description
generation_idstringreqID of the generation to refine.
refinement_promptstringreqInstruction describing the desired change.
enginestringoptOverride engine (defaults to parent generation engine).
json
// Request
{
  "generation_id": "gen_abc123",
  "refinement_prompt": "Make the arm swing wider and add a subtle head bob"
}

// Response: same shape as /generate, plus:
{
  "generation_id": "gen_def456",
  "parent_generation_id": "gen_abc123",
  "engine": "unity",
  "files": [ ... ]
}

GET /templates: List animation templates

GET?action=templates

Returns a catalogue of optimised prompt templates for common animation tasks. Use these as a starting point to improve generation quality.

Query params

FieldTypeReq.Description
enginestringopt"unity" | "blender"
categorystringopte.g. "character", "camera", "fx", "ui"
animation_typestringopt"skeletal" | "transform" | "camera" | "material" | "particle" | "ui" | "procedural"
json
// GET ?action=templates&engine=unity&category=character

{
  "templates": [
    {
      "id": "walk-cycle-unity",
      "name": "Humanoid Walk Cycle",
      "description": "Smooth locomotion animation for Unity Animator",
      "engines": ["unity"],
      "animation_type": "skeletal",
      "category": "character",
      "difficulty": "beginner",
      "tags": ["locomotion", "humanoid", "animator"],
      "prompt_template": "Create a walk cycle animation for a {character_type} character ...",
      "parameters": [
        { "key": "character_type", "label": "Character Type", "default": "humanoid", "description": "Type of character rig" }
      ]
    }
  ],
  "count": 1,
  "filters": { "engine": "unity", "category": "character", "animation_type": null }
}

POST /preview: Three.js preview data

POST?action=preview

Returns a Three.js-compatible scene JSON for a generation or prompt. Useful for rendering a visual preview of the animation in a browser without running a full game engine.

Request body

FieldTypeReq.Description
generation_idstringoptExisting generation to generate preview from.
animation_typestringoptHint the type of animation to preview.
enginestringoptTarget engine context.
promptstringoptGenerate preview from a prompt (no prior generation needed).
json
// Response
{
  "preview_data": {
    "format": "threejs_compatible",
    "version": "1.0",
    "engine": "unity",
    "animation_type": "transform",
    "scene": {
      "objects": [ { "type": "mesh", "geometry": "BoxGeometry", ... } ],
      "animations": [ { "name": "walk", "duration": 1.0, "tracks": [ ... ] } ],
      "camera": { "position": [0, 2, 5], "target": [0, 1, 0] }
    }
  },
  "format": "threejs_compatible"
}

GET /status: Poll async generation

GET?action=status&generation_id={id}

Check the status of an async generation. Poll this endpoint until status is 'completed' or 'failed'. The completed response includes the same files and metadata as a sync generation.

Query params

FieldTypeReq.Description
generation_idstringreqID from an async /generate call.
json
// Pending
{ "generation_id": "gen_xyz789", "status": "pending", "engine": "unity" }

// Generating
{ "generation_id": "gen_xyz789", "status": "generating", "engine": "unity" }

// Completed
{
  "generation_id": "gen_xyz789",
  "status": "completed",
  "engine": "unity",
  "completed_at": "2025-03-01T12:00:05Z",
  "files": [ ... ],
  "preview_data": { ... },
  "metadata": { ... }
}

// Failed
{
  "generation_id": "gen_xyz789",
  "status": "failed",
  "error_message": "Claude API error: rate limit exceeded"
}

Webhooks

When a webhook_url is provided on a generate request, MCPity POSTs the completed payload to your URL. Requests are signed with HMAC-SHA256 so you can verify they genuinely came from MCPity.

Event payload

json
{
  "event": "animation.generation.completed",
  "generation_id": "gen_xyz789",
  "status": "completed",
  "engine": "unity",
  "files": [ ... ],
  "metadata": { ... }
}

Signature header

X-MCPity-Signature: <hmac-sha256-hex>

Compute HMAC-SHA256(payload, webhook_secret) and compare with a timing-safe equality check.

typescript
// Node.js / Next.js webhook verification
import crypto from "crypto";

export async function POST(request: Request) {
  const body      = await request.arrayBuffer();
  const signature = request.headers.get("X-MCPity-Signature") ?? "";
  const secret    = process.env.MCPITY_WEBHOOK_SECRET!;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(Buffer.from(body))
    .digest("hex");

  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
    return Response.json({ error: "invalid signature" }, { status: 401 });
  }

  const event = JSON.parse(Buffer.from(body).toString());
  console.log("Animation ready:", event.generation_id);
  return Response.json({ ok: true });
}

Client SDKs

Official SDKs are available for TypeScript/JavaScript, Python, and C#. All SDKs cover all five endpoints, error handling, async polling helpers, and webhook signature verification.

🟦

TypeScript

npm i @mcpity/animation-client
typescript
import { MCPityAnimationClient } from "@mcpity/animation-client";

const client = new MCPityAnimationClient({
  apiKey: "mcp_live_abc123...",
});
const result = await client.generate({
  prompt: "Create a walk cycle",
  engine: "unity",
});
🐍

Python

pip install requests # copy mcpity_client.py
python
from mcpity_client import MCPityAnimationClient

client = MCPityAnimationClient(
    api_key="mcp_live_abc123...",
)
result = client.generate(
    prompt="Create a walk cycle",
    engine="unity",
)
🟪

C#

Copy MCPityAnimationClient.cs → Assets/
csharp
var client = new MCPityAnimationClient(
  new MCPityClientConfig {
    ApiKey = "mcp_live_abc123...",
  }
);
var result = await client.GenerateAsync(
  new GenerateRequest {
    Prompt = "Create a walk cycle",
    Engine = "unity",
  }
);
SDK source files are in the sdks/ directory of the repository: sdks/typescript/, sdks/python/, and sdks/csharp/.