ArmorPaint MCP
# ArmorPaint MCP
A local MCP server for controlling ArmorPaint from Codex, Claude, Cursor, or another agent that supports stdio MCP. It exposes 41 tools for projects, meshes, materials, nodes, layers, masks, painting, baking, cameras, and exports. Viewport captures are returned as images.
The server needs the native ArmorPaint bridge included here. An unmodified ArmorPaint app cannot connect. The Apple silicon build is tested; native Windows and Linux builds remain unverified. Claude and Cursor client instructions are provided, but those clients have not been tested directly.
## Install
Use Python 3.11 or newer. From this folder:
```sh
python3 -m venv .venv
.venv/bin/python -m pip install .
.venv/bin/armorpaint-mcp --help
```
Use the full path to `.venv/bin/armorpaint-mcp` in your client settings. On Windows, the executable is `.venv\Scripts\armorpaint-mcp.exe`.
The MCP server needs no API key. Your agent supplies the model, reasoning, and image interpretation.
## Build the ArmorPaint bridge
Skip this step if your app already includes this bridge. For Apple silicon, install full Xcode with its Metal toolchain, then run:
```sh
git clone https://github.com/armory3d/armorpaint.git ../armorpaint
git -C ../armorpaint checkout 906418acc600132fa927876d208eb452dc5a0967
.venv/bin/python scripts/build_macos.py ../armorpaint --output build/macos
```
Copy `build/macos/Build/Products/Release/ArmorPaint.app` to `/Applications/ArmorPaint MCP.app`, or use its existing location in your settings. This is a local ad hoc signed build, without Apple notarization.
The bridge is pinned to ArmorPaint 1.1alpha at the revision above. For other desktop platforms, apply it with `scripts/apply_bridge.py` and follow the [upstream build instructions](https://github.com/armory3d/armorpaint#readme).
## Choose your paths
Replace the example paths below with absolute paths. Keep spaces inside the quotes. Do not leave `~`, `$HOME`, or placeholders in JSON or TOML.
| Option | Purpose |
| --- | --- |
| `--app` | Bridge-enabled ArmorPaint app or executable |
| `--bridge-dir` | Private connection and preferences folder, created automatically |
| `--workspace` | Folder for meshes, references, projects, and exports |
| `--launch` | Start ArmorPaint when a client connects |
| `--timeout` | Server operation timeout in seconds |
Create your workspace folder first. Use the same bridge directory in different clients to share a session. Use different directories for independent sessions.
## Claude Desktop
Open **Settings → Developer → Edit Config**. On macOS, the file is `~/Library/Application Support/Claude/claude_desktop_config.json`.
Merge this entry into your configuration, preserving other servers. The same template is in [setup/mcp.json](setup/mcp.json).
```json
{
"mcpServers": {
"armorpaint": {
"command": "/absolute/path/armorpaint-mcp/.venv/bin/armorpaint-mcp",
"args": [
"--launch",
"--app", "/Applications/ArmorPaint MCP.app",
"--bridge-dir", "/absolute/path/armorpaint-session",
"--workspace", "/absolute/path/texture-projects",
"--timeout", "180"
]
}
}
}
```
Quit and reopen Claude Desktop, then check for `armorpaint` in its connectors. These settings apply to the desktop app, not a remote connector in the Claude website. [Official setup guide](https://modelcontextprotocol.io/docs/2026-07-28/develop/connect-local-servers).
## Claude Code
Replace the paths and run:
```sh
claude mcp add --transport stdio --scope user armorpaint -- \
"/absolute/path/armorpaint-mcp/.venv/bin/armorpaint-mcp" \
--launch \
--app "/Applications/ArmorPaint MCP.app" \
--bridge-dir "/absolute/path/armorpaint-session" \
--workspace "/absolute/path/texture-projects" \
--timeout 180
```
Use `--scope local` instead for a connection specific to the current project. To inspect the entry and allow time for startup and baking:
```sh
claude mcp get armorpaint
MCP_TIMEOUT=90000 MCP_TOOL_TIMEOUT=200000 claude
```
The Claude timeout variables use milliseconds. Run `/mcp` inside Claude Code to check the connection. [Official documentation](https://code.claude.com/docs/en/mcp).
## Cursor
Merge the JSON example above into `~/.cursor/mcp.json` for all projects, or `.cursor/mcp.json` inside one project. For Cursor, add `"type": "stdio"` inside the `armorpaint` entry. Replace the paths, reload Cursor, and enable `armorpaint` in its MCP settings. Start from [setup/mcp.json](setup/mcp.json). [Official documentation](https://cursor.com/docs/mcp).
## Codex
Add this to `~/.codex/config.toml`, replacing the paths. Update the existing table if `armorpaint` is already configured. A copy is in [setup/codex.toml](setup/codex.toml).
```toml
[mcp_servers.armorpaint]
command = "/absolute/path/armorpaint-mcp/.venv/bin/armorpaint-mcp"
args = [
"--launch",
"--app", "/Applications/ArmorPaint MCP.app",
"--bridge-dir", "/absolute/path/armorpaint-session",
"--workspace", "/absolute/path/texture-projects",
"--timeout", "180"
]
startup_timeout_sec = 90
tool_timeout_sec = 200
```
The desktop app and CLI share MCP settings on the same host. Restart the MCP connection in Codex settings, or restart the app. In the CLI, use `/mcp` in a fresh session. `codex mcp get armorpaint` shows the saved configuration. [Official documentation](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
## Other agents
Configure a local stdio MCP server using the same executable and arguments. Image inspection requires support for MCP image content. A remote-only agent needs a local runtime to launch this server and ArmorPaint.
The MCP tools use standard schemas; they are not tied to a model provider. Compatibility has been checked with the official MCP SDK and Codex's runtime, not every agent application.
## First use
Ask your agent:
> Use ArmorPaint to check the connection and inspect the current scene. Report its objects, layers, and texture resolution without changing anything.
It should call `armorpaint_status` and `armorpaint_get_state`. Use `armorpaint_list_node_types` before editing material graphs. The `armorpaint://project` resource also returns the scene state.
Put your mesh and reference in the workspace, attach the reference image to the conversation, and describe the finish you want. Ask the agent to save a checkpoint, inspect viewport captures, and export the project and PBR maps.
## Session behavior
The app polls a private local mailbox on its main thread. Requests are serialized across clients. No network listener is created. Preferences and `armorpaint.log` are stored inside the bridge directory. Closing the client leaves ArmorPaint open.
`--workspace` checks file paths accepted by the normal tools. It is not an operating-system sandbox: the app runs as your user, and imported projects may reference other assets. Scripting is disabled by default. `--allow-scripts` adds `armorpaint_run_script`; it also requires the app to start with `ARMORPAINT_MCP_ALLOW_SCRIPTS=1`, which the launch option sets when scripting is enabled.
Save checkpoints before substantial edits. A timed-out operation may already have changed the scene, and undo does not cover every operation. Inspect the result before retrying.
## Troubleshooting
- **Server missing:** check JSON or TOML syntax, absolute executable paths, and client reload status.
- **Not connected:** confirm the app includes the bridge, keep `--launch`, and use the same bridge directory in both processes.
- **App startup failed:** inspect `armorpaint.log` in the bridge directory. A graphical desktop is required.
- **Path rejected:** keep input and output files inside the configured workspace.
- **Operation timed out:** inspect the scene and logs, then adjust both the client and server timeouts if needed.
- **Unexpected texture:** inspect exported maps, UVs, object masks, and lighting. The agent must judge the visual result.
## License
The MCP integration is [MIT licensed](LICENSE). ArmorPaint and its dependencies retain their own licenses. This project is independent of Armory3D and the agent vendors.
TDQS
Scored across 41 tools
Most tools target a distinct resource-action pair, and the detailed descriptions help separate overlapping operations like set_layer vs layer_action and fill_layer vs paint_stroke. A few close neighbors exist—export_layer vs export_textures and set_node_value vs set_material_pbr—but they are still distinguishable from their names and descriptions.
The armorpaint_ prefix plus verb_noun pattern is consistent overall, e.g. create_material, delete_material, connect_nodes, export_mesh. Minor deviations exist such as new_project instead of create_project, bake as a bare verb, and layer_action as a generic suffix, but the naming is still predictable and readable.
With 41 tools, this exceeds the 25-tool threshold that typically indicates an overgrown surface. The tools are organized by subsystem and each has a real purpose, but the count is heavy enough that an agent must manage a large selection set.
The tool set covers the full ArmorPaint workflow: project handling, mesh/material/node graph editing, layer management, painting, baking, viewport inspection, and multiple export paths. Minor gaps exist—such as no object deletion or duplicate, and no explicit material rename—but they are workaroundable and do not block core workflows.