pixijs-mcp
v1.0.0
Published
A Model Context Protocol (MCP) server that inspects and controls any running PixiJS application live in the browser over the Chrome DevTools Protocol.
Downloads
25
Maintainers
Readme
pixijs-mcp
A Model Context Protocol server that lets an AI agent
inspect and control any running PixiJS application live in the
browser. It attaches to a Chrome tab over the Chrome DevTools Protocol (CDP), discovers the
PixiJS Application, and exposes the scene graph, renderer/ticker stats, screenshots, and
mutation tools.
Use it to ask questions like "what's in my stage right now?", "why is this sprite invisible?", "what's my current FPS?", or to poke at node properties and slow down the ticker while debugging animations.
MCP client (Cursor, Claude, …) ──stdio──► pixijs-mcp ──CDP──► Chrome tab (your PixiJS app)Quick start
1. Make your PixiJS app discoverable
Expose your Application on the global scope (this is also what the official PixiJS
DevTools extension looks for):
import { Application } from 'pixi.js'
const app = new Application()
await app.init({ width: 800, height: 600 })
// Either of these is enough:
globalThis.__PIXI_APP__ = app
// or
globalThis.__PIXI_DEVTOOLS__ = { app }If you can't set a global, you can instead point the server at a custom expression with the
PIXI_APP_EXPR environment variable (see Configuration).
2. Run Chrome with remote debugging
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222
# Windows
chrome.exe --remote-debugging-port=9222Open your PixiJS app in that Chrome instance.
3. Install & build
npm install
npm run buildOr run straight from source with no build step using tsx:
npm run dev4. Register with your MCP client
Once published to npm you can run it with npx -y pixijs-mcp. To run a local checkout
instead, swap the command for node /absolute/path/to/pixijs-mcp/dist/index.js (or
npx tsx /absolute/path/to/pixijs-mcp/src/index.ts to skip the build).
Cursor
Add to ~/.cursor/mcp.json (global) or project .cursor/mcp.json:
{
"mcpServers": {
"pixijs": {
"command": "npx",
"args": ["-y", "pixijs-mcp"],
"env": {
"PIXI_URL": "localhost:3000"
}
}
}
}Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config), then restart Claude.
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"pixijs": {
"command": "npx",
"args": ["-y", "pixijs-mcp"],
"env": {
"PIXI_URL": "localhost:3000"
}
}
}
}Claude Code (CLI)
Register it with claude mcp add (use --scope user to make it available in every project):
claude mcp add pixijs \
--scope user \
--env PIXI_URL=localhost:3000 \
-- npx -y pixijs-mcpThen check it with claude mcp list and claude mcp get pixijs.
Configuration
All configuration is via environment variables:
| Variable | Default | Purpose |
| --------------- | ----------- | ------------------------------------------------------------------------------------------------ |
| CDP_HOST | localhost | Chrome DevTools host. |
| CDP_PORT | 9222 | Chrome remote-debugging port. |
| PIXI_URL | (unset) | Substring used to pick the tab. When unset, attaches to the first regular page tab. |
| PIXI_APP_EXPR | (unset) | JS expression returning your Application if it isn't on a known global (e.g. window.myGame.app). |
Tools
Inspection
| Tool | Description |
| ----------------- | -------------------------------------------------------------------------------------------- |
| check_connection| Verify CDP reachability and whether a PixiJS app was found (reports PixiJS version). |
| get_app_info | Renderer type/size/resolution, screen dims, ticker stats, stage child count. |
| get_ticker | FPS, minFPS, maxFPS, deltaMS, deltaTime, speed, started, listener count. |
| count_nodes | Total display objects and a breakdown by type. |
| get_scene_tree | Recursively serialize the scene graph (configurable path + depth). |
| get_node | Detailed single-node info: transform, bounds, texture/text, direct children. |
| find_nodes | Search the tree by label and/or type substring. |
Visuals & raw access
| Tool | Description |
| ---------------- | -------------------------------------------------------------------- |
| get_screenshot | PNG screenshot of the page (optionally at a higher scale). |
| eval | Evaluate an arbitrary JS expression in the page (escape hatch). |
| send_key | Dispatch a keyboard press (named keys or single letters/digits). |
Mutation & control
| Tool | Description |
| ------------------- | ------------------------------------------------------------------------------------------- |
| set_node_property | Set x, y, alpha, rotation, angle, visible, renderable, zIndex, tint, scaleX, scaleY. |
| control_ticker | stop / start / update the render loop (step a single frame while stopped). |
| set_ticker_speed | Set the ticker speed multiplier (slow-mo / fast-forward). |
Node paths
Nodes are addressed by a /-joined chain of child indices from the stage. "" is the
stage; "0" is its first child; "0/2/1" is the second child of the third child of the
first child. Use find_nodes to discover paths, then get_node / set_node_property to
act on them.
Architecture
The page-side logic lives in a single real function (src/agent.ts) rather than a pile of
interpolated code strings. On first use it is serialized with Function.prototype.toString()
and injected once to install window.__PIXI_MCP__. Each tool then calls a named method on
window.__PIXI_MCP__.api, passing its arguments as JSON data — request data is never
interpolated into page code, which avoids escaping and injection pitfalls. The agent is
re-injected automatically if the page reloads. The only dynamic code is the optional,
operator-provided PIXI_APP_EXPR.
Compatibility
Designed for PixiJS v8 (uses label, app.renderer, app.ticker). It also works with
v6/v7 apps that expose name/stage/renderer/ticker, and degrades gracefully when only
a stage or renderer is exposed.
