NitroStack Logo
/python
/sdk
/widgets

UI Widgets

Agent skill: nitrostack-python-ui-widgets

Python widgets are static HTML, not React trees from @nitrostack/widgets. Bind a route with @widget and return domain JSON from the tool.

Python
from nitrostack import tool, widget, WidgetOptions, WidgetCsp, ExecutionContext

@tool(name="show_card", description="Product card", input_schema=CardInput)
@widget("card")
async def show_card(self, input: CardInput, context: ExecutionContext) -> dict:
    return {"name": "Widget", "price": 9.99}

Place HTML at widgets/out/{route}.html (for example widgets/out/card.html). The SDK registers ui://widget/card.html and sets mode-gated _meta on tools/list and tools/call.

Object form:

Python
@widget(WidgetOptions(
    route="chart",
    prefers_border=True,
    csp=WidgetCsp(connect_domains=["https://api.example.com"]),
))

NITROSTACK_APP_MODE (default universal)

ModeTool _metaResource MIME
universalBoth OpenAI and MCP Apps keystext/html;profile=mcp-app
openaiopenai/outputTemplate, ui/templatetext/html
mcp-app_meta.ui (resourceUri, visibility, CSP)text/html;profile=mcp-app

Helpers: get_app_mode, is_openai_mode, is_mcp_app_mode, get_widget_mime_type.

Inspector and Studio

MCP Inspector: HTTP + stateless, Apps tab. Connect to http://localhost:3000/mcp (no trailing slash). Live preview: http://localhost:3000/widgets/preview. Do not use widgets/preview.html as the live result.

NitroStudio folder-connect looks for a TypeScript project (package.json with @nitrostack/core and src/index.ts). A Python server will not detect. Use Inspector HTTP or a custom Streamable HTTP URL. Turn Authentication off unless the OAuth template is configured.

There is no Python equivalent of the TypeScript Widget SDK / file-upload guides.