인터페이스는 현지화되어 있으며, Skill 소개와 설명 문서는 선택한 언어로 AI가 자동 번역합니다. 코드·명령어·경로·전문 용어는 원문을 유지하며 원작자 문서가 우선합니다.
Skills 둘러보기
개발 및 엔지니어링 · SKILL.md

3dsmax-mcp

3dsmax-mcp

Tool choices, workflows, and MAXScript pitfalls for controlling 3ds Max via MCP.

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill 문서

GitHub

name: 3dsmax-mcp description: Tool choices, workflows, and MAXScript pitfalls for controlling 3ds Max via MCP.

3ds Max MCP — Agent Guide

Each tool's description documents its parameters, modes and limits. This guide covers what no single tool can: routing, tool choice, cross-tool workflows, safety rules and MAXScript pitfalls.

Tool Profile Routing

  • Full/core: operational tools such as query_scene and create_object are advertised directly; call them by name.
  • Progressive: if only list_toolsets, describe_toolset and call_tool are advertised, never call an operational name as a top-level tool. Pick a capability with list_toolsets, load only that group with describe_toolset, then invoke it through call_tool(name=..., arguments=...). If the exact tool and arguments are already known, call_tool can dispatch directly.

Principles

  • Match the user's request. Do not run setup, discovery or scene analysis by habit, and do not call get_bridge_status or get_session_context as a preamble.
  • Prefer a dedicated tool over raw MAXScript whenever one clearly matches.
  • Do not render unless the user asks. Viewport capture is fine when visual proof helps.
  • Verify meaningful edits with query_scene(action="delta"), re-inspection or a capture.
  • Keep mutating calls sequential. Concurrent writes interleave undo transactions: a crash, then persistent corruption such as phantom successes and wrong handles.
  • Multiple Max instances: the first native connection stays bound to that Max and never silently switches. Use list_max_instances, select_max_instance(pid), get_selected_max_instance and release_max_instance. MCP_MAX_PIPE or MCP_MAX_PID pins the startup target (the pipe takes precedence); release also clears it.

Tool Choice

  • Scene reads: query_scene (overview/filter/class/property/selection/delta), get_hierarchy, get_instances, get_dependencies, walk_references. resolve_node_refs gives canonical handle/name/path identity. scene_qa checks naming, transforms, hierarchy and timeline only; it never judges meshes or visuals, and its fix repairs naming only (preview with dry_run=true unless approved).
  • Inspection: inspect_object, inspect_properties, analyze_node_orientation (before rig, vehicle or camera transforms). For unfamiliar plugin APIs: introspect_class, introspect_instance, discover_plugin_classes, map_class_relationships, inspect_plugin_class. Arnold materials such as ai_standard_surface may be missing from class discovery; use inspect_plugin_class or introspect_osl.
  • Edits: object, modifier, material, controller, organization (manage_layers, manage_groups, manage_selection_sets) and viewport tools. Use scene_patch for a preflighted batch of renames, relative transforms, flags or parenting committed as one undo step.
  • Fallbacks: execute_maxscript, or execute_python (pymxs, needs safe mode off), only when no dedicated tool exists.
  • Scene files: manage_scene (hold/fetch/reset/save/info). inspect_max_file, search_max_files, merge_from_file and batch_file_info work without loading a scene.
  • Interactive sessions: watch_scene follows the user's actions.

Workflows

Identity and tokens

  • Node handles are stable only within the loaded scene. Cross-check cached handles with name or path, and refresh after a reset or load.
  • Pass expected_scene_seq from resolve_node_refs to scene_patch when stale targeting matters; selection changes do not invalidate it.
  • Guarded edits take the token from a fresh inspection: expected_mesh, expected_view, curve_token, expected_style, expected_controller, plugin schema/state tokens, expected_dialog. A refused token means inspect again, never bypass the guard.

Modeling

  • Polygon edits: inspect_mesh or an AGENT VIEWPORT capture → pick_component with the capture's view_token as expected_view → mesh_edit(expected_mesh=...) → verify with inspect_mesh, geometry_qa or a capture.
  • Construction: create_mesh for computed vertex/face arrays; loft_mesh for parameterized section lofts; curve_model, inspect_curve and edit_curve for curve-driven forms (read curve-construction.md first); draw_spline plus Lathe/Extrude/Bevel_Profile/Sweep through add_modifier, refined with spline knot edits or edit_vertices conform.
  • Edits act on the editable base cage and preserve modifiers above it. Collapsing (convert=true, collapse_modifier_stack) happens only when requested.
  • boolean_operation: prefer inline cutters (named, atomic, no scene litter). Non-live operands are consumed, so never consume a node other tools still reference by name.
  • After placing parts that should sit on or join each other, run contact_check and judge reported depth against the design intent.

