---
phase: 21-book-mcp-apps-refresh
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - pmcp-book/src/ch12-5-mcp-apps.md
autonomous: true
requirements:
  - BKAP-01
  - BKAP-02

must_haves:
  truths:
    - "Reader can author a widget by dropping an HTML file into a widgets/ directory and see it served as a ui://app/{name} resource"
    - "Reader understands that WidgetDir reads from disk on every request so a browser refresh shows the latest HTML without server restart"
    - "Reader can scaffold a new MCP Apps project with cargo pmcp app new <name> and understands the generated directory structure"
    - "Reader can run cargo pmcp app build --url <URL> to produce manifest.json and landing.html artifacts"
    - "Reader can use cargo pmcp preview --url <URL> --open to launch a browser-based preview of their widgets"
    - "Reader understands the end-to-end developer workflow: scaffold -> code widgets -> run server -> preview -> build"
  artifacts:
    - path: "pmcp-book/src/ch12-5-mcp-apps.md"
      provides: "Rewritten chapter with WidgetDir and developer workflow sections"
      min_lines: 500
      contains: "WidgetDir"
  key_links:
    - from: "pmcp-book/src/ch12-5-mcp-apps.md"
      to: "src/server/mcp_apps/widget_fs.rs"
      via: "Documented WidgetDir API matches actual struct methods"
      pattern: "WidgetDir::new|discover|read_widget"
    - from: "pmcp-book/src/ch12-5-mcp-apps.md"
      to: "cargo-pmcp/src/commands/app.rs"
      via: "Documented CLI subcommands match actual AppCommand enum variants"
      pattern: "cargo pmcp app (new|build|manifest|landing)"
---

<objective>
Rewrite the first half of Ch 12.5 (MCP Apps Extension) to document the current WidgetDir-based authoring pattern and the `cargo pmcp app` developer workflow.

Purpose: The existing chapter documents an older UIResourceBuilder + inline HTML approach. It needs to be replaced with the current file-based widget authoring pattern (WidgetDir) and the CLI-driven developer workflow (cargo pmcp app new/build/preview). Readers need to understand how to author widgets from plain HTML files and iterate with hot-reload.

Output: `pmcp-book/src/ch12-5-mcp-apps.md` rewritten from the chapter introduction through the developer workflow, leaving a continuation point for Plan 21-02 to add the adapter pattern and example walkthrough sections.
</objective>

<execution_context>
@./.claude/get-shit-done/workflows/execute-plan.md
@./.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md

The existing chapter is 843 lines and uses an outdated approach (UIResourceBuilder, inline HTML templates, postMessage). The entire chapter must be rewritten to reflect the current architecture.

Style reference: Read `pmcp-book/src/ch14-performance.md` (first ~50 lines) and `pmcp-book/src/ch15-testing.md` (first ~50 lines) to match the existing book's voice, structure, and formatting conventions.

Source code to extract documentation from (READ THESE during execution):
- `src/server/mcp_apps/widget_fs.rs` — WidgetDir struct, WidgetEntry, discover(), read_widget(), inject_bridge_script(), error_page()
- `src/server/mcp_apps/mod.rs` — Module-level docstring with architecture diagram and feature flag info
- `cargo-pmcp/src/commands/app.rs` — AppCommand enum: New, Manifest, Landing, Build subcommands with all their flags
- `cargo-pmcp/src/commands/preview.rs` — Preview command: url, port, open, tool, theme, locale, widgets_dir flags
- `cargo-pmcp/src/templates/mcp_app.rs` — Scaffold template (what `cargo pmcp app new` generates)
- `examples/mcp-apps-chess/src/main.rs` — Real example using WidgetDir + ChatGptAdapter (lines 420-497 show ResourceHandler implementation pattern)
</context>

<tasks>

<task type="auto">
  <name>Task 1: Rewrite Ch 12.5 intro, WidgetDir authoring, and quick start</name>
  <files>pmcp-book/src/ch12-5-mcp-apps.md</files>
  <action>
Read the following source files to extract accurate details:
- `src/server/mcp_apps/widget_fs.rs` for WidgetDir API (new, discover, read_widget, inject_bridge_script, WidgetEntry fields)
- `src/server/mcp_apps/mod.rs` for the module overview, architecture diagram, and feature flag requirements
- `examples/mcp-apps-chess/src/main.rs` for the real-world ResourceHandler pattern using WidgetDir + ChatGptAdapter (lines 420-497)
- `cargo-pmcp/src/templates/mcp_app.rs` for what `cargo pmcp app new` generates (to show the scaffold structure)

Also read `pmcp-book/src/ch14-performance.md` (first 50 lines) for style reference.

Rewrite `pmcp-book/src/ch12-5-mcp-apps.md` completely, replacing ALL existing content with these sections:

