Autonomous Application Building

SkillAI & models

Autonomous PyWry application building using LLM sampling, elicitation, and progress reporting.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Autonomous Application Building skill

What this skill tells your AI

The instructions your AI receives, as published by deeleeramone/pywry in pywry/pywry/mcp/skills/autonomous_building/SKILL.md and read by ahel’s review.

This skill teaches agents how to use PyWry MCP's agentic tools to autonomously design, build, and export complete widget applications from a plain-English description.

When to Use These Tools

Use the agentic tools when you need to:

  • Build a complete PyWry app from a description without manual step-by-step tool calls
  • Deliver a full Python project (main.py, requirements.txt, README.md, widgets/)
  • Interactively gather requirements from the user before generating code
  • Show real-time progress to the user during long build operations

Available Agentic Tools

plan_widget — AI-Planned Widget Spec

Sends the description to the LLM via sampling and returns a validated WidgetPlan JSON object. Use this to inspect the plan before committing to building.

# Returns a WidgetPlan JSON (no widget is created yet)
result = await client.call_tool("plan_widget", {
    "description": "A crypto price dashboard with symbol selector and refresh button"
})
plan = json.loads(result[0].text)
# plan contains: title, html_content, toolbars, callbacks, width, height, ...

build_app — End-to-End Autonomous Builder

The primary tool for autonomous app building. One call:

  1. Samples a WidgetPlan from the description
  2. Registers the widget in the session
  3. Returns widget_id and complete runnable Python code
result = await client.call_tool("build_app", {
    "description": "Task tracker with add/remove buttons and completion percentage",
    "open_window": False  # set True to open a native window immediately
})
data = json.loads(result[0].text)
widget_id  = data["widget_id"]
python_code = data["python_code"]  # paste into a .py and run directly

The returned python_code is a fully self-contained Python script requiring only pywry.

export_project — Complete Python Project Package

Takes one or more widget_ids and generates a full project tree:

my_app/
    main.py            ← entry-point
    requirements.txt   ← dependencies
    README.md          ← quickstart docs
    widgets/
        <widget_id>.py ← one file per widget
result = await client.call_tool("export_project", {
    "widget_ids": ["abc123", "def456"],
    "project_name": "my_dashboard",
    "output_dir": "",          # leave empty to get file contents as JSON
    # "output_dir": "/tmp"     # set to write files to disk
})
data = json.loads(result[0].text)
files = data["files"]  # {relative_path: file_content}

scaffold_app — Interactive Multi-Turn Builder

Uses ctx.elicit() to ask the user questions before generating the plan:

  • App title and description
  • Display mode (native / inline)
  • Optional libraries (Plotly, AG-Grid)
  • Toolbar position
result = await client.call_tool("scaffold_app", {})
# MCP client will prompt the user for each field
data = json.loads(result[0].text)
plan = data["widget_plan"]

Recommended Workflow

Quick build (autonomous)

# 1. Build the app
build = await client.call_tool("build_app", {
    "description": "Your plain-English description here"
})
data = json.loads(build[0].text)

# 2. Save the code
Path("my_widget.py").write_text(data["python_code"])

# 3. Or package as a full project
project = await client.call_tool("export_project", {
    "widget_ids": [data["widget_id"]],
    "project_name": "my_app",
    "output_dir": "./output"  # writes files to disk
})

Inspect-then-build

# 1. Plan first
plan_result = await client.call_tool("plan_widget", {
    "description": "..."
})
plan = json.loads(plan_result[0].text)

# 2. Review and tweak the JSON plan manually
# 3. Then build using the reviewed description

Interactive (with user input)

# Let the user guide the design
scaffold = await client.call_tool("scaffold_app", {})
data = json.loads(scaffold[0].text)

# Build from the collected spec
build = await client.call_tool("build_app", {
    "description": data["collected"]["description"]
})

Progress Reporting

All agentic tools emit report_progress events. Clients that display a progress bar will show real-time status: Planning… → Generating code… → Writing files… → Done


Combining With Other Tools

After build_app you can continue refining using the standard tools:

# Read the skill resource for styling tips
content = await client.read_resource("skill://styling/SKILL.md")

# Update a component dynamically
await client.call_tool("set-content", {
    "widget_id": widget_id,
    "component_id": "main-content",
    "content": "<p>Updated!</p>"
})

# Check events emitted by toolbar buttons
await client.call_tool("get-events", {"widget_id": widget_id})

Tips for Good Results

  • Specificity beats brevity: "A real-time stock ticker with 5 company buttons and a price display area" produces better plans than "a finance app".
  • Mention coloring / layout: "left sidebar with dark theme", "top toolbar with primary variant buttons".
  • Describe interactivity: "clicking a country updates the chart below" triggers better callback planning.
  • Large widgets: Request include_plotly=True or include_aggrid=True in your description if you need charts or tables.

Signals

GitHub stars
93
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
autonomous-building
Source
github.com/deeleeramone/pywry