Skip to content

MCP setup

feather-cli mcp is a Model Context Protocol server that runs over standard input and output. It exposes every command in the catalog as an MCP tool, with the same JSON schemas and descriptions, so any MCP-capable AI client can author, play-test and inspect a Feather 2 project.

You can connect it in two ways:

Mode Agent works on Can see the viewport Needs the editor running
Live The project open in the editor, alongside you Yes Yes
Headless A project folder, in memory No No

Option 1: enable automation from the editor

Section titled “Option 1: enable automation from the editor”
  1. Open Tools → Automation (MCP).
  2. Click Enable for a project folder… and choose the folder the agent may use. File operations are limited to this folder.
  3. Click Copy MCP configuration and paste it into your AI client’s MCP settings. Copy command copies the equivalent command line.

The panel then shows the session, the document revision, the full command list and recent command activity.

Option 2: launch the editor with a session

Section titled “Option 2: launch the editor with a session”
Terminal window
feather-editor --workspace /path/to/my-game --automation .feather-session.json --panel automation

The session file is created inside the workspace. Add --project FILE to open a specific project.

Use absolute paths to the CLI and the session file:

{
"mcpServers": {
"feather": {
"command": "/absolute/path/to/feather-cli",
"args": ["--connect", "/absolute/path/to/my-game/.feather-session.json", "mcp"]
}
}
}

In the macOS app the CLI is at Feather v2.app/Contents/MacOS/feather-cli.

The editor listens only on the loopback interface. The session file holds the address and a random 256-bit token, and is created with owner-only permissions. Requests without the token are refused. The editor deletes the session file when it exits. If an old session file is still present, choose a new file name.

For a headless session, point the server at a workspace and, optionally, a project:

{
"mcpServers": {
"feather": {
"command": "/absolute/path/to/feather-cli",
"args": ["--workspace", "/absolute/path/to/my-game", "--project", "project.feather.json", "mcp"]
}
}
}

The document stays in memory for the whole MCP session. Call project.save to write it to disk. Commands that need a window, such as runtime.play and viewport.capture, return requires_live_editor.

Every tool accepts an optional expected_revision argument. Read the current revision first, for example with engine.status or project.inspect, then pass it with your edit. A stale revision returns revision_conflict and changes nothing. See Agents overview.

An agent can capture the real editor image and receive it as MCP image content:

  1. Call viewport.capture with a PNG path inside the workspace. It returns a job_id.
  2. Poll job.inspect with that job_id until status is completed (or failed).
  3. Call viewport.image with the same job_id. MCP returns the PNG as image content; the CLI returns it as base64.
Terminal window
feather-cli --connect .feather-session.json command viewport.capture \
--json '{"path":"captures/view.png"}'
feather-cli --connect .feather-session.json command job.inspect --json '{"job_id":1}'
feather-cli --connect .feather-session.json command viewport.image --json '{"job_id":1}'

To frame the shot first, use viewport.focus, viewport.frame_scene or viewport.view.set, and poll viewport.view.get with the returned request_id until it reports applied.

  • Images returned by viewport.image are at most 16 MiB.
  • Live jobs (capture, export and simulation) report running, completed or failed through job.inspect.
  • The server negotiates MCP protocol versions 2025-11-25, 2025-06-18 and 2025-03-26.

A typical agent loop against a live editor:

  1. engine.status — check for pending editor edits and Play state.
  2. Author with scene.*, prefab.* and the domain commands, passing expected_revision.
  3. game.simulate — check gameplay without a renderer; see Simulation.
  4. viewport.capture → job.inspect → viewport.image — look at the result.
  5. project.save — write the project.