Materials

  • Create and assign: assign_material, create_material_from_textures, smart_import, palette_laydown. They default to OpenPBR; pass material_class for another renderer. Share an existing material with assign_material(names=[...], source_name=...).
  • Edit: set_material_property, set_material_properties, set_sub_material, create_texture_map, set_texture_map_properties. Switch pipelines with create_shell_material, replace_material and batch_replace_materials.
  • Audit: get_material_slots (prefer slot_scope="map"), get_materials, and material_roles (follow next_offset; check complete and truncated).
  • OSL: write_osl_shader, then introspect_osl before wiring. The shader name must match shader_name; OSLMap lowercases parameter names.
  • material_class is the material's own class name: PhysicalMaterial, not Physical (the camera).

Lighting and plugin settings

  • lighting_capabilities → create_lights → inspect_lights → edit_lights. Never infer integer enum meanings. RGB is linear in the rendering color space, Kelvin is explicit, and EXR/HDR inputs get no extra gamma.
  • Other plugin settings: inspect_plugin_class or inspect_plugin_instance with schema_version=2, then plugin_patch with the returned schema and state tokens. Shared or animated resources need deliberate handling.

Viewport and capture

  • Open agent_viewport(action="open") before inspection captures. Navigation and captures then default to it and never redirect into the user's view; source="active" targets the user's view explicitly. Release and reopen after a scene load.
  • set_viewport aims by eye and target without creating a camera. Use capture_viewport, capture_multi_view or capture_screen(enabled=True) for stills and frame-buffer crops.
  • Start interactive previews (agent_viewport(action="render")) and production renders (render_automations) only on request. A capture never certifies convergence or finished denoising.

