PyWryBLOCK
PyWry is a cross-platform app factory, rendering engine and UI toolkit for Python that produces native desktop, web, and notebook experiences from a single API.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
PyWry is a cross-platform rendering engine and desktop UI toolkit for Python. One API, three output targets:
- Native window — OS webview via PyTauri. Not Qt, not Electron. Use unrestricted HTML/CSS/JS.
- Jupyter widget — anywidget + FastAPI + WebSocket, works in JupyterLab, VS Code, and Colab.
- Browser tab — FastAPI server with Redis state backend for horizontal scaling.
Build Once, Render Anywhere: Prototype interactive data apps in a Jupyter Notebook, easily deploy them as web apps, and seamlessly compile them into secure, lightweight standalone desktop executables via pywry[freeze].
Installation
Python 3.10–3.14, virtual environment recommended.
pip install pywry
Core extras:
Chat provider extras:
d870349f2c13OBSERVED · 2026-10-07Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add pywry-frontend-assets --env GEMINI_API_KEY=${GEMINI_API_KEY} --env NVIDIA_API_KEY=${NVIDIA_API_KEY} --env PYWRY_DEPLOY__AUTH_ENABLED=${PYWRY_DEPLOY__AUTH_ENABLED} --env PYWRY_OAUTH2__CLIENT_ID=${PYWRY_OAUTH2__CLIENT_ID} -- npx -y pywry-frontend-assets{
"mcpServers": {
"pywry-frontend-assets": {
"command": "npx",
"args": [
"-y",
"pywry-frontend-assets"
],
"env": {
"GEMINI_API_KEY": "${GEMINI_API_KEY}",
"NVIDIA_API_KEY": "${NVIDIA_API_KEY}",
"PYWRY_DEPLOY__AUTH_ENABLED": "${PYWRY_DEPLOY__AUTH_ENABLED}",
"PYWRY_OAUTH2__CLIENT_ID": "${PYWRY_OAUTH2__CLIENT_ID}"
}
}
}
}Exposed tools (67)
39 read · 24 write · 4 destructive. Blast radius: 4 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
build_div | read | |
build_ticker_item | read | |
chat_get_history | read | |
chat_manage_thread | read | |
chat_register_command | read | |
chat_send_message | write | |
chat_set_typing | write | Show or hide the typing indicator in a chat widget. |
chat_stop_generation | write | |
chat_update_settings | write | |
create_chat_widget | write | |
create_widget | write | |
destroy_widget | destructive | Destroy a widget and clean up resources. |
download | write | Trigger a file download in the browser. |
export_widget | read | |
get_component_docs | read | |
get_component_source | read | |
get_events | read | |
get_skills | read | |
get_widget_app | read | |
inject_css | read | |
list_resources | read | |
list_widgets | read | List all active widgets with their URLs. |
navigate | read | Navigate the widget to a new URL (client-side redirect). |
remove_css | destructive | Remove previously injected CSS by style_id. |
send_event | write | |
set_content | write | |
set_style | write | |
show_dataframe | read | |
show_plotly | read | |
show_toast | read | Display a toast notification in the widget. |
show_tvchart | read | |
tvchart_add_indicator | write | |
tvchart_add_markers | write | |
tvchart_add_price_line | write | |
tvchart_add_series | write | |
tvchart_apply_options | write | |
tvchart_auto_scale | read | Toggle auto-scale on the price axis. Emits ``tvchart:auto-scale``. |
tvchart_change_interval | read | |
tvchart_chart_type | read | |
tvchart_compare | read | |
tvchart_drawing_tool | read | |
tvchart_fit_content | read | Fit all bars to the visible area. Emits ``tvchart:time-scale`` with ``{fitContent: true}``. |
tvchart_fullscreen | read | Toggle chart fullscreen mode. Emits ``tvchart:fullscreen``. |
tvchart_list_indicators | read | |
tvchart_log_scale | read | Toggle the logarithmic price scale. Emits ``tvchart:log-scale``. |
tvchart_open_layout | read | Open the layout picker dialog. Emits ``tvchart:open-layout``. |
tvchart_redo | read | Redo the last undone chart action. Emits ``tvchart:redo``. |
tvchart_remove_indicator | destructive | |
tvchart_remove_series | destructive | |
tvchart_request_state | read | |
tvchart_save_layout | write | |
tvchart_save_state | write | |
tvchart_screenshot | read | Take a screenshot of the chart. Emits ``tvchart:screenshot``. |
tvchart_set_visible_range | write | |
tvchart_show_indicators | read | Open the indicator picker panel. Emits ``tvchart:show-indicators``. |
tvchart_show_settings | read | Open the chart settings modal. Emits ``tvchart:show-settings``. |
tvchart_symbol_search | read | |
tvchart_time_range | read | |
tvchart_time_range_picker | read | Open the date-range picker dialog. Emits ``tvchart:time-range-picker``. |
tvchart_toggle_dark_mode | read | Toggle the chart |
tvchart_undo | read | Undo the last chart action. Emits ``tvchart:undo``. |
tvchart_update_bar | write | |
tvchart_update_series | write | |
update_marquee | write | |
update_plotly | write | Update an existing Plotly chart with new data/layout. |
update_theme | write | Switch widget theme to dark/light/system. |
update_ticker_item | write |
Trust audit
BLOCKgrade F · trust 42/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | WARN |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (7 observation(s))
- Network
- declared (6 observation(s))
- Shell
- declared (9 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
return eval(getterExpr);
return eval(formatterExpr);
return eval(setterExpr);
eval(event.payload.script);
btn.click = eval('(' + btn.click + ')');icon.icns
icon.icns
mod = importlib.import_module(module_path)
ext_mod = importlib.import_module(mod_name)
module = importlib.import_module(module_name, package=__package__)
module = importlib.import_module(f"{name}.dbapi2")"beacon",
widget_id: str, _request: Request, reason: str = "beacon"
return f"redis://{username}:{password}@{host}:{port}/0"bad_url = f"redis://admin:wrongpassword@{host}:{port}/0"bad_url = f"redis://fakeuser:fakepass@{host}:{port}/0"ssh_key = """-----BEGIN OPENSSH PRIVATE KEY-----
"private_key": "-----BEGIN RSA PRIVATE KEY-----\\nMIIE...base64...\\n-----END RSA PRIVATE KEY-----\\n",
ssh_key = """-----BEGIN OPENSSH PRIVATE KEY-----
assert "-----BEGIN OPENSSH PRIVATE KEY-----" in retrieved
"private_key": "-----BEGIN RSA PRIVATE KEY-----\\nMIIE...\\n-----END RSA PRIVATE KEY-----\\n",
<div class="pywry-modal-overlay" id="modal-settings" style="display:none">
<div class="view-list" style="display:none">List View Content</div>
<div class="view-chart" style="display:none">Chart View Content</div>
<div id="section-data" style="display:none">Data content...</div>
Gates applied: no_behavioural_pass.
d870349f2c13full audit observations/trust-audit/mcp-server/deeleeramone__pywry.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | d870349f2c13 | BLOCK | F | 42 | first audit |
Questions
What is the PyWry MCP server?
PyWry is a cross-platform app factory, rendering engine and UI toolkit for Python that produces native desktop, web, and notebook experiences from a single API.
What tools does PyWry expose?
67 in total: 39 read-only, 24 that write, and 4 that can delete or overwrite (destroy_widget, remove_css, tvchart_remove_indicator, tvchart_remove_series). Every one is listed on this page with its risk.
Is PyWry safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (42/100) and found 5 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 4 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does PyWry need?
It reads GEMINI_API_KEY, NVIDIA_API_KEY, PYWRY_DEPLOY__AUTH_ENABLED, PYWRY_OAUTH2__CLIENT_ID, PYWRY_OAUTH2__CLIENT_SECRET, PYWRY_SERVER__INTERNAL_API_TOKEN, PYWRY_SERVER__SSL_KEYFILE, PYWRY_SERVER__SSL_KEYFILE_PASSWORD, PYWRY_SERVER__STRICT_WIDGET_AUTH, PYWRY_SERVER__WEBSOCKET_REQUIRE_TOKEN and PYWRY_SQLITE_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does PyWry run?
It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as pywry-frontend-assets.
How current is this page?
The grade is for one exact copy of the source (d870349f2c13), read on 2026-10-07. The repository is watched and re-audited when it changes.