**1. Chapter Introduction** (# Chapter 12.5: MCP Apps Extension -- Interactive UIs)
- Opening paragraph: MCP Apps Extension lets your server serve rich, interactive UIs (charts, maps, games, dashboards) as widgets alongside tools
- The modern DX: write HTML files in a `widgets/` directory, the server reads them on every request (hot-reload), adapters transform them for different hosts (ChatGPT, MCP Apps, MCP-UI)
- What this chapter covers: authoring, CLI workflow, adapter pattern, and example walkthroughs
- Feature flag requirement: `pmcp = { version = "1.10", features = ["mcp-apps"] }`

**2. Quick Start** (## Quick Start: Your First Widget (5 Minutes))
- Three-step minimal workflow:
  1. `cargo pmcp app new my-widget-app` — scaffold
  2. Edit `widgets/hello.html` — write your UI
  3. `cargo run &` then `cargo pmcp preview --url http://localhost:3000 --open` — preview
- Show a minimal working `widgets/hello.html` that uses `window.mcpBridge.callTool()` to call a tool and render the result
- Show the minimal `src/main.rs` using ServerBuilder + WidgetDir + ChatGptAdapter (based on the real example pattern in chess/map/dataviz examples)
- Include expected behavior description

**3. Widget Authoring with WidgetDir** (## Widget Authoring with WidgetDir)
- **Convention** (### Convention): widgets are `.html` files in a `widgets/` directory; filename maps to MCP resource URI (`widgets/board.html` -> `ui://app/board`)
- **WidgetDir API** (### WidgetDir API):
  - `WidgetDir::new(path)` — point at the widgets directory
  - `widget_dir.discover()` — scan for `.html` files, returns `Vec<WidgetEntry>` sorted by filename
  - `WidgetEntry` fields: `filename` (stem), `uri` (e.g., `ui://app/board`), `path` (absolute path)
  - `widget_dir.read_widget("board")` — read from disk on every call (no cache = hot-reload)
  - If file not found, returns a styled error page (show what it looks like)
- **Hot-Reload Development** (### Hot-Reload Development):
  - WidgetDir reads from disk on every request — no server restart needed
  - Edit your HTML, refresh the browser, see changes instantly
  - This enables a frontend-style development workflow for MCP widgets
- **The ResourceHandler Pattern** (### The ResourceHandler Pattern):
  - Show the concrete implementation pattern from the examples:
    1. Struct holds `ChatGptAdapter` + `WidgetDir`
    2. `read()` extracts widget name from URI, calls `widget_dir.read_widget()`, then `adapter.transform()`
    3. `list()` calls `widget_dir.discover()` and maps entries to `ResourceInfo`
  - Full code example based on the chess/map pattern (simplified)
  - Explain that this pattern is identical across all three shipped examples (chess, map, dataviz)

**4. Bridge Communication** (## Bridge Communication)
- **window.mcpBridge API** (### window.mcpBridge API):
  - `mcpBridge.callTool(name, args)` — call an MCP tool, returns Promise
  - `mcpBridge.readResource(uri)` — read an MCP resource
  - `mcpBridge.getPrompt(name, args)` — get a prompt
  - `mcpBridge.notify(method, params)` — send a notification
  - `mcpBridge.setState(state)` / `mcpBridge.getState()` — widget state management (ChatGPT only)
  - `mcpBridge.sendMessage(message)` — send follow-up message (ChatGPT only)
- **Communication Flow** (### Communication Flow):
  - ASCII diagram: Widget (iframe) -> mcpBridge.callTool() -> bridge script -> postMessage/window.openai -> Host -> MCP Server -> response back
  - The bridge is auto-injected by the adapter (widget authors do NOT need to write postMessage code)
- **Error Handling** (### Error Handling in Widgets):
  - Show try/catch pattern around callTool
  - mcpBridgeReady event for widgets that need to wait for bridge initialization

End the file with a clear `<!-- CONTINUED IN PLAN 21-02: Adapter Pattern and Example Walkthroughs -->` comment.

IMPORTANT: Extract ALL API details from source code. The WidgetDir methods, WidgetEntry fields, and bridge API methods must match the actual Rust and JavaScript source. Use the real ResourceHandler pattern from the examples, not the old UIResourceBuilder approach.
  </action>
  <verify>
    <automated>grep -c "## " pmcp-book/src/ch12-5-mcp-apps.md | xargs test 4 -le</automated>
    Verify the file has at least 4 major sections (## headers), contains "WidgetDir", "discover", "read_widget", "mcpBridge.callTool", "cargo pmcp app new", "hot-reload".
    Run: grep -cE "(WidgetDir|discover|read_widget|mcpBridge\.callTool|cargo pmcp app new|hot.reload)" pmcp-book/src/ch12-5-mcp-apps.md
    Should return 10+.
  </verify>
  <done>
    Ch 12.5 first half covers WidgetDir file-based authoring (convention, API, hot-reload, ResourceHandler pattern) and bridge communication (mcpBridge API, communication flow, error handling). All API details match source code. The UIResourceBuilder/inline HTML approach from the old chapter is completely replaced.
  </done>
</task>

<task type="auto">
  <name>Task 2: Write developer workflow section (cargo pmcp app new/build/preview)</name>
  <files>pmcp-book/src/ch12-5-mcp-apps.md</files>
  <action>
Read the following source files to extract accurate details:
- `cargo-pmcp/src/commands/app.rs` for AppCommand enum: New (name, path), Manifest (url, logo, output), Landing (widget, output), Build (url, logo, widget, output) — all flags
- `cargo-pmcp/src/commands/preview.rs` for preview command flags: url, port, open, tool, theme, locale, widgets_dir
- `cargo-pmcp/src/templates/mcp_app.rs` for scaffold template content (what files get generated)
- `cargo-pmcp/src/publishing/detect.rs` for project detection logic
- `cargo-pmcp/src/publishing/manifest.rs` for manifest generation
- `cargo-pmcp/src/publishing/landing.rs` for landing page generation

Insert the following sections BEFORE the `<!-- CONTINUED IN PLAN 21-02 -->` comment in the file:

**5. Developer Workflow** (## Developer Workflow)
- End-to-end workflow overview: scaffold -> author widgets -> run server -> preview -> build -> deploy
- ASCII diagram or numbered flow showing the full cycle

**5.1. Scaffolding** (### Scaffolding with `cargo pmcp app new`)
- `cargo pmcp app new <name>` creates a complete project directory
- `--path <DIR>` flag for custom location
- Generated structure: `src/main.rs`, `widgets/hello.html`, `Cargo.toml`, `README.md`
- Show the generated directory tree
- Error if directory already exists (matches cargo new semantics)

**5.2. Preview** (### Live Preview with `cargo pmcp preview`)
- `cargo pmcp preview --url <URL>` connects to a running MCP server
- `--open` flag opens browser automatically
- `--port <PORT>` (default: varies) for preview server port
- `--tool <NAME>` to auto-select a specific tool on load
- `--theme <light|dark>` and `--locale <LOCALE>` for environment simulation
- `--widgets-dir <PATH>` for hot-reload of widget files
- Full example: `cargo run &` then `cargo pmcp preview --url http://localhost:3000 --open`
- Explain the preview connects via MCP protocol and renders widgets in a browser environment

**5.3. Building for Distribution** (### Building with `cargo pmcp app build`)
- `cargo pmcp app build --url <URL>` produces both manifest.json and landing.html
- `--output <DIR>` (default: "dist") for output directory
- `--logo <URL>` for custom logo in manifest
- `--widget <NAME>` to select which widget to showcase in landing page
- Subcommands for individual artifacts:
  - `cargo pmcp app manifest --url <URL>` for just manifest.json (ChatGPT-compatible)
  - `cargo pmcp app landing` for just landing.html (standalone demo page)
- What each artifact is for:
  - `manifest.json`: ChatGPT Apps directory listing, auto-discovered widgets
  - `landing.html`: standalone demo page with embedded widget iframe and mock bridge

**5.4. Project Detection** (### Project Detection)
- Brief explanation: cargo pmcp app commands auto-detect the project from Cargo.toml metadata
- `[package.metadata.pmcp]` section in Cargo.toml for customization
- Widget discovery scans the `widgets/` directory

IMPORTANT: Extract ALL CLI flags, subcommands, and default values from the actual source code. Do not invent flags.
  </action>
  <verify>
    <automated>grep -cE "(cargo pmcp (app|preview)|manifest\.json|landing\.html|--url|--open|--output)" pmcp-book/src/ch12-5-mcp-apps.md</automated>
    Should return 15+ matches confirming full CLI documentation.
    Also verify: grep -c "### " pmcp-book/src/ch12-5-mcp-apps.md should return 8+ subsections.
  </verify>
  <done>
    Ch 12.5 includes complete developer workflow documentation covering scaffolding (cargo pmcp app new with all flags), live preview (cargo pmcp preview with all flags), building for distribution (cargo pmcp app build/manifest/landing with all flags), and project detection. All flags and defaults match the actual source code.
  </done>
</task>

</tasks>

<verification>
1. `pmcp-book/src/ch12-5-mcp-apps.md` exists and has been rewritten (no UIResourceBuilder references remain)
2. Chapter covers BKAP-01: WidgetDir file-based authoring with hot-reload
3. Chapter covers BKAP-02: cargo pmcp app new/build/preview workflow end-to-end
4. WidgetDir API matches `src/server/mcp_apps/widget_fs.rs` (new, discover, read_widget)
5. CLI flags match `cargo-pmcp/src/commands/app.rs` (New, Manifest, Landing, Build variants)
6. Preview flags match `cargo-pmcp/src/commands/preview.rs`
7. ResourceHandler pattern matches examples (chess/map/dataviz main.rs)
8. Bridge API (mcpBridge.callTool etc.) matches adapter.rs bridge scripts
9. File ends with continuation comment for Plan 21-02
</verification>

<success_criteria>
- Ch 12.5 is rewritten to document the current WidgetDir-based approach, not the old UIResourceBuilder approach
- A reader can follow the chapter to scaffold, author, preview, and build an MCP Apps project
- All API details, CLI flags, and patterns are extracted from actual source code
- Writing style matches the existing book (ch14/ch15 formatting conventions)
</success_criteria>

<output>
After completion, create `.planning/phases/21-book-mcp-apps-refresh/21-01-SUMMARY.md`
</output>
