fastmcp/docs/apps/development.mdx
Jeremiah Lowin 639a8d3327
Require a startup-URL session for the fastmcp dev apps preview (#5417)
`fastmcp dev apps` now runs its dev UI as a session started from the printed startup URL, so the preview is tied to the terminal that launched it. Opening the startup URL sets a session cookie, and requests also need the dev server's own Host and the dev UI's origin. The picker creates launches on the server, and launch pages open them by id. Tool UI resources run in a sandboxed iframe with their own opaque origin and talk to the dev UI through AppBridge, which matches how production MCP Apps hosts isolate app content. Picker errors are HTML-escaped. The `/mcp` proxy forwards only what the MCP server needs. The spawned MCP server runs with `FASTMCP_HTTP_HOST_ORIGIN_PROTECTION=auto` unless that variable is already set.

Compatibility: opening the dev UI without the startup URL returns 403, and launch URLs come from the picker rather than being written by hand. Port-forwarded or proxied setups where the browser-facing host and port differ from the bind address get 400. Sandboxed apps send `Origin: null` and cannot use `alert`/`confirm`, popups, or `localStorage`.

Co-authored-by: Bill Easton <williamseaston@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-04 10:14:58 -04:00

69 lines
3.6 KiB
Text

---
title: Development
sidebarTitle: Development
description: Preview and test your app tools locally without a full MCP host.
icon: flask
---
import { VersionBadge } from '/snippets/version-badge.mdx'
<VersionBadge version="3.2.0" />
<Frame>
<img src="/apps/images/dev-app.png" alt="The dev UI showing a rendered Prefab app with the MCP inspector panel" />
</Frame>
`fastmcp dev apps` gives you a browser preview for your app tools without needing an MCP host client. It starts your server and a local dev UI side by side: you pick a tool, fill in its arguments, and the rendered result opens in a new tab.
Works with both [Interactive Tools](/apps/prefab) and [custom HTML apps](/apps/low-level).
## Quick start
```bash
fastmcp dev apps server.py
```
The dev UI opens in your browser on port 8080 through a startup URL that the terminal prints. Each run prints a new URL; open it to use the dev UI in another browser or after closing the tab. Your MCP server runs on port 8000 with auto-reload enabled by default — save a file and the server restarts automatically.
## How it works
The dev server does three things:
The **picker page** connects to your MCP server, finds all tools with UI metadata, and renders a form for each one. The forms are auto-generated from the tool's input schema — text fields, dropdowns, checkboxes, all wired up.
When you submit a form, the dev server **calls your tool** via the MCP protocol and opens the result in a new tab. Each result page comes from a picker launch and stays available, including on reload, until the dev server stops. The result page loads the tool's UI resource (the Prefab renderer or your custom HTML) inside an AppBridge — the same protocol that real MCP hosts use. The resource runs in a sandboxed iframe, so it can't use `localStorage`, open popups, or show `alert` and `confirm` dialogs.
A **reverse proxy** on `/mcp` forwards requests from the browser to your MCP server, avoiding CORS issues that would otherwise block the iframe-based renderer from talking to a different port.
## MCP inspector
The dev UI includes an inspector panel on the left side that captures MCP traffic in real time. It shows JSON-RPC messages flowing between the browser and your server — requests, responses, and AppBridge `postMessage` traffic.
Each entry shows direction, method, timing, and a smart summary. Click any entry to expand the full JSON-RPC body. The panel auto-scrolls to new messages unless you've scrolled up to inspect older ones.
The inspector is useful for debugging: you can see exactly what arguments your tool received, what it returned, and how the AppBridge communicated with the renderer.
## Options
```bash
fastmcp dev apps server.py:mcp --mcp-port 9000 --dev-port 9090 --no-reload
```
| Option | Flag | Default | Description |
| ------ | ---- | ------- | ----------- |
| MCP Port | `--mcp-port` | `8000` | Port for your MCP server |
| Dev Port | `--dev-port` | `8080` | Port for the dev UI |
| Auto-Reload | `--reload` / `--no-reload` | On | Watch files and restart the server on changes |
| Host | `--host` | `127.0.0.1` | Interface for both local servers to bind |
| Log Panel | `--log-panel` / `--no-log-panel` | On | Show or hide the log panel in the dev UI |
With `--host 0.0.0.0`, open the dev UI through `localhost` or an IP address. To reach it by hostname, pass that hostname to `--host`.
## Multiple tools
If your server has multiple app tools, the picker shows a dropdown. Each tool gets its own form and launch button. The tool's `title` is displayed when available, falling back to the tool name.
```bash
# Server with multiple app tools
fastmcp dev apps examples/apps/contacts/contacts_server.py
```