Forge operators¶
Complete inventory of every bpy.ops.forge.* operator implemented by the Forge addon (addon/Forge): signature with defaults, selection requirement (poll), behavior and the MCP tool that wraps it. Workflow rules live in the create / modify skills — this guide is the exhaustive lookup; fetch a single entry with forge_skill(name="operators", section="<operator name>").
Agent usage rules¶
- Contract: this inventory is the complete supported operator surface. Strictly follow it — never read, search or infer behavior from the addon source code (
addon/Forge/**); source internals are not part of the interface. When an operator, parameter or enum value you need is not documented here or in thecreate/modifyskills, it has no supported implementation: report the missing capability as feedback instead of improvising a workaround. - Operators are grouped below as creation, definition, utility, file/IO, CoACD, UI-only popups, and add-on infrastructure. Sources:
ops/creation.py,ops/materials.py,ops/definition.py,ops/utilities.py,ops/io_ops.py,ops/coacd.py,ops/properties_operators.py,core/props.py,settings.py,mcp/operator.py. - Selection semantics: every
pollbelow means each selected object must match the listedForge_Model_Typeset (check_selected_model_types, all-of). Operators additionally allowing an empty selection say "or nothing selected". Creation/definition operators read the ordered selection (selected_ordercustom property) — MCPselect=[...]lists set that order. - Creation / definition operators open a parameter dialog only via
INVOKE_DEFAULT; calling withEXEC_DEFAULTplus keyword arguments runs headless — this is what the MCP wrappers do. Prefer the wrapper (forge_create_*,forge_define_*, ...) whenever one exists: it manages selection, waits for modal jobs and returnscreatednames. - Modal operators (
import_mjcf,export_mjcf,create_attach,create_include) returnRUNNING_MODALand keep working on a UI timer; pollForge_Props.is_importing/is_exporting/is_attaching/is_includingfor completion, or use the MCP wrappers that wait. Every modal operation also claims the scene-level slotForge_Props.modal_operation_active(withmodal_operation_name/token/status/message); a second modal operator fails while the slot is held — read, never write, these state properties. - UI-only operators (section below) cannot be driven by agents — the agent path is direct property assignment (
obj.Forge_<Type>.<property>,scene.Forge_Props,scene.Forge_Temp_Props) documented in themodifyskill. - File-browser helpers (
forge.temp_fileetc.) are drivable viaEXEC_DEFAULTwith an explicitfilepath, but setting the target property directly is simpler and is what the MCP wrappers do.
Creation operators¶
forge.create_geometry(geometry_type='BOX', size_box=(1, 1, 1), size_radius=0.5, size_height=1)¶
- Requires: selection all in
[LINK, FRAME, REPLICATE], or nothing selected.- One
visualper selected object as its child at local[0, 0, 0]; nothing selected → standalone visual in theWorldcollection at the 3D cursor.geometry_typein[BOX, CAPSULE, CYLINDER, SPHERE](MESH excluded); size param per type:BOX→size_box(full dimensions),SPHERE→size_radius,CAPSULE/CYLINDER→size_radius+size_height(full straight-section height; the socket stores the same full height).- MCP:
forge_create_geometry.
forge.create_collider(collider_type='BOX', create_method='GEOMETRY_TYPE', auto_size=False, use_min_as_height=False, size_box=(1, 1, 1), size_radius=0.5, size_height=1)¶
- Requires: selection all in
[LINK, FRAME], or allVISUAL, or nothing selected.create_method='GEOMETRY_TYPE'(default): only withvisualselection — auto-detects shape from each visual (MESHincluded); size params unused andcollider_typeis ignored (the collider takes the visual's own geometry type).create_method='COLLIDER_TYPE': explicitcollider_typein[BOX, CAPSULE, CYLINDER, SPHERE, MESH]with size params orauto_size=True(measure from selected visual);MESHbakes the visual geometry into a convex mesh collider and needs avisualselection.auto_size=Trueis ignored with alink/frameselection or no selection: with no selected visual to measure, explicit size parameters (or their defaults) are used. Areplicateselection is not accepted by this operator.use_min_as_height=True: CAPSULE/CYLINDER only — the height is taken from the selectedvisual's smallest bounding-box axis rather than its largest, and the shape is oriented along that axis. Only effective together withauto_size=True; with explicitsize_radius/size_heightthe values are used as given and the flag is ignored.- MCP:
forge_create_collider(exposes this parameter asmin_is_height).
forge.create_height_field()¶
- Requires: nothing selected. Creates a root
hfieldnode (no parent) in theWorldcollection at the 3D cursor.- MCP:
forge_create_height_field.
forge.create_plane()¶
- Requires: nothing selected. Creates a root
planenode (no parent) in theWorldcollection at the 3D cursor.- MCP:
forge_create_plane.
forge.create_site(site_type='SPHERE', size_box=(0.2, 0.2, 0.2), size_radius=0.1, size_height=0.2)¶
- Requires: selection all
LINK. Onesiteper selected link as its child.site_typein[BOX, CAPSULE, CYLINDER, SPHERE]; size param mapping ascreate_geometry.- MCP:
forge_create_site.
forge.create_link()¶
- Requires: selection all in
[LINK, FRAME, REPLICATE], or all in[VISUAL, COLLIDER], or nothing selected.- No parameters. Based on
[LINK, FRAME, REPLICATE]→ child at local[0, 0, 0]; based onVISUAL/COLLIDERwith forge parent → sibling under that parent at the object's local position; based on parentlessVISUAL/COLLIDER→ link at the object's location markedRoot Link; nothing selected →Worldcollection root candidate (mark withforge.mark_root_link).- MCP:
forge_create_link.
forge.create_joint(joint_type='HINGE')¶
- Requires: selection all
LINK. Onejointper selected link as its child.joint_typein[FREE, BALL, SLIDE, HINGE].- MCP:
forge_create_joint.
forge.create_actuator(actuator_type='POSITION')¶
- Requires: selection all in
[LINK, JOINT, TENDON]. Oneactuatorper selected target.actuator_typein[GENERAL, MOTOR, POSITION, VELOCITY, ADHESION].- MCP:
forge_create_actuator.
forge.create_tendon(tendon_type='FIXED')¶
- Requires: at least 2 selected, all
JOINT, every joint subtype in[SLIDE, HINGE].- Creates a single
tendonfrom the ordered selection; each target item exportscoef(default0.5).tendon_typecurrently onlyFIXED.- MCP:
forge_create_tendon.
forge.create_equality(equality_type='CONNECT')¶
- Requires: exactly 2 selected, all
LINK, allJOINTor allSITE.- Dynamic type items:
JOINTselection →JOINTonly (joint-coupling equality);LINK/SITEselection →CONNECT/WELD.- Ordered selection: first object is
target1, second istarget2.- MCP:
forge_create_equality.
forge.create_sensor(Sensor_Type, set_ref=False, set_xbody=False, set_subtree=False)¶
- Requires: selection all
LINK, allJOINT, allSITE, all in[VISUAL, COLLIDER], or all in[LINK, SITE, VISUAL, COLLIDER, CAMERA](mixed — also covers camera-only selections).- Available
Sensor_Typeitems are computed from the selection / flags — full ranges in thecreateskill (joint →Jointpos/Jointvel; site →Touch…Contact; link → frame + subtree types; visual/collider → frame types +Contact; camera → frame types only).set_ref=True: needs exactly 2 selected — first is target, second is reference.set_xbody/set_subtree: only forLINKtargets, mutually exclusive (xbody→ xbody frame sensors,subtree→Contactonly).- Contact subtree workflow: require exactly two
LINKroots and use bothset_ref=Trueandset_subtree=True. Ordered selection maps the first root tosubtree1(target), the second tosubtree2(ref); both must be explicitly set and verified in the exported sensor.- MCP:
forge_create_sensor.
forge.create_contact(contact_type)¶
- Requires: at least 2 selected, all
LINK, or all in[VISUAL, COLLIDER, PLANE, HFIELD].- Dynamic type items:
LINKselection →EXCLUDE(default); geom selection →PAIR(default).- Creates one
contactper pair combination of the ordered selection (n·(n−1)/2 objects).- MCP:
forge_create_contact.
forge.create_light(light_type, light_mode)¶
- Requires: selection all
LINK, or nothing selected.- Dynamic items: nothing selected →
light_type[DIRECTIONAL, SPOT, POINT],light_mode[FIXED, TRACK, TRACKCOM](defaultsDIRECTIONAL/FIXED); links selected →light_type[SPOT, POINT](defaultSPOT); 1–2 links →light_modefull[TARGETBODY, TARGETBODYCOM, FIXED, TRACK, TRACKCOM](defaultTARGETBODY), 3+ links or nothing selected →[FIXED, TRACK, TRACKCOM](defaultFIXED).- 1 link +
TARGETBODY/TARGETBODYCOM→ single world light at the 3D cursor targeting that link; 2 links + targeting mode → single light, first selected is position, second is target; otherwise one light per link as its child. Nothing selected → world light at the 3D cursor.- MCP:
forge_create_light.
forge.create_camera(camera_type='PERSPECTIVE', camera_mode)¶
- Requires: selection all
LINK, or nothing selected.camera_typein[PERSPECTIVE, ORTHOGRAPHIC]. Dynamiccamera_mode: 1–2 links selected → full[TARGETBODY, TARGETBODYCOM, FIXED, TRACK, TRACKCOM](defaultTARGETBODY); nothing or 3+ links selected →[FIXED, TRACK, TRACKCOM](defaultFIXED).- 1 link + targeting mode → single world camera at the 3D cursor targeting that link; 2 links + targeting mode → single camera, first selected is position, second is target; otherwise one camera per link as its child. Nothing selected → world camera at the 3D cursor.
- MCP:
forge_create_camera.
forge.create_frame()¶
- Requires: selection all in
[LINK, REPLICATE, FRAME], or nothing selected.- One
frameper selected object as its child; nothing selected →Worldroot at the 3D cursor.- Shift+Click in the UI reverses parenting (selected objects become children of the new frame) —
reverse_parentis a plain class attribute, not an operator parameter; scripts useforge_define_parentinstead.- MCP:
forge_create_frame.
forge.create_replicate(count=0, sep='', offset=(0, 0, 0), euler=(0, 0, 0))¶
- Requires: selection non-empty and all in
[CAMERA, LIGHT, VISUAL, COLLIDER, SITE, LINK, FRAME, ATTACH, REPLICATE].- Creates a single
replicateobject with the selection as its sources; copies differ byoffset/eulerand are named withsep.- Moves the sources (with their subtrees) into the replicate's own collection, created viewport-hidden. Blender cannot select objects there, so a later operator over them selects nothing and fails its
poll(context is incorrect).- MCP:
forge_create_replicate.
forge.create_inertial(inertial_model_type='VISUAL', check_mesh_valid=False)¶
- Requires: selection all
LINK(links without children are skipped).- Collects children of the selected type (
VISUALorCOLLIDER), recursively throughFRAMEdescendants, without entering childLINKhierarchies; needs at least one matching geometry object.- Mesh validation runs only when
check_mesh_valid=True. A failed check skips the Link. Primitive shapes use analytic mass and inertia;MESHgeometry requires TetGen. A successful calculation creates a newINERTIALchild without replacing existing inertials.- MCP:
forge_create_inertialuses the defaults above and accepts onlyselect. For the other calculation options, use the documented operator parameters throughforge_execute.
forge.create_material(category, material, use_existing=True)¶
- Requires: selection non-empty and all in
[VISUAL, HFIELD, PLANE](materials can be assigned to visual, height-field and plane geometry).category/materialare exact bundled Forge PBR library names;use_existing=Trueassigns an existing same-named datablock as-is,Falsealways rebuilds (Blender suffixes the taken name).- Assignment uses the first object-level material slot, creating it when empty; the operator does not write primitive geometry-node material sockets.
- MCP:
forge_create_material.
forge.assign_material(material)¶
- Requires: selection non-empty and all in
[VISUAL, HFIELD, PLANE].materialis the exact name of an existing Blender material, including any Blender suffix.- Reuses its nodes and settings as-is, assigning the first object-level material slot on each selected object. Does not create or copy a material; other slots and unselected object assignments are preserved.
- MCP: call through
forge_executeafter reading the modify skill.
Definition operators¶
forge.define_model_type(Model_Type)¶
- Requires: selection all
UNDEFINED(plain Blender objects). AvailableModel_Typefrom the Blender object type:EMPTY→LINK;MESH→VISUALorCOLLIDER;LIGHT→LIGHT;CAMERA→CAMERA.- Side effects:
VISUALsets geometry typeMESH, group2,contype/conaffinity0, prefixGEO_;COLLIDERsets typeMESH, group3, prefixCOL_;LINKprefixLNK_;LIGHTmaps Blender type (SUN→DIRECTIONAL, elseSPOT/POINT,AREAcancels), modeFIXED, prefixLIT_;CAMERAmapsORTHO/PERSP(others cancel), modeFIXED, prefixCAM_. Objects move to the matching type collection (WORLDwhen parentless).- MCP:
forge_define_model_type.
forge.define_geometry_type(geometry_type='MESH', apply_to_all=False)¶
- Requires: selection all
VISUAL.geometry_typein[BOX, CAPSULE, CYLINDER, SPHERE, MESH]; size preserved when switching shapes; toMESHbakes current geometry and unlocks scale; fromMESHuses object dimensions as size.apply_to_all=Falseapplies to the active object only.- MCP:
forge_define_geometry_type.
forge.define_collider_type(collider_type='SPHERE', apply_to_all=False)¶
- Requires: selection all
COLLIDER. Behavior asdefine_geometry_type(size preserved,MESHbakes).- MCP:
forge_define_collider_type.
forge.define_site_type(site_type='SPHERE', apply_to_all=False)¶
- Requires: selection all
SITE.site_typein[BOX, CAPSULE, CYLINDER, SPHERE]; size preserved.- MCP:
forge_define_site_type.
forge.define_joint_type(joint_type='HINGE', apply_to_all=False)¶
- Requires: selection all
JOINT.joint_typein[FREE, BALL, SLIDE, HINGE]; updates the joint shape gizmo.- MCP:
forge_define_joint_type.
forge.define_actuator_type(actuator_type='POSITION', apply_to_all=False)¶
- Requires: selection all
ACTUATOR.actuator_typein[GENERAL, MOTOR, POSITION, VELOCITY, ADHESION].- MCP:
forge_define_actuator_type.
forge.define_parent()¶
- Requires: an active object plus selection. Active
VISUALis refused — acolliderunder avisualis not exported. Active in[LINK, FRAME, REPLICATE]→ parents selected objects of type[LINK, VISUAL, COLLIDER, JOINT, SITE, LIGHT, CAMERA, FRAME, REPLICATE, ATTACH]to it; children of a selectedVISUALare lifted to the same parent first. Active object itself is skipped.- World position of children is preserved.
- Every reparented object moves into the collection of its model type (
visual→Visual,collider→Collider, …), so a root object inWorldleaves it.- Ordered selection matters: parent first, children after (MCP
forge_define_parent).- MCP:
forge_define_parent.
Utility operators¶
forge.batch_rename(new_name='', numerate='###')¶
- Requires: any selection. Renames each selected object to
{new_name}_{index}with zero padding ofnumeratelength, index from 0 in Blender's selected-object iteration order; this is not the recorded click order.- MCP:
forge_batch_rename.
forge.set_instance_idname()¶
- Requires: selection all in
[LINK, FRAME, VISUAL]. Applies only to selectedLINKobjects (Frame and Visual objects are skipped): writesobj["INSTANCE_IDNAME"] = Forge_Props.instance_body(an object reference that survives renames), or removes the property when no instance body is chosen. Reports how many links were marked / cleared. Links already markedINSTANCE_LINKare refused (warning).- The instance source is a link marked with
INSTANCE_LINK(viaforge.mark_instance_link);Forge_Props.instance_body(panel Instance field) only accepts marked links. A marked instance link never appears as a<body>in the multibody tree; a referenced one feeds the<asset>section with its subtree's meshes / materials, while an unreferenced one exports nothing at all (warned).- Export semantics: the instance link's children are written into every link marked with
INSTANCE_IDNAME = <instance link name>. Each such link keeps its own body element (name / pos / quat / link props) but its children are replaced by the copy, with every element name prefixed"<instance>_<name>"(camera / lighttargetrefs inside the subtree renamed too). Instance subtrees gather no assets of their own, and global sections (actuator/sensor/tendon/equality/contact) are not duplicated per instance — don't reference instance-link-internal elements from them. A marked link nested inside a template subtree is never copied as a<body>either — its content still only exports through the placeholders referencing it.- MCP:
forge_set_instance_idname.
forge.select_by_tag()¶
- Requires: object mode. Adds every scene object whose name contains the main scene's
Forge_Props.select_tagto the current selection — it does not clear first, so pre-selected objects stay selected.- An empty
select_tagmatches every object name (""is contained in any string) and therefore selects the whole scene.- MCP:
forge_select_by_tag.
forge.select_by_model_type()¶
- Requires: Object Mode. Adds selectable objects whose Forge type matches the main scene's
Forge_Props.select_model_typeto the current selection; existing selection is preserved.- No dedicated MCP wrapper. Set
Forge_Props.select_model_typeand invoke the documented operator throughforge_executewhen needed.
forge.select_hulls()¶
- Requires: object mode. Selects every scene object whose full name matches the addon preference
coacd_name_templateinterpreted as a pattern (?→ any name segment,#→ digits) — the same template CoACD uses to name hulls.- MCP:
forge_select_hulls.
forge.scale_gizmo_size()¶
- No poll. Sets gizmo display of selected objects — or all objects in the blend file when nothing is selected — using the main scene's
Forge_Props.gizmo_scalerelative to each object's stored base size: modifierSocket_0forJOINT/CONTACT/EQUALITY/TENDON/ACTUATOR/SENSOR,empty_display_sizeforLINK/FRAME/ATTACH.INERTIALdisplay is determined by mass and inertia and is excluded.- MCP:
forge_scale_gizmo_size.
forge.mark_root_link()¶
- Requires: selection all in
[LINK, FRAME, REPLICATE]. Parentless objects are marked withobj["Root Link"] = True; objects that have a parent are first unparented while preserving world transform, then marked.- MCP:
forge_mark_root_link.
forge.mark_instance_link()¶
- Requires: selection all
LINK. Togglesobj["INSTANCE_LINK"] = Trueper selected link (run again to unmark); reports how many links were marked / unmarked.- A marked instance link never exports as a
<body>; its children are written under everyINSTANCE_IDNAMElink. A referenced marked link feeds the<asset>section with its subtree's meshes / materials; an unreferenced one exports nothing at all (warned).Forge_Props.instance_body's picker only lists marked links.- MCP:
forge_mark_instance_link.
forge.mesh_check()¶
- Requires: selection all
VISUAL. Reports self- and pairwise intersections (boundary-only contact and separating coplanar faces are valid — details in themodifyskill). Run beforecreate_inertial/ export.- MCP:
forge_mesh_check.
forge.add_tendon_target_item()¶
- Requires: the active object is
TENDON. Appends an item toobj.Forge_Tendon.targets.itemsand setsactive_indexto the new last entry (filltarget/coefafterwards via property access).- No MCP wrapper — prefer
forge_set_tendon_targets(name, [...])which replaces the whole ordered path.
forge.remove_tendon_target_item()¶
- Requires: the active object is
TENDON. Removes the item atForge_Tendon.targets.active_indexand clamps the index.- No MCP wrapper — prefer
forge_set_tendon_targets.
File and IO operators¶
forge.import_mjcf(filepath)¶
- Modal (
BaseProgressOperator).filepathargument wins, else the main scene'sForge_Props.import_file_path; missing file cancels.- Destructive: clears scene objects, collections, non-main scenes and orphaned data before rebuilding the model (stage order: compiler → option → statistic → visual → asset → worldbody → contact → equality → tendon → actuator → sensor → replicates).
- Requires the
Forge Libraryasset library (auto-recreated from the addon'slib/assetswhen missing).- MCP:
forge_import_mjcf(setsimport_file_path/import_material, invokes, waits foris_importingto clear).
forge.export_mjcf()¶
- Modal. No filepath parameter — always writes the main scene's
Forge_Props.export_path(resolved against the blend file whenrel_pathis set).- Stage order: gather assets → export images / hfields / visual meshes / collider meshes → XML sections (include, compiler, option, statistic, visual, asset, world, contact, equality, tendon, actuator, sensor) → write file.
update_forge_onlyskips asset file writes;use_glbswitches visual mesh format.- Empty mesh visuals/colliders (zero vertices or triangles) are skipped, so no mesh asset or
<geom mesh="...">reference is emitted.- A World environment image connected through an Environment Texture is exported as
<texture type="envhdr">and restored to the main scene World on import.- MCP:
forge_export_mjcf(setsexport_path+rel_path=Falseand the two flags, refuses existing destinations withoutoverwrite=True, waits foris_exportingto clear).
forge.create_attach()¶
- Modal. Requires: exactly 1 selected
[LINK, REPLICATE, FRAME]object (becomes the attach parent), or nothing selected.- Reads the main scene's
Forge_Temp_Props:tmp_file,tmp_model,tmp_prefix,tmp_link— all must be non-empty (file must exist). Imports the external model into its own scene / collection, then creates theattachreference.- A file already
included in the scene yields an empty attach task list and reportsAttach fail: list index out of range; attach and include take separate files.- MCP:
forge_create_attach(setsForge_Temp_Propsdirectly from thefile/model/prefix/linkarguments and waits).
forge.create_include()¶
- Modal. Requires: nothing selected. Reads
Forge_Temp_Props.tmp_include; imports the file's collections into the scene but only an<include>tag is written on export (file content never exported).- MCP:
forge_create_include(setstmp_includedirectly).
forge.temp_file(filepath)¶
- UI file browser (
*.xml) feedingcreate_attach. On execute storesForge_Temp_Props.tmp_file, derivestmp_model(basename) andtmp_prefix(model + "_"), resetstmp_linkto"None".- Agent path: assign
Forge_Temp_Propsdirectly (whatforge_create_attachdoes); drivable viaEXEC_DEFAULTwithfilepath=....
forge.temp_link(tmp_link)¶
- UI enum dialog listing the
<body>links parsed fromForge_Temp_Props.tmp_file(get_link_namesidentifiers); stores the choice intmp_link.- Agent path: assign
Forge_Temp_Props.tmp_linkdirectly with the link identifier.
forge.temp_include(filepath)¶
- UI file browser (
*.xml) feedingcreate_include; storesForge_Temp_Props.tmp_include.- Agent path: assign
Forge_Temp_Props.tmp_includedirectly.
forge.file_path(filepath)¶
- UI file browser; stores the chosen path in
Forge_Props.import_file_path(used byimport_mjcfinvoke).- Agent path: assign
Forge_Props.import_file_pathdirectly.
forge.export_path(filepath)¶
- UI file browser; appends
.xmlwhen missing and storesForge_Props.export_path; setsrel_path=Truewhen the path lies under the blend file's directory (stores a blend-relative path), elserel_path=False.- Agent path: assign
Forge_Props.export_path(+rel_path) directly.
CoACD¶
forge.coacds(threshold=0.05, max_convex_hull=-1, preprocess_mode='Auto', preprocess_resolution=50, resolution=2000, mcts_nodes=20, mcts_iterations=100, mcts_max_depth=3, pca=False, merge=True, decimate=False, max_ch_vertex=128, extrude=False, extrude_margin=0.01, apx_mode='CH', seed=0)¶
- Requires: object mode with one or more selected
VISUALobjects; needs thecoacdpython package (install via addon preferences pip).- Decomposes triangle faces from the evaluated mesh without applying a Triangulate modifier to or deleting the source object; processing can take minutes.
- Creates one mesh object per convex hull in the source object's first collection, named from the add-on preference
coacd_name_template(?→ source object name,#→ 1-based zero-padded hull index). Each hull hasForge_Model_Type='COLLIDER', geometry typeMESH, the source's world transform, and the same parent as the source.- Key parameters:
threshold(concavity termination),max_convex_hull(only withmerge),preprocess_modein[Auto, On, Off], sampling / MCTS controls,decimate+max_ch_vertex,extrude+extrude_margin,seed.- MCP:
forge_coacd(single object by name).
UI-only popup operators¶
All 16 open invoke_props_dialog windows whose edits happen through the live UI; their execute is a no-op for agents. Every value they expose is reachable by direct property assignment — see the parameter reference in the modify skill. Never call them from scripts.
forge.properties_global— sceneForge_GlobalConfig(compiler/option/statistic).forge.properties_visual— sceneForge_VisualConfig(<visual>section groups).forge.properties_link,forge.properties_shape,forge.properties_shape_site,forge.properties_hfield,forge.properties_plane,forge.properties_joint,forge.properties_actuator,forge.properties_tendon,forge.properties_equality,forge.properties_contact,forge.properties_sensor,forge.properties_light,forge.properties_camera,forge.properties_replicate— per-objectForge_<Type>property groups.
Addon infrastructure operators¶
Not model-authoring; manage the environment and the MCP bridge itself. No MCP wrappers.
forge.pip_install(package)— install / upgrade a python package into Blender's environment (addon preferences dependency rows).forge.ensure_pip()— bootstrap pip / setuptools / wheel when missing.forge.mcp_server_start— start the in-Blender TCP bridge the MCP server connects to; refuses in--backgroundmode (useblender --background --command forge_mcpinstead).forge.mcp_server_stop— stop the bridge and unregister its polling timer.