Skip to main content
Glama
BluntMan-420

MaxForge MCP

by BluntMan-420
README.md
# MaxForge MCP

Lets an AI agent (Claude, or anything else that speaks [MCP](https://modelcontextprotocol.io)) drive a **live 3ds Max session** — not by generating scripts for a human to paste in, but by actually creating, editing, and animating objects in real time while Max is open.

Normally, getting an AI to help in 3ds Max means it writes a script and you run it yourself, blind to whether it actually worked. This closes that loop: the agent can query the real scene state before and after every action, catch its own mistakes, and iterate live instead of guessing.

## What it can do

| | |
|---|---|
| **Inspect the scene** | list objects, read the current selection, query units / frame rate / frame range |
| **Create & transform** | primitives, position / rotation / scale |
| **Materials & textures** | create a material, load a bitmap texture, assign it to objects |
| **Animation** | keyframe position/rotation/scale across frames with real spline interpolation |
| **Collision proxies** | generate a basic bounding-box proxy for an object |
| **Export & save** | export selected objects or the whole scene, save the `.max` file |
| **Escape hatch** | run arbitrary raw MaxScript or Python for anything not covered above |

Every mutation is wrapped in a real undo block — anything the agent does is a normal Ctrl+Z away from being undone.

## How it works

```
AI agent (MCP client) --stdio--> server/max_mcp_server.py --TCP, localhost only--> max_side/bridge.py (inside 3ds Max)
```

A small Python bridge runs inside 3ds Max, loaded via a startup script, and opens a socket bound to `127.0.0.1` only. An MCP server outside Max connects to it and exposes the tools above. Every command runs on Max's main thread via a Qt timer — the 3ds Max SDK isn't thread-safe, so commands arriving on a socket thread are queued and drained on the main loop rather than executed directly.

```
max_side/
  bridge.py      socket + main-thread queue (the only place pymxs is touched)
  commands.py    one function per tool, each wrapped in an undo block
  serialize.py   converts pymxs values (Point3, Matrix3, nodes, ...) to JSON
  startup_stub.ms   drop into Max's startup scripts folder
server/
  client.py         TCP client, newline-delimited JSON
  tools.py           MCP tool definitions
  max_mcp_server.py  the MCP server itself (stdio transport)
```

## Setup

**Requirements:** 3ds Max 2022+ (pymxs), Python 3.10+ on the machine running the MCP server, [`uv`](https://docs.astral.sh/uv/).

**1. Install dependencies**
```
uv sync
```

**2. Load the bridge into 3ds Max**

Copy `max_side/startup_stub.ms` into Max's startup scripts folder — typically:
```
%LOCALAPPDATA%\Autodesk\3dsMax\<version>\ENU\scripts\startup\
```
Open the copied `startup_stub.ms` and set `MAXFORGE_REPO_PATH` to wherever you cloned this repo. It starts the bridge on port `47823` automatically the next time Max launches. Three macroscripts (category "MaxForge MCP") are also registered for manual control — Start / Stop / Reload — so you can pick up code changes without restarting Max.

**3. Point an MCP client at it**

For Claude Code:
```
claude mcp add maxforge -- <repo>\.venv\Scripts\python.exe <repo>\server\max_mcp_server.py
```
Or wire `server/max_mcp_server.py` into any other MCP-compatible client's config the same way.

## Safety

The socket only ever binds to `127.0.0.1` — never the network. This is a code-execution endpoint sitting inside a modeling app; it's designed to only be reachable from the same machine it runs on.

## Status

Live-tested against a running Max 2025 session with a full assertion-based suite (29/29 checks) covering every tool, every error path, and an undo/redo round trip.

`create_collision_proxy` currently only builds a generic axis-aligned box — it isn't tuned to any specific game engine's collision format yet.

## Adding a new tool

1. Add a handler in `max_side/commands.py`, wrapped in `undoable("MCP: ...")`, registered in the `COMMANDS` dict.
2. Add a matching wrapper in `server/tools.py` — its docstring is what the agent sees.
3. Register it in the loop at the top of `server/max_mcp_server.py`.
4. Run the "Reload MaxForge Bridge" macroscript in Max instead of restarting.

## License

Copyright (c) 2026 .bluntman420. — see [LICENSE.md](LICENSE.md). Free to
use as-is; modification and redistribution of modified versions is not
permitted.

TDQS

B3.3/5.0

Scored across 17 tools

Disambiguation5/5

Every tool targets a distinct operation in the 3ds Max domain: scene state, materials, animation, scripting, selection, object creation, transformation, properties, deletion, export, and saving. Even the two scripting tools (run_maxscript and run_python) are cleanly separated by language, and set_property vs. transform have clear boundaries (arbitrary vs. spatial transformation). No two tools appear to do the same thing.

Naming Consistency3/5

The majority of tools follow a verb_noun pattern (apply_material, set_keyframe, get_scene_info, create_object, set_property, save_scene, add_modifier). However, several tools use bare verbs (select, transform, delete, export, ping) and two use verb_language (run_maxscript, run_python). This mix of patterns is readable but not fully consistent.

Tool Count4/5

With 17 tools, this is slightly above the ideal 3-15 range but still appropriate for a comprehensive 3ds Max bridge that covers modeling, animation, scene management, and export. The tools are not redundant, and the count reflects the breadth of operations required for a professional DCC integration.

Completeness4/5

The surface covers the core lifecycle: create, inspect, modify, delete, select, save, export, and add modifiers. It also handles materials and keyframes. Minor gaps include lack of a dedicated get_property tool (though run_maxscript can access anything) and no duplicate or group operations. Overall, agents can accomplish most workflows without dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues