Playwright-style MCP server for pywebview apps — lets AI assistants see, control, and debug your Python desktop web UI without modifying your app's source code.
AI assistant → MCP tools → pywebview-mcp server → HTTP bridge → pywebview app
- Screenshot the webview page via CDP (edgechromium/qt)
- Inspect the full DOM tree (tag, id, role, text, bounds)
- Click, type, scroll, press keys — full page interaction
- Find elements by CSS selector, text, role, or tag
- call_api — invoke
js_apimethods directly from Python (skip DOM when the app exposes an API) - eval_js / eval_python — run code in the page or app process
- Read Python logs captured from the app
- Launch and stop the app directly from Claude
Zero changes to your app's source code required.
- Python 3.11+
- pywebview 6.0+
- uv (recommended)
- Windows (tested with WebView2), Linux/macOS (should work with supported renderers)
| Component | Where it runs | Needs pywebview? |
|---|---|---|
MCP server (pywebview-mcp) |
AI client's MCP process | No |
Bridge (via launch_app) |
Inside your pywebview app | Uses project's existing pywebview |
No changes to the target project. launch_app(cwd=…) injects only the
bridge modules via an isolated PYTHONPATH — nothing is added to pyproject.toml,
and the MCP server's dependencies (httpx, cffi, …) never enter the app environment.
Add to %USERPROFILE%\.cursor\mcp.json or project .cursor/mcp.json:
{
"mcpServers": {
"pywebview": {
"command": "uvx",
"args": ["--from", "git+https://github.com/com55/pywebview-mcp", "pywebview-mcp"]
}
}
}Local development:
{
"mcpServers": {
"pywebview": {
"command": "uv",
"args": ["run", "--directory", "/path/to/pywebview-mcp", "pywebview-mcp"]
}
}
}Optional custom port:
"env": { "PYWEBVIEW_MCP_PORT": "7891", "PYWEBVIEW_MCP_CDP_PORT": "9222" }claude mcp add -s user pywebview -- uvx --from git+https://github.com/com55/pywebview-mcp pywebview-mcpOr install the plugin (MCP + skill):
claude plugin install github:com55/pywebview-mcpFrom MCP (recommended — zero project setup):
launch_app(cwd="/path/to/project") # main.py at root
launch_app(cwd="/path/to/project", script="app.py") # other name at root
launch_app(cwd="/path/to/project", script="backend/gui.py") # entry in subfolder
get_launch_help() # full script decision guide
cwd is the project root (pyproject.toml). script is the entry .py relative to cwd.
Manual equivalent (same isolated PYTHONPATH that launch_app builds):
cd your-pywebview-project
# PYTHONPATH must point at a directory that contains *only* pywebview_mcp
# (bridge modules). Do not point it at the MCP server's site-packages.
uv run python -m pywebview_mcp main.pylaunch_app(cwd="/path/to/project")screenshot()+get_dom_tree()- Interact via
click,type_text, orcall_api("get_ui_state") get_logs()/get_app_output()to debug
| Env var | Default | Purpose |
|---|---|---|
PYWEBVIEW_MCP_PORT |
7891 | HTTP bridge (differs from pyside6-mcp's 7890) |
PYWEBVIEW_MCP_CDP_PORT |
9222 | Chrome DevTools for screenshots |
- Screenshots require
edgechromiumorqtrenderer (CDP). Set automatically by the launcher. - Native file dialogs block automation — use
call_apito set paths instead. - Element IDs reset on every app restart — call
get_dom_tree()again. - uvx cache — after updating the package, clear uv cache or use a local path.
pywebview_mcp/server.py— FastMCP stdio server (no pywebview dependency)pywebview_mcp/bridge.py— in-process HTTP bridgepywebview_mcp/__main__.py— monkey-patcheswebview.startfor zero-config injection
MIT