Skip to main content
Glama

max-mcp

Let an AI assistant work inside your running Autodesk 3ds Max session, and keep the user in control of what it changed.

max-mcp is an MCP server for 3ds Max. Any MCP client (Claude Code, Claude Desktop, Cursor, Gemini CLI, ChatGPT developer mode, custom agents over HTTP) can read the selection, query objects and layers, grab the viewport, and run MAXScript or Python (pymxs) in the live scene. Every request is logged, every scene change is a named undo record, and the AI can only undo its own steps.

Why this project - archviz work in 3ds Max is full of repetitive scene surgery (renaming, layer sorting, batch property edits, checks) that an assistant can do well, but only if it sees the open scene and the user can audit and reverse what it did. Headless batch scripts can't see the open scene; most bridges give the AI a raw "run script" tool and nothing else. max-mcp is the small, model-agnostic layer in between. It is also a portfolio piece.

settings and history window The max-mcp window inside 3ds Max: History tab with per-request undo state, scene diff and the code that ran.

How it works

Piece

Runs in

Depends on

max_side/ (listener, settings/history window)

3ds Max (its own Python 3.11)

pymxs, standard library, Max's bundled PySide6

max_mcp/ (server.py, client.py, config.py)

your Python 3.10+

official mcp SDK, standard library

The listener accepts newline-delimited JSON on 127.0.0.1:30025; the MCP server (stdio or streamable HTTP) forwards tool calls to it. Commands run on Max's main thread (see below). The bridge never saves your scene and has no save tool.

Tested with 3ds Max 2025 (Python 3.11.8, PySide6 6.5.3). Other versions that ship pymxs + PySide6 should work but are untested.

Related MCP server: 3dsmax-mcp

Install

git clone <repo-url> max-mcp
cd max-mcp
pip install .            # or pip install -e .   (editable)
# without installing:    uvx --from . max-mcp

