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:
conradomateu
2026-03-16 15:25:07 +01:00
parent 4cec559dbc
commit 82c23d79c7
2 changed files with 62 additions and 8 deletions
+20
View File
@@ -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)
+42 -8
View File
@@ -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)