feat: add auto-start option for RPC server on FreeCAD launch
Adds an opt-in setting to automatically start the RPC server when FreeCAD opens, removing the need to manually click "Start RPC Server" each session. Changes: - New `auto_start_rpc` setting in freecad_mcp_settings.json (default: false) - New "Auto-Start Server" checkable menu item under FreeCAD MCP menu - InitGui.py uses QTimer.singleShot(0) to start the server after FreeCAD finishes initialization, only when the setting is enabled - Consolidated _sync_remote_toggle_state into _sync_toggle_states to handle both Remote Connections and Auto-Start checkboxes Tested on macOS with FreeCAD 1.0. Cross-platform: uses only PySide QtCore.QTimer and FreeCAD.getUserAppDataDir() (no OS-specific code). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ class FreeCADMCPAddonWorkbench(Workbench):
|
||||
commands = [
|
||||
"Start_RPC_Server",
|
||||
"Stop_RPC_Server",
|
||||
"Toggle_Auto_Start",
|
||||
"Toggle_Remote_Connections",
|
||||
"Configure_Allowed_IPs",
|
||||
]
|
||||
@@ -28,3 +29,22 @@ class FreeCADMCPAddonWorkbench(Workbench):
|
||||
|
||||
|
||||
Gui.addWorkbench(FreeCADMCPAddonWorkbench())
|
||||
|
||||
|
||||
def _auto_start_mcp():
|
||||
try:
|
||||
from rpc_server import rpc_server
|
||||
|
||||
settings = rpc_server.load_settings()
|
||||
if not settings.get("auto_start_rpc", False):
|
||||
return
|
||||
|
||||
msg = rpc_server.start_rpc_server()
|
||||
FreeCAD.Console.PrintMessage(f"[MCP] Auto-start: {msg}\n")
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintWarning(f"[MCP] Auto-start failed: {e}\n")
|
||||
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
QtCore.QTimer.singleShot(0, _auto_start_mcp)
|
||||
|
||||
@@ -32,6 +32,7 @@ _SETTINGS_FILENAME = "freecad_mcp_settings.json"
|
||||
_DEFAULT_SETTINGS = {
|
||||
"remote_enabled": False,
|
||||
"allowed_ips": "127.0.0.1",
|
||||
"auto_start_rpc": False,
|
||||
}
|
||||
|
||||
|
||||
@@ -709,26 +710,59 @@ class ConfigureAllowedIPsCommand:
|
||||
return True
|
||||
|
||||
|
||||
class ToggleAutoStartCommand:
|
||||
def GetResources(self):
|
||||
return {
|
||||
"MenuText": "Auto-Start Server",
|
||||
"ToolTip": "Automatically start the RPC server when FreeCAD launches.",
|
||||
"Checkable": True,
|
||||
}
|
||||
|
||||
def Activated(self, checked=0):
|
||||
settings = load_settings()
|
||||
settings["auto_start_rpc"] = bool(checked)
|
||||
save_settings(settings)
|
||||
|
||||
if settings["auto_start_rpc"]:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"MCP RPC server will start automatically on next FreeCAD launch.\n"
|
||||
)
|
||||
else:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"MCP RPC server auto-start disabled.\n"
|
||||
)
|
||||
|
||||
def IsActive(self):
|
||||
return True
|
||||
|
||||
|
||||
FreeCADGui.addCommand("Start_RPC_Server", StartRPCServerCommand())
|
||||
FreeCADGui.addCommand("Stop_RPC_Server", StopRPCServerCommand())
|
||||
FreeCADGui.addCommand("Toggle_Auto_Start", ToggleAutoStartCommand())
|
||||
FreeCADGui.addCommand("Toggle_Remote_Connections", ToggleRemoteConnectionsCommand())
|
||||
FreeCADGui.addCommand("Configure_Allowed_IPs", ConfigureAllowedIPsCommand())
|
||||
|
||||
|
||||
def _sync_remote_toggle_state():
|
||||
"""Sync the Remote Connections checkbox with saved settings on startup."""
|
||||
def _sync_toggle_states():
|
||||
"""Sync checkable menu items with saved settings on startup."""
|
||||
try:
|
||||
settings = load_settings()
|
||||
enabled = settings.get("remote_enabled", False)
|
||||
main_window = FreeCADGui.getMainWindow()
|
||||
toggle_map = {
|
||||
"Remote Connections": settings.get("remote_enabled", False),
|
||||
"Auto-Start Server": settings.get("auto_start_rpc", False),
|
||||
}
|
||||
found = 0
|
||||
for action in main_window.findChildren(QtWidgets.QAction):
|
||||
if action.text() == "Remote Connections":
|
||||
action.setChecked(enabled)
|
||||
return
|
||||
if action.text() in toggle_map:
|
||||
action.setChecked(toggle_map[action.text()])
|
||||
found += 1
|
||||
if found == len(toggle_map):
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
# Retry if menu not ready yet
|
||||
QtCore.QTimer.singleShot(2000, _sync_remote_toggle_state)
|
||||
QtCore.QTimer.singleShot(2000, _sync_toggle_states)
|
||||
|
||||
|
||||
QtCore.QTimer.singleShot(2000, _sync_remote_toggle_state)
|
||||
QtCore.QTimer.singleShot(2000, _sync_toggle_states)
|
||||
Reference in New Issue
Block a user