Skip to main content
Glama

edit_object

Modify existing 3D objects in FreeCAD when creation tools cannot handle the task. Change object properties and update designs directly through the MCP server interface.

Instructions

Edit an object in FreeCAD. This tool is used when the create_object tool cannot handle the object creation.

Args: doc_name: The name of the document to edit the object in. obj_name: The name of the object to edit. obj_properties: The properties of the object to edit. Returns: A message indicating the success or failure of the object editing and a screenshot of the object.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
doc_nameYes
obj_nameYes
obj_propertiesYes

Implementation Reference

  • Primary MCP handler for the 'edit_object' tool. Proxies the call to FreeCAD RPC server and handles response with screenshot.
    @mcp.tool() def edit_object( ctx: Context, doc_name: str, obj_name: str, obj_properties: dict[str, Any] ) -> list[TextContent | ImageContent]: """Edit an object in FreeCAD. This tool is used when the `create_object` tool cannot handle the object creation. Args: doc_name: The name of the document to edit the object in. obj_name: The name of the object to edit. obj_properties: The properties of the object to edit. Returns: A message indicating the success or failure of the object editing and a screenshot of the object. """ freecad = get_freecad_connection() try: res = freecad.edit_object(doc_name, obj_name, {"Properties": obj_properties}) screenshot = freecad.get_active_screenshot() if res["success"]: response = [ TextContent(type="text", text=f"Object '{res['object_name']}' edited successfully"), ] return add_screenshot_if_available(response, screenshot) else: response = [ TextContent(type="text", text=f"Failed to edit object: {res['error']}"), ] return add_screenshot_if_available(response, screenshot) except Exception as e: logger.error(f"Failed to edit object: {str(e)}") return [ TextContent(type="text", text=f"Failed to edit object: {str(e)}") ]
  • RPC server method for edit_object that queues the GUI-safe edit task.
    def edit_object(self, doc_name: str, obj_name: str, properties: dict[str, Any]) -> dict[str, Any]: obj = Object( name=obj_name, properties=properties.get("Properties", {}), ) rpc_request_queue.put(lambda: self._edit_object_gui(doc_name, obj)) res = rpc_response_queue.get() if res is True: return {"success": True, "object_name": obj.name} else: return {"success": False, "error": res}
  • Core implementation that edits the FreeCAD object properties in the GUI thread, handling special properties like References.
    def _edit_object_gui(self, doc_name: str, obj: Object): doc = FreeCAD.getDocument(doc_name) if not doc: FreeCAD.Console.PrintError(f"Document '{doc_name}' not found.\n") return f"Document '{doc_name}' not found.\n" obj_ins = doc.getObject(obj.name) if not obj_ins: FreeCAD.Console.PrintError(f"Object '{obj.name}' not found in document '{doc_name}'.\n") return f"Object '{obj.name}' not found in document '{doc_name}'.\n" try: # For Fem::ConstraintFixed if hasattr(obj_ins, "References") and "References" in obj.properties: refs = [] for ref_name, face in obj.properties["References"]: ref_obj = doc.getObject(ref_name) if ref_obj: refs.append((ref_obj, face)) else: raise ValueError(f"Referenced object '{ref_name}' not found.") obj_ins.References = refs FreeCAD.Console.PrintMessage( f"References updated for '{obj.name}' in '{doc_name}'.\n" ) # delete References from properties del obj.properties["References"] set_object_property(doc, obj_ins, obj.properties) doc.recompute() FreeCAD.Console.PrintMessage(f"Object '{obj.name}' updated via RPC.\n") return True except Exception as e: return str(e)
  • Utility function to set properties on FreeCAD objects, with special handling for Placement, Vectors, References, ShapeColor, etc.
    def set_object_property( doc: FreeCAD.Document, obj: FreeCAD.DocumentObject, properties: dict[str, Any] ): for prop, val in properties.items(): try: if prop in obj.PropertiesList: if prop == "Placement" and isinstance(val, dict): if "Base" in val: pos = val["Base"] elif "Position" in val: pos = val["Position"] else: pos = {} rot = val.get("Rotation", {}) placement = FreeCAD.Placement( FreeCAD.Vector( pos.get("x", 0), pos.get("y", 0), pos.get("z", 0), ), FreeCAD.Rotation( FreeCAD.Vector( rot.get("Axis", {}).get("x", 0), rot.get("Axis", {}).get("y", 0), rot.get("Axis", {}).get("z", 1), ), rot.get("Angle", 0), ), ) setattr(obj, prop, placement) elif isinstance(getattr(obj, prop), FreeCAD.Vector) and isinstance( val, dict ): vector = FreeCAD.Vector( val.get("x", 0), val.get("y", 0), val.get("z", 0) ) setattr(obj, prop, vector) elif prop in ["Base", "Tool", "Source", "Profile"] and isinstance( val, str ): ref_obj = doc.getObject(val) if ref_obj: setattr(obj, prop, ref_obj) else: raise ValueError(f"Referenced object '{val}' not found.") elif prop == "References" and isinstance(val, list): refs = [] for ref_name, face in val: ref_obj = doc.getObject(ref_name) if ref_obj: refs.append((ref_obj, face)) else: raise ValueError(f"Referenced object '{ref_name}' not found.") setattr(obj, prop, refs) else: setattr(obj, prop, val) # ShapeColor is a property of the ViewObject elif prop == "ShapeColor" and isinstance(val, (list, tuple)): setattr(obj.ViewObject, prop, (float(val[0]), float(val[1]), float(val[2]), float(val[3]))) elif prop == "ViewObject" and isinstance(val, dict): for k, v in val.items(): if k == "ShapeColor": setattr(obj.ViewObject, k, (float(v[0]), float(v[1]), float(v[2]), float(v[3]))) else: setattr(obj.ViewObject, k, v) else: setattr(obj, prop, val) except Exception as e: FreeCAD.Console.PrintError(f"Property '{prop}' assignment error: {e}\n")
  • Proxy method in FreeCADConnection class that forwards edit_object calls to the XML-RPC server.
    def edit_object(self, doc_name: str, obj_name: str, obj_data: dict[str, Any]) -> dict[str, Any]: return self.server.edit_object(doc_name, obj_name, obj_data)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/heok-yongssun/freecad-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server