Skip to main content

MCP server

Pro feature

The MCP server ships in Custom Widgets Pro. The free package under GPLv3 does not include it.

See plans

Custom Widgets exposes an MCP (Model Context Protocol) server, so an AI agent can do the things you would otherwise do by hand: open a form in Qt Designer, change a property, run the app, take a screenshot, read the widget catalogue, click a button and check what happened.

It is not a chat wrapper around the docs. The agent drives the real Designer process and the real running app.

Starting it

This is the part that catches everyone, so it comes first.

python -m Custom_Widgets.mcp --transport http --port 8765

Leave it running. Agent sessions then connect automatically.

An HTTP MCP server is never started by the client

The client only dials in. If nothing is already listening on port 8765, every session reports the server as unavailable — with no error explaining why. Nine times out of ten "MCP is broken" means "the daemon is not running".

Check it:

ss -ltn | grep 8765          # expect LISTEN on 127.0.0.1:8765

The transport flag is not optional. The default is stdio, while clients are configured for http, so starting it bare gives you a working server that nothing is configured to reach.

Why HTTP and not stdio

Deliberate. The server is a shared daemon: several sessions and agents dial into one process, so commands against a project are serialised by that project's worker. A stdio server could not do that — every client would spawn its own isolated copy, and two agents editing the same form would race.

Custom_Widgets-mcp says command not found

That console script only exists once the package is installed (pip install -e .). Working straight from a source tree, it is not on PATH. Use python -m Custom_Widgets.mcp — the same entry point.

Client configuration

{
"mcpServers": {
"custom-widgets": { "type": "http", "url": "http://127.0.0.1:8765/mcp" }
}
}

Options

FlagDefaultNotes
--transportstdioMust be http to match the client config
--host127.0.0.1Loopback only
--port8765Must match the client config
--project-dircwdThe server chdirs here and sets the project root

What the agent can do

51 tools, in five groups.

Qt Designer

Launch and quit it, open and close forms, create a form from a template or from raw .ui XML, read a form's generated source, inspect the widget tree, set widget properties undoably, screenshot it, and drive its menus and docks.

ToolPurpose
designer_launch / designer_quitStart and stop Designer
designer_open_files / designer_close_filesManage open forms
designer_new_form / designer_new_form_xmlCreate from a template or from XML
designer_set_form_xmlReplace a live form's XML
designer_get_ui_codeRead the generated source
designer_get_object_infoInspect the widget tree
designer_set_widget_propertyChange a property (undoable)
designer_screenshotSee the current state

The running app

Run, stop and restart the project app, read its output, then treat it as a live target: list windows, find widgets, click, set text, set properties, invoke slots, screenshot.

ToolPurpose
designer_run_app / designer_stop_app / designer_restart_appLifecycle
designer_app_logsRead stdout and stderr
app_find / app_click / app_set_textDrive the UI
app_invoke / app_set_propertyReach past the UI
app_screenshot / app_object_treeObserve the result

This is what makes the agent able to verify its own change rather than assume it worked.

The widget catalogue

ToolPurpose
widgets_catalogEvery widget, its properties, signals and defaults
widget_signatureThe .pyi type signature for one widget
render_widgetRender a widget headless and look at it
search_examplesSearch the shipped examples and docs

Styling

designer_set_stylesheet, designer_qss_window, designer_refresh_icons and project_write_style drive the QSS/theme editor and write project SCSS.

Design rules

design_lint runs the same checks as the CLI — glyph icons used as icons, hardcoded hex colours that should be token roles, drop shadows — so an agent gets told off for the same things a human would.

Workspaces

workspaces_status and designer_open_workspace exist because one daemon serves several projects. Switching workspace re-points Designer and the app runner at another project folder without restarting anything.

See also