Every plugin has a manifest at .ohmygame-plugin/plugin.json. Point $schema at https://ohmygame.dev/schema/plugin-2.json to get completion and checks in your editor.
Required fields
| Field | What it is |
|---|---|
id |
publisher/name. The publisher is your npm scope, without @. |
version |
The plugin’s version, the same as in package.json. |
engines |
{ "ohmygame-api": "^2.3.0" }: the plugin API versions it works with. |
displayName |
The name the app shows. |
description |
One sentence on what it does. |
ohmygame-api can be an exact version, or ^x.y.z, ~x.y.z or >=x.y.z. Its minor version grows when something new is added for plugins, so a plugin that needs a newer field asks for that version. An app that’s too old says so and, on the desktop, offers the update.
Optional fields
| Field | What it is |
|---|---|
icon |
A path to an SVG or PNG in the package. |
categories |
Any of engine, art, audio, publishing, provider, theme, workflow, integration. |
longDescription |
The text on the plugin’s About tab. |
examples |
Up to five Try it prompts. |
beta |
Marks the plugin as beta. |
links |
A homepage and a sponsor link. |
projectFiles |
Up to 20 files or folders the plugin leaves in projects, such as ./.maker/. Uninstalling lists them and leaves them in place. |
entrypoints.native |
The file with the plugin’s native code. |
capabilities |
What the plugin asks to be allowed. See below. |
configuration |
Settings fields shown on the plugin’s page. |
ui |
major, the page components’ major version its panels use; preview, to use components still in preview. |
contributes |
What the plugin adds. See below. |
Capabilities
| Capability | Asks for |
|---|---|
native |
Running entrypoints.native |
project.files |
"read" or "write" access to project files for its panels |
project.selection |
Seeing what’s selected |
composer |
Filling the message box |
secrets |
Receiving secret settings |
network |
A list of hosts its HTTP MCP servers may reach |
processes |
A list of commands its local MCP servers may start |
game |
Opening and playing the project’s game, as the agent’s playtesting does |
What a plugin can add
contributes holds each part:
| Field | Adds |
|---|---|
skills |
A folder of Skills, each one a folder with a SKILL.md |
tools |
Tools for the agent, registered by native code. Each has a name, a description and an input schema. |
commands |
Commands in the app, with an id, a title, a run and the slots where they show |
panels |
Panels beside the chat, with an id, a title, an area and an HTML entry |
mcpServers |
Local or HTTP MCP servers, with an id, a title, a command and the tools they offer |
projectTypes |
New kinds of project, with a template folder and a preview of web, web-build or native |
themes |
Colour themes for Settings → Appearance |
providers |
Chat model providers for Settings → Providers |
agents |
Coding agents |
hooks |
Code that reacts to events, such as a finished turn |
canvasNodes, canvasPresets |
New nodes and presets on the canvas |
previewDevices, previewFilters, inputMaps |
Additions to the game preview |
Commands
A command’s run does one of these:
run |
Does |
|---|---|
{ "prompt": "…" } |
Sends a prompt, or puts it in the message box with "insert": true |
{ "tool": "…" } |
Calls a tool |
{ "openPanel": "…" } |
Brings one of the plugin’s panels forward |
{ "openSettings": true } |
Opens the plugin’s page |
{ "url": "…" } |
Opens a link |
{ "native": "…" } |
Runs a command registered by native code |
slots place it in the app. The slots include project.menu, project.toolbar, project.publish, composer.add, composer.slash, home.starters, canvas.add, canvas.node and game.more.
Native code
The native entry exports activate(context). It runs in a Node process for each project, never inside the app itself, and can register only the tools and commands the manifest declares:
export function activate(context) {
context.registerTool("hello", async (input, options) => {
options.progress("Saying hello…");
return { text: `Hello, ${input.name ?? "there"}` };
});
}context.project.folder is the project, and context.dataFolder is the plugin’s own data folder.
A local MCP server
"capabilities": { "processes": ["node"] },
"contributes": {
"mcpServers": [
{ "id": "server", "title": "%mcp.title%", "command": "node", "args": ["./mcp/server.mjs"], "tools": ["echo"] }
]
}The command must also be listed in capabilities.processes, so you approve it before it runs.