No installer: the listener only needs its folder on sys.path, which the start script does by itself (it also drops the two action icons into Max's usericons folder, see below).

1. Load it inside 3ds Max

Scripting > Run Script... and pick max_side/max_mcp_start.ms. The MAXScript Listener prints [MaxMcp] dinleniyor 127.0.0.1:30025 and the window is available as macroScript MaxMcp Settings (category max-mcp, add it to any menu/toolbar/quad via Customize > Customize User Interface), or with python.Execute "import max_mcp_ui; max_mcp_ui.show()".

Both actions, MaxMcp Settings and MaxMcp Start/Stop (a check button that stays highlighted while the listener runs), come with SVG icons, so they can go on the ribbon too: right-click the ribbon > Customize Ribbon, pick category max-mcp in the action list and drag them onto a panel. The icons live in max_side/icons/MaxMcp/; the macro file copies them to Max's per-user usericons\MaxMcp folder when they are missing or changed. That folder is the only thing written outside the repo besides the optional startup loader.

To load it automatically at startup, press Install loader in the window (writes a one-line max_mcp_loader.ms into Max's per-user startup folder; Remove loader deletes it) or use the CLI:

python -m max_mcp.paths            # shows detected paths and the loader text, writes nothing
python -m max_mcp.paths --write    # writes the loader

Whether the listener actually starts at startup is the autostart setting.

2. Register the MCP server in your client

The window's Client configuration box generates these for your current port/key (press Copy). Defaults shown; replace python with the interpreter that has mcp installed.

Claude Code

claude mcp add -s user max -- python -m max_mcp.server
# HTTP transport:
claude mcp add -s user --transport http max http://127.0.0.1:30026/mcp

Claude Desktop (claude_desktop_config.json), Cursor (.cursor/mcp.json or global MCP settings), Gemini CLI (~/.gemini/settings.json) - all use the same mcpServers shape:

{ "mcpServers": { "max": { "command": "python", "args": ["-m", "max_mcp.server"] } } }

Gemini CLI's HTTP form uses "httpUrl": "http://127.0.0.1:30026/mcp"; Cursor's uses "url". These shapes follow each vendor's public docs at the time of writing but were not verified by running those clients here; only Claude Code and the official mcp Python client were tested.

HTTP / remote clients (ChatGPT developer mode, OpenAI/xAI remote MCP tools, custom agents) - run the HTTP transport and point the client at the URL:

python -m max_mcp.server --transport http                 # http://127.0.0.1:30026/mcp
python -m max_mcp.server --transport http --http-host 0.0.0.0 --key <secret>   # LAN; key mandatory

With a key, clients must send Authorization: Bearer <secret>. Hosted services need the URL to be reachable from the internet (a tunnel such as ngrok or cloudflared, over HTTPS) - not verified here, and exposing Max's script execution to the internet is your risk to take.

Configuration

Settings live in %LOCALAPPDATA%\max-mcp\config.json (override the path with MAX_MCP_CONFIG) and are edited in the window. Precedence, highest first: environment variable > command-line argument > config file > default.

Key

Env

Default

Meaning

port

MAX_MCP_PORT

30025

listener TCP port

host

MAX_MCP_HOST

127.0.0.1

listener bind address

key / key_enabled

MAX_MCP_KEY

"" / false

shared key (env var implies enabled)

autostart

MAX_MCP_AUTOSTART

true

start listener with Max (needs loader)

pump_interval_ms

MAX_MCP_PUMP_MS

50

main-thread pump interval

timeout

MAX_MCP_TIMEOUT

60

seconds a call may wait for Max

http_host / http_port

MAX_MCP_HTTP_HOST / _PORT

127.0.0.1 / 30026

streamable-HTTP bind

checkpoint_mode

MAX_MCP_CHECKPOINT_MODE

off

off / changing / all scene copies

checkpoint_max_count / _mb

MAX_MCP_CHECKPOINT_MAX_*

10 / 2048

checkpoint retention

history_max_mb

MAX_MCP_HISTORY_MAX_MB

5

history.jsonl size before rotation

ai_undo_enabled

MAX_MCP_AI_UNDO

true

may the max_undo tool run

Server CLI: --transport stdio|http --port --host --key --timeout --http-host --http-port --config.

Tools

Tool

Parameters

What it does

Undoable

max_info

-

version, scene path, dirty flag, units, counts, renderer, listener status

read-only

max_selection

limit=200, detail=false

selected objects

read-only

max_query_objects

name_pattern, class_name, layer, selected_only, detail, limit=100

find objects; name_pattern is a MAXScript wildcard (Wall_*), case-insensitive

read-only

max_layers

-

layers with hidden/frozen/current flags and object counts

read-only

max_set_layer_hidden

name, hidden=true

hide/show a layer

yes - MCP: set_layer_hidden #id

max_viewport_capture

path="", max_size=1024

active viewport to PNG, returns the path

read-only (writes the PNG)

max_run_maxscript

code, undo=true, timeout=60

run MAXScript; returns the last value (format output goes to Max's Listener)

yes when undo=true - MCP: run_maxscript #id

max_run_python

code, undo=true, timeout=60

run Python in Max; rt, pymxs predefined; single expression returns its value, else assign result

yes when undo=true - MCP: run_python #id

max_history

limit=30, tool="", full=false

the command history (see below)

read-only

max_undo

steps=1 or to_history_id

undo the bridge's own records only

it is the undo

Object records contain name, class, layer, pos, hidden; with detail=true also superclass, bbox_min/max, rotation, scale, parent, children, frozen, selected, wirecolor, material {name, class}, user_props, faces.

History, undo and checkpoints

Every request is appended to <config dir>/history.jsonl (rotated at history_max_mb, two older files kept) with time, MCP client name (clientInfo), tool, argument summary, full args, duration, ok/error, output, objects added/removed, selection before/after and a "scene changed" flag from Max's undo put counter. The History tab of the window shows the rows; a row reveals the full code and output, Copy code and Re-run act on it.

Undo records. Scene-changing tools are accepted as one undo record each, labelled MCP: <tool> #<id>, so Ctrl+Z in Max undoes exactly one request. An error inside the record cancels it (partial changes are rolled back) and the error is returned.

max_undo (the AI). Undoes the last steps records or everything down to to_history_id - but only if every level on the way is a bridge record. The bridge reads the real stack (theHold.getUndoNames()), identifies its own levels by label and depth, and verifies after each max undo. If a user's manual step sits in between the call is refused and names the step; if the target has left the undo stack it fails. (When the pump runs inside a python.Execute call - the dotNet-timer fallback - Max names every level "MAXScript"; the depth bookkeeping still works, but once the stack is full and Max starts dropping old levels those records are reported as gone rather than guessed.) Undone entries are marked undone in the history; the undo call is itself a history row. The "AI may undo its own steps" switch in the window turns the tool off (it then returns "disabled"). There is no max_redo: Max clears the redo stack on the next change, and the next AI request is a change, so a redo tool would almost never have anything to redo; Ctrl+Y in Max covers the rare case.

Revert to here (the user). The History tab can undo back to any record still on the stack, including past the user's own steps - after a confirmation that lists them. Rows whose record is gone are grey ("gone" / "undone").

Checkpoints (optional, default off). With checkpoint_mode = changing (or all) the bridge copies the scene before each request with saveMaxFile <copy> useNewFile:false quiet:true, which keeps the scene's own file name and path and never touches your file; the "modified" flag is restored afterwards. Default off because a full scene write before every command is slow on large scenes and the undo records already cover normal use; turn it on for risky sessions. Copies live in <config dir>/checkpoints, limited by count and total size, oldest deleted first.

Restoring a checkpoint is deliberately NOT an MCP tool. It replaces the whole scene and discards everything done since, including the user's manual work, so it only exists as Restore checkpoint in the History tab, behind a confirmation. The restore goes through Max's Hold/Fetch mechanism (the copy is placed as maxhold.mx and fetched), so the scene keeps its file name and path and nothing is written to your file until you save.

The window also shows and sets Max's undo levels (theHold.setMaxUndoLevels).

How the main-thread problem is solved

pymxs must only be used from Max's main (UI) thread. The listener never touches Max from its socket threads: every request is queued, and a PySide6 QTimer on the main thread drains the queue, runs the handler and hands the result back through a threading.Event. Max's own Qt event loop fires the timer. max_mcp_start.ms falls back to a System.Windows.Forms.Timer calling max_mcp_listener.pump() if the QTimer cannot be created.

Consequences:

  • A call waits at most timeout seconds for the main thread. If Max is busy (rendering, a long script, a modal dialog blocking the event loop) the call returns a timeout error; a job that had not started is dropped, one already running keeps running and its result is discarded.

  • A long command blocks the Max UI for its duration and cannot be interrupted from outside. Keep max_run_* snippets short or raise timeout deliberately.

  • When Max closes, the socket closes; the MCP server reports "cannot reach the 3ds Max listener" until Max (with the listener) is back. A fresh connection is opened per call, so nothing needs a restart on the MCP side.

Security

  • The listener binds to 127.0.0.1 by default; the HTTP transport too. Binding HTTP to any other address requires a key (the server refuses to start otherwise); clients send Authorization: Bearer <key>.

  • max_run_maxscript / max_run_python execute arbitrary code inside Max with your user rights. On a single-user machine any local process already has that power, so the key is off by default; enable it (Generate + "require shared key") on shared machines or whenever HTTP leaves localhost.

  • The bridge never saves the scene. It writes: the history file, optional checkpoint copies, viewport PNGs where you ask for them, and (only through the window's Install/Remove buttons) the startup loader.

Tests

pip install -e .[dev]
pytest                      # unit tests, no 3ds Max required (fake pymxs, fake undo stack)
python tests/e2e_batch.py   # optional: headless 3dsmaxbatch round trip, needs Max installed

Unit tests cover the protocol/queue/timeout machinery, every handler against a fake pymxs, config precedence, the UI-free settings model, history rotation, undo bookkeeping (own steps only, refusal on user steps, target gone, switch off), checkpoint naming/pruning, and the streamable-HTTP transport with the official MCP client (key required / 401 / public bind refused).

The headless test runs the listener with serve_blocking() on Max's main thread because 3dsmaxbatch has no Qt event loop while a script runs, so the QTimer pump and the window are only exercised in an interactive Max:

  1. Open 3ds Max, run max_side/max_mcp_start.ms.

  2. In a terminal: python -c "from max_mcp import client; print(client.call('info'))" - pump_mode should read qt.

  3. From your MCP client: max_selection, then max_run_python creating a box, then max_undo - the box disappears; press Ctrl+Z / look at the History tab.

Troubleshooting

  • "cannot reach the 3ds Max listener" - Max not running, listener not started, or different ports on the two sides. Check the MAXScript Listener for [MaxMcp] dinleniyor ...; python -m max_mcp.paths confirms paths.

  • Every call times out - the pump is not running (modal dialog, timer never created). Close the dialog; Restart in the window. max_info shows pump_mode and pump_on_main_thread.

  • max_undo refused - a manual step is on top of the AI's; use the window's Revert (it asks) or Ctrl+Z yourself.

  • Port in use - change it in the window (Save + Restart) and re-copy the client config.

  • Viewport capture in batch mode - works, but shows the default headless viewport; meaningful only in interactive Max.

Known limitations (found in live testing)

  • Modal dialogs block the bridge. If a command makes 3ds Max show a modal message box, Max's main thread waits until someone clicks OK. Example: ProBoolean showing "Invalid Boolean". While it waits, every request times out. Prefer operations that do not raise UI, such as building the mesh yourself instead of using a boolean.

  • Operations that commit their own undo records (ProBoolean, for example) are now merged into the single MCP: <tool> #id level by theHold.SuperBegin/SuperAccept. Objects created after such an operation in the same command can still end up outside the undo record. Keep these operations in a separate command, or avoid them.

  • Multi-statement MAXScript runs line by line. Statements before a compile error in a later line have already executed.

What makes it different

Several 3ds Max MCP servers already exist, and some are much larger than this one (150–380 tools). This project makes different trade-offs:

  • The user can see every AI action and roll it back. Each request is listed in a History panel inside Max with its client, code, result and changed objects. The user can return to any listed step with one click. The AI can undo only its own steps (max_undo): it refuses if a manual user step sits in between. Restoring a scene checkpoint is never exposed as a tool. In the projects we looked at, undo was exposed as a tool the AI calls, and we did not find a user-facing history panel with rollback. This was not an exhaustive survey.

  • Settings live inside Max. Port, bind address, shared key, autostart, AI-undo switch, checkpoints and ready-to-copy client configs are all in one dialog. Other projects use config files, environment variables or an installer.

  • The tool set is small on purpose (~10 tools, plus MAXScript and Python for everything else). This means less context for the model and a smaller attack surface.

  • There is no save tool. The bridge never writes over the user's scene file. Checkpoints are copies in a temp folder, and the scene's path and name stay the same.

  • No dependencies on the Max side. It uses only pymxs, the standard library and Max's bundled PySide6. All work runs on Max's main thread. The project is MIT licensed.

Undo has limits, as it does in every DCC. Effects outside the scene are not reverted by undo: files written, renders started, assets exported. The "Undoable" column in the tool table marks these cases.

Türkçe kısa not

Max'te max_side/max_mcp_start.ms çalıştır (pencereden "Install loader" ile startup'a yükleyici konur), sonra istemcine python -m max_mcp.server kaydet (pencerenin "Client configuration" kutusu metni üretir). Köprü sahneyi asla kaydetmez; her değişiklik MCP: <araç> #<id> adlı bir undo kaydı. max_undo yalnız yapay zekânın kendi adımlarını geri alır, araya senin adımın girdiyse reddeder; senin adımlarını da geçen geri dönüş ve kontrol noktası yükleme yalnız penceredeki onaylı düğmelerle yapılır.

License

MIT - see LICENSE.

Available Tools

10 tools
max_historyA

Read the bridge's command history (time, client, tool, summary, duration, ok/error, objects added/removed, selection, undo_state). undo_state is 'on_stack' (max_undo can target it), 'undone' or 'gone'. full=True includes complete args and output.

NameRequiredDescriptionDefault
fullNo
toolNo
limitNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does disclose real behavioral traits: the exact record shape, the three undo_state lifecycle values, and that full=True returns complete args and output. It omits whether history is bounded, truncated by limit, or persisted across sessions, which leaves a gap for a read tool with no safety annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences with zero waste; the returned-field list sits in a compact parenthetical and the most decision-relevant fact (undo_state semantics) is pushed early. Nothing is repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description need not explain returns, and it still supplies the undo_state vocabulary that the schema lacks. Missing only the filtering/limit behavior, which matters for predictable invocation but is a narrow gap given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the two unexplained parameters (`tool`, `limit`) are documented nowhere at all — the agent cannot tell from either source that `tool` filters the history by tool name or that `limit` defaults to 30. The description compensates for `full` only, leaving two of three parameters opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read the bridge's command history') and enumerates the record fields returned, so the agent knows exactly what it gets. It does not position itself against named siblings such as max_info or max_undo beyond the undo_state note, so sibling differentiation is only partial.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the description explains when to set full=True and links 'on_stack' records to max_undo, which is genuinely useful routing. But it never says when to call this tool versus max_info or max_query_objects, and gives no guidance on the `tool` filter or the limit default.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_infoA

Check the connection and return Max version, open scene path, dirty flag, units, object/selection counts, renderer and listener status.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the burden; it does signal that this is a connection/state inspection that returns information rather than changing anything. However, it never states outright that it is read-only or non-destructive, nor whether the connection check can fail in a particular way, leaving safety and failure semantics to inference.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence: the action first, then the payload. It is efficient, but the long tail of return fields partly duplicates what the output schema already enumerates, so a few of those clauses add less than they could.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only status tool with a declared output schema, the description is essentially sufficient: an agent knows what calling it yields and can rely on the schema for the exact shape. The only real gap is that it does not say when to prefer it over the more targeted query siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies; there is nothing for the description to disambiguate. The enumerated return fields are extra information, though they overlap with the output schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Check') plus an enumerated set of returned facts (Max version, scene path, dirty flag, units, counts, renderer, listener status), which makes the resource clear. It is implicitly distinguishable from siblings like max_query_objects and max_layers because it returns environment-level state rather than object lists, but it never names those siblings to draw the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Check the connection' hints that this is a good first call to verify the Max session is alive before other operations, but that is left implicit. There is no explicit when-to-use/when-not guidance and no mention of alternatives for narrower queries such as selection or layer inspection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_layersA

List all layers with hidden/frozen/current flags and object counts.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of disclosure; it does convey that this is a non-destructive listing and what fields come back. It says nothing about ordering, scope (all layers vs. active scene), or pagination behavior, which are the remaining behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no waste; every phrase (layers, flags, object counts) maps to information the caller needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and an output schema present, the description needn't explain return structure, and it covers the essentials for a simple listing tool. Missing only minor scoping detail on which layers are enumerated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. The description correctly implies no filtering arguments are needed, matching the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('layers') and enumerates the returned attributes (hidden/frozen/current flags, object counts). This clearly separates it from the mutating sibling max_set_layer_hidden, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implied usage only: the read-only listing framing suggests when to reach for it, but there is no explicit statement of when to use this versus max_info or max_query_objects, and no exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_query_objectsB

Find scene objects. name_pattern is a MAXScript wildcard ('Wall_*', 'door', case-insensitive); class_name matches classOf (e.g. 'Editable_Poly', 'Box'); layer matches the layer name. detail=True adds bbox, transform, material, user properties.

NameRequiredDescriptionDefault
layerNo
limitNo
detailNo
class_nameNo
name_patternNo
selected_onlyNo

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the full load. It discloses that matching is case-insensitive and that detail=True enriches results with bbox, transform, material and user properties, which is genuinely useful. However, it never states that this is a read-only query, nor how the default limit of 100 truncates results, which matters for a scene scan returning potentially thousands of objects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with the action front-loaded and parameter explanations following. Every clause carries information; the only flaw is the slightly telegraphic phrasing around detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the enrichment produced by detail is well covered. But for a 6-parameter tool with zero schema descriptions and no annotations, omitting limit and selected_only leaves meaningful gaps in what the agent needs to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains name_pattern (wildcard syntax plus examples), class_name (matches classOf with examples), layer, and detail. That leaves limit and selected_only completely undocumented, meaning an agent cannot tell how truncation works or that selection filtering is even available.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource, 'Find scene objects', which tells the agent exactly what the tool returns. It does not distinguish itself from siblings like max_selection, which overlaps when selected_only is used, but the purpose itself is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the filtering semantics (name/class/layer), but there is no explicit statement of when to prefer this over max_selection or max_layers, and no exclusions or prerequisites. An agent must infer the routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_run_maxscriptA

Execute MAXScript inside Max and return the value of the last expression. (format/print output goes to Max's Listener window; return values instead.) undo=True wraps the code in an undo record.

NameRequiredDescriptionDefault
codeYes
undoNo
timeoutNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does real work: it discloses that format/print output goes to Max's Listener rather than being captured, that the last expression's value is what returns, and that undo=True wraps execution in an undo record. The only undisclosed behavior is what timeout actually does when exceeded.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action and return behavior, with the output-redirection caveat and undo semantics following. No filler; only the parenthetical phrasing is slightly awkward.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the Listener caveat is a valuable addition. However, for an arbitrary-code-execution tool with no annotations, the missing timeout semantics and the absent differentiation from max_run_python leave meaningful gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains the effect of `undo` well, but says nothing about the `timeout` parameter (units, default, behavior on expiry) and adds only indirect meaning for `code`. Two of three parameters remain underspecified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: execute MAXScript inside Max, and adds that the last expression's value is returned. It implicitly distinguishes itself from max_run_python by naming the language, but never explicitly says so.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the language ('MAXScript'), with no explicit when-to-use or when-not guidance. The most important routing decision, MAXScript here versus Python via max_run_python, is left entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_run_pythonB

Execute Python (Max's own 3.11 with pymxs) inside Max. rt (pymxs.runtime) and pymxs are predefined. A single expression returns its value; for multi-line code assign to result. print() output is returned too.

NameRequiredDescriptionDefault
codeYes
undoNo
timeoutNo

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose genuinely useful behavior: predefined `rt`/`pymxs` globals, expression-vs-`result` return semantics, and captured print output. It says nothing about side effects on the Max scene, sandboxing, or what the `undo` and `timeout` parameters actually do, which are the risk-relevant traits for arbitrary code execution.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the action and environment, then the return-value rules. No filler; only minor cost is the slightly cryptic backtick formatting around `rt`.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Return-value explanation is present (and an output schema exists, so that is close to redundant), and the execution environment is covered. For a tool that runs arbitrary code, the omission of undo semantics, timeout behavior, and scene-mutation implications leaves meaningful gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate for all three parameters. It handles `code` well (single expression returns value; multi-line must assign to `result`; print output returned) but never mentions `undo` or `timeout`, leaving two parameters entirely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Execute Python ... inside Max', plus the runtime context (3.11 with pymxs). It implicitly separates itself from the sibling max_run_maxscript by naming the language, but never explicitly contrasts the two, so an agent must infer which to choose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance and no explicit alternative named, despite max_run_maxscript being an obvious sibling. Nothing tells the agent when Python is preferable to MaxScript, or what the undo/timeout defaults imply for safe use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_selectionB

List the currently selected objects (name, class, layer, position; with detail=True also bbox, transform, parent, material, user properties).

NameRequiredDescriptionDefault
limitNo
detailNo

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; it does disclose that this is a non-mutating listing and that detail=True expands the returned fields (bbox, transform, parent, material, user properties). It omits behavior such as what happens when nothing is selected or whether results are capped/truncated by limit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the action and resource, with the detail-mode fields cleanly bracketed. The parenthetical field list is dense but every item is informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, and the description covers the detail mode well. The unexplained 'limit' parameter and the absence of any differentiation from max_query_objects leave gaps for a tool in a crowded sibling set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate: it explains 'detail' well by enumerating the extra fields, but says nothing about 'limit' (default 200), leaving the agent to guess whether it truncates results or is ignored.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('currently selected objects') plus the exact fields returned. It does not explicitly distinguish itself from the sibling max_query_objects, which is the main alternative for listing objects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus max_query_objects (which presumably queries arbitrary objects rather than the live selection), nor any mention of prerequisites such as the selection being non-empty. Usage must be inferred from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_set_layer_hiddenA

Hide (hidden=True) or show (hidden=False) a layer by name. Undoable.

NameRequiredDescriptionDefault
nameYes
hiddenNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the behavioral burden; 'Undoable' is a genuinely useful disclosure about reversibility. However, it doesn't say what happens on an unknown layer name (error vs no-op) or any permission requirements, leaving key mutation behavior unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero waste; the primary action and its parameter mapping are front-loaded before the undo note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be covered, and the description does explain the toggle and its undoability. The remaining gap is edge-case behavior (invalid name) for an otherwise simple two-parameter mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It does clarify the meaning of the 'hidden' boolean (True=hide, False=show), which adds real value, but 'name' semantics (exact match, case sensitivity, path vs leaf) are left entirely unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Hide... or show... a layer by name') and even disambiguates the boolean mapping inline (hidden=True/False). An agent can distinguish this from siblings like max_layers (listing) or max_selection without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The toggle semantics are spelled out, which implies when to use it, but there is no explicit guidance on when to prefer this over alternatives or any preconditions. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_undoA

Undo the bridge's OWN scene changes: either the last steps undo records or everything down to and including history entry to_history_id. Only records labelled 'MCP: #' are undone; if a user's manual step sits in between the call is refused and names it (the user can revert past it from the settings window). Fails when the target has left the undo stack or when AI undo is disabled in the settings window.

NameRequiredDescriptionDefault
stepsNo
to_history_idNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses the labelling filter, the refusal-on-interleaved-manual-step behavior (including that the error names the step), the stale-target failure, and the 'AI undo disabled' failure. That is exactly the preconditions and failure-mode detail an agent needs before calling a mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then constraint, then failure modes, and no sentence is filler. The middle sentence is multi-clause and dense, but the density is carrying real semantic content rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an unannotated two-parameter mutation tool, the description covers selection semantics, filtering, refusal conditions, and failure states, and an output schema exists so return values need not be explained. Nothing essential to calling it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the prose must compensate, and it largely does: `steps` is defined as a count of most-recent undo records and `to_history_id` as an inclusive history-entry boundary, with "either ... or" implying mutual exclusivity. It does not state what happens if both are supplied or how the defaults (1 and 0) interact.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb + resource ("Undo the bridge's OWN scene changes") with an explicit scope qualifier that separates it from generic history browsing siblings like max_history. The two modes of selection (last `steps` records vs. down to `to_history_id`) are stated up front.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly frames the context: it only undoes records labelled 'MCP: <tool> #<id>' and refuses when a manual step sits in between, pointing the user to the settings window instead. The one gap is that it never tells the agent to consult max_history to discover valid `to_history_id` values.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

max_viewport_captureA

Grab the active viewport to a PNG file and return its path and size. path defaults to %TEMP%/max-mcp/capture_.png. max_size limits the longer edge (0 = keep the viewport resolution).

NameRequiredDescriptionDefault
pathNo
max_sizeNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the default output path timestamp pattern and how max_size affects resolution, plus that it returns path and size. However, it omits whether files are overwritten, permission needs for the target directory, or failure behavior when no viewport is active.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with the core action front-loaded and zero filler. The default path and size semantics follow logically. Slightly more structure (e.g., explicit param labeling) could help but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return value explanation isn't required, and both optional parameters are documented with defaults. For a simple, side-effect-light capture tool this is nearly complete; only edge-case behavior (no active viewport, unwritable path) is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does: it explains path's default (%TEMP%/max-mcp/capture_<timestamp>.png) and that max_size limits the longer edge with 0 meaning keep viewport resolution. Both undocumented parameters gain meaningful semantics beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Grab the active viewport to a PNG file'. The resource (viewport capture) is inherently distinct from all listed siblings, which are query/script/inspection tools. It doesn't explicitly name a sibling to differentiate, which keeps it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (capture the current viewport for visual inspection) but never states when to use this versus siblings like max_info or max_query_objects. There are no exclusions or alternatives named, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 10 tool updatesv0.2.0
    • First observedmax_history
    • First observedmax_info
    • First observedmax_layers
    • First observedmax_query_objects
    • First observedmax_run_maxscript
    • First observedmax_run_python
    • First observedmax_selection
    • First observedmax_set_layer_hidden
    • First observedmax_undo
    • First observedmax_viewport_capture

TDQS

A3.7/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct resource or action: scene info, layers, selection, object querying, layer visibility, viewport capture, MAXScript execution, Python execution, history, and undo. The two execution tools are clearly separated by language, and query vs. selection tools are distinguished by scene-wide filtering vs. current selection. No pair appears to do the same thing.

Naming Consistency4/5

All names share the max_ prefix and use snake_case, which makes the set predictable. However, some tools are noun-based (max_layers, max_info, max_selection, max_history) while others are verb-based (max_query_objects, max_set_layer_hidden, max_run_maxscript), so the pattern is not fully uniform.

Tool Count5/5

Ten tools is a well-scoped set for a 3ds Max bridge: it covers introspection, selection/query, layer visibility, viewport capture, scripting escape hatches, history, and undo. Each tool has a clear role, and the count avoids both thinness and bloat.

Completeness4/5

The surface covers core bridge operations well, including scene introspection, object discovery, viewport capture, arbitrary MAXScript/Python execution, command history, and undo. Dedicated tools for common lifecycle actions such as scene save/open, render/export, or direct object creation/transformation are absent, though the scripting tools provide workarounds.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Enables AI assistants to directly control Autodesk 3ds Max through natural language to create models, set materials, adjust lighting, and automate animations. It bridges the Model Context Protocol with 3ds Max via a TCP socket to execute Python and MAXScript commands.
    24
    18
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Connect AI agents to Autodesk 3ds Max through the Model Context Protocol, enabling natural language control of scene creation, materials, modifiers, rendering, and plugin workflows.
    253 PyPI
    348
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A local MCP server that enables MCP-compatible AI clients to inspect and control the currently open scene in a running Autodesk VRED Professional 2027 instance via a secure bridge, supporting read-only inspection and gated mutations like selection, visibility, transforms, and screenshots.
    MIT
  • F
    license
    B
    quality
    B
    maintenance
    Enables AI agents to control a live 3ds Max session directly, including creating and editing objects, materials, animation, and scene inspection, with undo support.
    17
    -