Baseplate docs
Baseplate is an MCP server that gives your coding agent a library of safety-scanned Roblox effects and game sounds, each with a name and a plain description. Set it up once, then ask for what you need in plain words.
Quickstart
You need Node 18 or newer, a Rojo project, and the Roblox Studio MCP so your agent can load effects into your place.
1. Connect your agent
Claude Code:
claude mcp add baseplate -- npx -y baseplate-cli mcp
Codex, in ~/.codex/config.toml:
[mcp_servers.baseplate] command = "npx" args = ["-y", "baseplate-cli", "mcp"]
Cursor, in .cursor/mcp.json:
{
"mcpServers": {
"baseplate": { "command": "npx", "args": ["-y", "baseplate-cli", "mcp"] }
}
}2. Ask for something
Open your Rojo project with your agent and ask in plain words, for example: "Add a fire explosion when the rocket hits", or "Make collecting a coin feel rewarding". The agent searches, adds and wires up the effect or sound.
3. Optional: automatic sound uploads
Add an Open Cloud API key to your project's .env and add_sfx uploads sounds to your Roblox account for you. See Configuration.
How it works
- Find. Your agent calls
find_vfxorfind_sfxwith plain words and gets back component names with descriptions. - Add. It calls
add_vfxoradd_sfxwith the names it picked. Effects are checked against their scanned version; sounds are copied into your project. - Play. It writes one line of Luau with the Juice runtime:
Juice.play("explosion/fire", part)orJuice.sfx("pickup/coin-3", part).
find_vfx
Searches the 600 effects by what they are for. Returns up to 5 single effects, each with its name, a one-line description and the pack it comes from.
| Argument | Description |
|---|---|
query | Plain words, for example "fire explosion" or "electric aura". |
find_vfx("fire explosion")
explosion/fire: Red and black fire explosion burst with sparks and particles, about 4s, big.add_vfx
Adds effects by name. For each effect it confirms with the Creator Store that the pack is still the version Baseplate scanned, adds the Juice runtime if it is missing, records the effect in vfx.json, and returns one Luau snippet for the Roblox Studio MCP's execute_luau. The snippet loads the effect into ReplicatedStorage.BaseplateVFX with its scripts removed.
| Argument | Description |
|---|---|
names | Effect names from find_vfx, for example ["explosion/fire"]. |
project_dir | Optional. The Rojo project root. Defaults to the current directory. |
find_sfx
Searches the 906 sounds by what they are for or how they sound. Every sound file is its own component, and each description is measured from the audio: length, tone or noise, pitch, rising or falling, hits. Returns up to 8.
| Argument | Description |
|---|---|
query | Plain words, for example "coin pickup", "short bright click" or "rain loop". |
find_sfx("coin pickup")
pickup/coin-3: Coin pickup: 0.35s, tonal, high (about 1314 Hz), tone center 1.5 kHz, tail 0.19s.add_sfx
Adds sounds by name. For each sound it copies the file to assets/sounds/<name>, adds the Juice runtime if it is missing, registers the sound in Sounds.luau and records it in sfx.json. With credentials set, it uploads the file to your Roblox account and fills in the asset ID. Without them, it tells you which files to import in Studio's Asset Manager.
| Argument | Description |
|---|---|
names | Sound names from find_sfx, for example ["pickup/coin-3"]. |
project_dir | Optional. The Rojo project root. Defaults to the current directory. |
Adding a sound again keeps any asset ID it already has.
Juice runtime
Juice is a small Luau module the add tools copy into src/shared/Juice. Call it from client code. A target is a Vector3, BasePart or Model.
| Function | What it does |
|---|---|
Juice.play(name, target?) | Plays the effect and the sound with that name, whichever exist. |
Juice.vfx(name, target) | Plays only the effect. |
Juice.attach(name, target) | Starts a looping effect and returns a stop() function. |
Juice.sfx(name, target?) | Plays only the sound. Without a target it plays flat, for UI. |
Juice.music(name?) | Crossfades to a looping track. Juice.music(nil) stops it. |
local Juice = require(game.ReplicatedStorage.Shared.Juice)
Juice.play("explosion/fire", rocket)
Juice.sfx("ui/click-2")
local stop = Juice.attach("aura/electric", character)Configuration
Set these in your environment or in your project's .env. Keep .env out of version control.
| Variable | Description |
|---|---|
ROBLOX_API_KEY | An Open Cloud API key with asset write access. Lets add_sfx upload sounds. |
ROBLOX_CREATOR | Who owns uploads: user:<id> or group:<id>. |
BASEPLATE_REGISTRY | Optional. Points the CLI at another catalog, a URL or a local folder. |
Lock files
Both add tools record what they added in your project root, so you can review it and know where every asset came from.
vfx.json
One entry per effect: its name, Creator Store asset ID, the path inside the pack, the pinned version and the pack name.
sfx.json
One entry per sound: its name, the file in your project, its Roblox asset ID once uploaded and its source file.
{
"component": "pickup/coin-3",
"file": "assets/sounds/pickup/coin-3.ogg",
"asset_id": null,
"source_file": "baseplate/coin_pickup.ogg"
}CLI
| Command | What it does |
|---|---|
npx baseplate-cli mcp | Runs the MCP server for your agent. |
npx baseplate-cli find <words> | Searches the effects yourself. |
npx baseplate-cli sound <words> | Searches the sounds yourself. |
Catalog JSON
Agents without MCP can read the same catalog directly.
- vfx-effects.json: every effect with its name, description, category, colors, size, length, pack and pinned version.
- sfx-files.json: every sound with its name, description, category, file and format.
FAQ
Is Baseplate free?
Yes. The library, the CLI and the MCP server are free to use. Effects come from free Creator Store packs, and every sound is CC0 or public domain.
Do I need to know Roblox development?
No. Your agent writes the Luau and calls the tools. You describe what you want in plain words and play-test in Studio.
How do sounds get into Roblox?
Roblox only plays audio uploaded to Roblox, so each sound is uploaded once to your own account, where no one else can remove it. With an Open Cloud key in your project's .env, add_sfx uploads for you. Without one, your agent tells you which file to import in Studio's Asset Manager.
What stops a free asset from breaking my game?
Effects are pinned to the scanned version and refused if the pack changes. Sounds are copied into your project and uploaded to your own account. Neither depends on Baseplate staying online.