Animation and controllers

  • Script controllers: script_controller inspect → validate → apply with expected_controller. A controller that returns zero at every frame has failed; inspect it with sample_frames.
  • Other controllers: assign_controller, inspect_controller, inspect_track_view, set_controller_props, add_controller_target. Pass list_wireable_params paths, including their [#Parameters] levels, to wire_params unchanged; get_wired_params and unwire_params read and remove wiring.
  • keyframe_tracks: timeline reads or sets frame rate, current frame and range. list inspects keys; parent numKeys is often 0 because keys live on Bezier Float sub-controllers. Retimes need time/times or both from_time and to_time. bake and resample skip list, constraint, expression, script and motion-capture controllers. Use loop, or match with order=hierarchy, for parented rigs. tracks takes exact tokens only: all, position/pos, rotation/rot, scale/scl, transform/tm.
  • On animated objects, edit keys with keyframe_tracks; transform_object rewrites keys at the current frame.

Plugins and assets

  • tyFlow graph work: read tyflow-graphs.md completely before acting.
  • RailClone (7.3.5+): get_railclone_style → edit the XML → set_railclone_style(expected_style=...) → verify with get_railclone_output. Read railclone.md first.
  • Data Channel and Max Creation Graph: read procedural-graphs.md completely before acting.
  • Forest Pack: scatter_forest_pack, then hide the source meshes.
  • Cosmos: cosmos_search → cosmos_download → cosmos_import. Repeating a completed import adds another instance.
  • Plugin surfaces: discover_plugin_surface, get_plugin_manifest, and resource://3dsmax-mcp/plugins/{name}/manifest|guide|recipes|gotchas.

Dialogs

  • execute_maxscript and tool scripts run in Max's quiet mode: prompts such as queryBox, overwrite or missing-file warnings silently take their default answer. Pass execute_maxscript(quiet=False) when the user wants to be asked.
  • A call that opens or waits behind a modal dialog returns BLOCKED_BY_DIALOG with its title, text and buttons. The call keeps running inside Max: never repeat it. Other replies warn while any dialog is open.
  • Read and answer dialogs with max_dialogs. respond presses a button by label or index and returns the interrupted call's result.
  • Choose the button yourself only when the user asked you to proceed without confirmation and the task determines the answer. Otherwise show the user the dialog and ask. Always ask before save, overwrite, discard, Fetch, Reset or licensing choices.
  • A MAXScript error box during a call fails that call with MAX_DIALOG_ERROR. Callback errors appear just after the triggering call returns; the next reply warns, so read the error and acknowledge it.

Results and Errors

  • Replies are a ToolEnvelope dict (ok/result/error/hint), not a JSON string. Tool-authored hints win over automatic ones; hint.suggested_tools may list alternatives.
  • Classify raw structured errors by error, code or status=error|failed, never by message alone.
  • USER_BUSY: Max has an open undo operation and the write was rejected before any change. Continue read-only and retry after it finishes; never bypass it with MAXScript.

Native Core Development

Only when changing the bridge's native C++ handlers; ordinary sessions never need it. reload_native_core (full and progressive profiles) swaps a rebuilt core into the running Max.

  • reload_native_core(action="status") tells you whether reload applies: layout="hot" reloads. static, the shipped layout, cannot; a native change there applies only after the rebuilt plugin is installed and Max restarts.
  • After rebuilding the core, call reload_native_core(action="reload"), check that build changed (a warning flags an unchanged one), then verify the changed behavior through its real tool, not just the status.
  • On any error the previous core keeps serving, unless the message says no core is loaded:
    • CORE_STATIC: static layout. Do not retry.
    • CORE_BUSY (retryable; with wait_ms up to 20000 the tool already retried): native calls were still running (including one waiting on a dialog), Max's main thread was busy (a render), or another reload was running. Let long calls finish or answer the dialog with max_dialogs, then reload, or raise wait_ms (up to 600000).
    • CORE_LOAD_FAILED: the DLL is missing, is not a core build, or would not load or initialize. Fix the cause and rebuild; never retry unchanged.
    • CORE_VERSION_MISMATCH: the core does not match the running shell's interface, SDK, compiler or build configuration. Rebuild Release from the same tree; a change to the shell itself cannot be reloaded.
    • A lost reload response: never resend it; compare build, reloads and last_error from status.
  • A reload stops watch_scene and drops its events; start it again if needed. query_scene(action="delta") positions, dialogs, the agent viewport, armed render jobs and undo history survive. Calls that arrive mid-swap get a retryable CORE_BUSY.
  • A reload cannot apply shell changes: the named pipe, main-thread executor, dialog monitoring (Win32 and Qt), scene journal, agent viewport, render job notifications, undo records, the core loader, and the shell/core interface. Those need the rebuilt plugin installed and a Max restart.
  • Python tool changes need a fresh MCP server process; a reload does not apply them.

execute_maxscript

  • Use it only when no dedicated tool exists: unsupported controller operations, render or environment settings, one-off scripted operations.
  • code is JSON-unescaped once before MAXScript parses it. A BAD_PARAM parse error without a line number almost always means escaping corruption, not bad logic:
    • Use forward slashes in path literals ("C:/assets/tex/") or derive paths at runtime; \" and \U break literals.
    • Do not put \n or \t inside string literals.
    • Keep the script on one line, with statements separated by ;.
    • Debug by shrinking to a known-good core (try (...) catch (getCurrentException() as string)) and adding pieces back.

MAXScript Pitfalls

  • Always pass #noPrompt to importFile, e.g. importFile @"C:/assets/model.fbx" #noPrompt using:FBXIMP; configure importer options first.
  • No parentheses with keyword arguments: Box width:10, not Box() width:10. Box width is X, length is Y, height is Z.
  • Wrap risky code: try (...) catch (ex) (ex).
  • Noise is a texture map; Noisemodifier is the modifier.
  • getDir #temp is Max's temp folder, not the OS temp folder.
  • Convert .NET strings to MAXScript strings before using string methods.
  • snapshotAsMesh returns a world-space TriMesh: read vertices in coordsys world without reapplying node.objectTransform, then delete it. Base-cage poly vertices still need the object transform.
  • Normalize controller and wire display tokens: [#Z Position] becomes [#z_position].
  • getClassInstances Material is invalid because Material is not a MAXClass; use sceneMaterials.
  • getHandleByAnim returns values like 12345P; quote them when building JSON.
  • Open Unwrap UVW with $Box001.modifiers[#Unwrap_UVW].edit(), not only the OpenUnwrapUI macro.
  • TCP fallback is opt-in. If viewport interaction stutters while it runs, stop it and use the native bridge.

MAXScript Reference (bundled)

Read the relevant file before writing unfamiliar MAXScript:

FileCovers
maxscript-core-syntax.mdVariables, scope, types, operators, control flow
maxscript-common-patterns.mdUndo/animate blocks, callbacks, file I/O
maxscript-3dsmax-objects.mdNodes, transforms, hierarchy, properties
maxscript-mesh-poly-ops.mdSub-object mesh/poly ops
maxscript-materials-textures.mdMaterials, texmaps, PBR
maxscript-animation-controllers.mdControllers, constraints, wire params
maxscript-rendering-cameras.mdRender settings, cameras, environment
maxscript-splines-shapes.mdSplines and shapes
maxscript-scripted-plugins.mdScripted geometry, modifiers, utilities
maxscript-ui-rollouts.mdRollout UIs and dialogs
저장한 Skills