mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 05:54:19 +02:00
Fix blocking docs issues: chart imports, Select API, Rx consistency (#3652)
This commit is contained in:
parent
b9ea53618d
commit
8ff28c13fa
5 changed files with 56 additions and 42 deletions
|
|
@ -283,7 +283,7 @@ Forms are the most common way to collect input and send it to the server. When a
|
|||
Build forms with individual input components:
|
||||
|
||||
```python
|
||||
from prefab_ui.components import Form, Input, Select, Textarea, Button
|
||||
from prefab_ui.components import Form, Input, Select, SelectOption, Textarea, Button
|
||||
from prefab_ui.actions.mcp import CallTool
|
||||
from prefab_ui.actions import ShowToast
|
||||
|
||||
|
|
@ -294,11 +294,11 @@ with Form(
|
|||
)
|
||||
):
|
||||
Input(name="title", label="Title", required=True)
|
||||
Select(
|
||||
name="priority",
|
||||
label="Priority",
|
||||
options=["low", "medium", "high", "critical"],
|
||||
)
|
||||
with Select(name="priority", label="Priority"):
|
||||
SelectOption("Low", value="low")
|
||||
SelectOption("Medium", value="medium")
|
||||
SelectOption("High", value="high")
|
||||
SelectOption("Critical", value="critical")
|
||||
Textarea(name="description", label="Description")
|
||||
Button("Create Ticket")
|
||||
```
|
||||
|
|
@ -433,7 +433,7 @@ from prefab_ui.components import (
|
|||
Badge, Button, Column, ForEach, Form,
|
||||
Heading, Input, Muted, Row, Separator, Text,
|
||||
)
|
||||
from prefab_ui.rx import RESULT
|
||||
from prefab_ui.rx import RESULT, Rx
|
||||
from pydantic import BaseModel, Field
|
||||
from fastmcp import FastMCP, FastMCPApp
|
||||
|
||||
|
|
@ -512,7 +512,7 @@ def contact_manager() -> PrefabApp:
|
|||
with Form(
|
||||
on_submit=CallTool(
|
||||
"search_contacts",
|
||||
arguments={"query": "{{ query }}"},
|
||||
arguments={"query": Rx("query")},
|
||||
on_success=SetState("contacts", RESULT),
|
||||
)
|
||||
):
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
|
|||
|
||||
<VersionBadge version="3.0.0" />
|
||||
|
||||
MCP Apps let tools return interactive UIs — charts, sortable tables, forms, dashboards — rendered in a sandboxed iframe inside the host client's conversation.
|
||||
MCP tools normally return text. That works for answers, but not for data the user wants to *explore* — a revenue chart they can hover over, a sortable employee directory, a form that submits structured input. MCP Apps let your tools return interactive UIs rendered right inside the conversation.
|
||||
|
||||
FastMCP implements the [MCP Apps extension](https://modelcontextprotocol.io/docs/extensions/apps) and gives you two ways to build interactive UIs with [Prefab](https://prefab.prefect.io), depending on how much server-side interaction you need.
|
||||
{/* TODO: screenshot of a Prefab app rendering in Claude Desktop */}
|
||||
|
||||
FastMCP builds on the [MCP Apps extension](https://modelcontextprotocol.io/docs/extensions/apps) with [Prefab](https://prefab.prefect.io), a Python component library that compiles to interactive UIs. You write Python; the user sees charts, tables, forms, and dashboards.
|
||||
|
||||
<Note>
|
||||
The examples throughout the Apps docs require the `apps` extra:
|
||||
|
|
@ -28,7 +30,7 @@ This installs [Prefab UI](https://prefab.prefect.io), the component library used
|
|||
|
||||
<VersionBadge version="3.1.0" />
|
||||
|
||||
The quickest way to give a tool a visual UI. You return a [Prefab](https://prefab.prefect.io) component or `PrefabApp` from an otherwise standard MCP tool, and when the host calls it, the app is rendered instead of plain text:
|
||||
The quickest way to give a tool a visual UI. Add `app=True` to any tool and return a Prefab component — when the host calls it, the user sees an interactive UI instead of a JSON blob:
|
||||
|
||||
```python
|
||||
from prefab_ui.app import PrefabApp
|
||||
|
|
@ -60,7 +62,7 @@ def revenue_chart(year: int) -> PrefabApp:
|
|||
return PrefabApp(view=view)
|
||||
```
|
||||
|
||||
Prefab apps aren't limited to static displays. Prefab's state system and client-side actions (toggles, tabs, conditionals) all work. You can even call other tools from the UI using `CallTool` with string names. There's no hard wall on what a Prefab app can do.
|
||||
Prefab apps aren't limited to static displays. Prefab's state system and client-side actions (toggles, tabs, conditionals) all work. You can even call other tools from the UI using `CallTool`. There's no hard wall on what a Prefab app can do.
|
||||
|
||||
See [Prefab Apps](/apps/prefab) for the full guide.
|
||||
|
||||
|
|
@ -75,7 +77,7 @@ When your app has a lot of server-side interaction — forms that save data, sea
|
|||
- **`@app.ui()`** — entry-point tools the model calls to open the app
|
||||
- **`@app.tool()`** — backend tools the UI calls via `CallTool`
|
||||
|
||||
Backend tools get stable global identifiers that survive namespacing, visibility is managed automatically (the model sees entry points, the UI sees backends), and `CallTool` accepts function references instead of string names:
|
||||
Backend tools get stable identifiers that survive namespacing, visibility is managed automatically (the model sees entry points, the UI sees backends), and `CallTool` accepts tool names that resolve correctly regardless of how servers are composed:
|
||||
|
||||
```python
|
||||
from prefab_ui.actions import SetState, ShowToast
|
||||
|
|
@ -130,20 +132,6 @@ You *can* build server-interactive UIs without `FastMCPApp` — it's all the sam
|
|||
|
||||
See [FastMCPApp](/apps/interactive-apps) for the full guide.
|
||||
|
||||
## Which Approach?
|
||||
|
||||
| Scenario | Approach |
|
||||
| -------- | -------- |
|
||||
| Visual output — charts, tables, status dashboards | [Prefab app](/apps/prefab) — `@mcp.tool(app=True)` |
|
||||
| Client-side interactivity — toggles, tabs, conditionals | [Prefab app](/apps/prefab) — state + `Rx()` |
|
||||
| Light server interaction — one or two tool calls | [Prefab app](/apps/prefab) — `CallTool("tool_name")` |
|
||||
| Heavy server interaction — forms, CRUD, search, multi-step | [FastMCPApp](/apps/interactive-apps) — managed tool binding |
|
||||
| Composed servers — apps mounted under namespaces | [FastMCPApp](/apps/interactive-apps) — stable global keys |
|
||||
| LLM-generated UIs — bespoke visualizations per request | [Generative UI](/apps/generative) — `GenerativeUI` provider |
|
||||
| Custom rendering — maps, 3D, specific JS frameworks | [Custom HTML](/apps/low-level) — raw MCP Apps extension |
|
||||
|
||||
The boundary isn't sharp. Start with a Prefab app; graduate to `FastMCPApp` when the tool-management complexity justifies it.
|
||||
|
||||
## Generative UI
|
||||
|
||||
<VersionBadge version="3.2.0" />
|
||||
|
|
@ -160,9 +148,23 @@ mcp.add_provider(GenerativeUI())
|
|||
|
||||
See [Generative UI](/apps/generative) for the full guide.
|
||||
|
||||
## Which Approach?
|
||||
|
||||
| Scenario | Approach |
|
||||
| -------- | -------- |
|
||||
| Visual output — charts, tables, status dashboards | [Prefab app](/apps/prefab) — `@mcp.tool(app=True)` |
|
||||
| Client-side interactivity — toggles, tabs, conditionals | [Prefab app](/apps/prefab) — state + `Rx()` |
|
||||
| Light server interaction — one or two tool calls | [Prefab app](/apps/prefab) — `CallTool("tool_name")` |
|
||||
| Heavy server interaction — forms, CRUD, search, multi-step | [FastMCPApp](/apps/interactive-apps) — managed tool binding |
|
||||
| Composed servers — apps mounted under namespaces | [FastMCPApp](/apps/interactive-apps) — stable routing |
|
||||
| LLM-generated UIs — bespoke visualizations per request | [Generative UI](/apps/generative) — `GenerativeUI` provider |
|
||||
| Custom rendering — maps, 3D, specific JS frameworks | [Custom HTML](/apps/low-level) — raw MCP Apps extension |
|
||||
|
||||
The boundary isn't sharp. Start with a Prefab app; graduate to `FastMCPApp` when the tool-management complexity justifies it.
|
||||
|
||||
## Custom HTML Apps
|
||||
|
||||
Both approaches above use [Prefab UI](https://prefab.prefect.io) to build UIs in pure Python. If you need full control — your own HTML, CSS, JavaScript, a specific framework — you can use the [MCP Apps extension directly](/apps/low-level). You write the HTML yourself and communicate with the host via the [`@modelcontextprotocol/ext-apps`](https://github.com/modelcontextprotocol/ext-apps) SDK.
|
||||
All the approaches above use [Prefab UI](https://prefab.prefect.io) to build UIs in pure Python. If you need full control — your own HTML, CSS, JavaScript, a specific framework — you can use the [MCP Apps extension directly](/apps/low-level). You write the HTML yourself and communicate with the host via the [`@modelcontextprotocol/ext-apps`](https://github.com/modelcontextprotocol/ext-apps) SDK.
|
||||
|
||||
## Previewing Apps Locally
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ Prefab includes [bar, line, area, pie, radar, and radial charts](https://prefab.
|
|||
|
||||
```python
|
||||
from prefab_ui.app import PrefabApp
|
||||
from prefab_ui.components import Column, Heading, BarChart, ChartSeries
|
||||
from prefab_ui.components import Column, Heading
|
||||
from prefab_ui.components.charts import BarChart, ChartSeries
|
||||
from fastmcp import FastMCP
|
||||
|
||||
mcp = FastMCP("Charts")
|
||||
|
|
@ -61,7 +62,8 @@ Multiple `ChartSeries` entries plot different data keys. Add `stacked=True` to s
|
|||
|
||||
```python
|
||||
from prefab_ui.app import PrefabApp
|
||||
from prefab_ui.components import Column, Heading, AreaChart, ChartSeries
|
||||
from prefab_ui.components import Column, Heading
|
||||
from prefab_ui.components.charts import AreaChart, ChartSeries
|
||||
from fastmcp import FastMCP
|
||||
|
||||
mcp = FastMCP("Charts")
|
||||
|
|
@ -97,7 +99,8 @@ def usage_trend() -> PrefabApp:
|
|||
|
||||
```python
|
||||
from prefab_ui.app import PrefabApp
|
||||
from prefab_ui.components import Column, Heading, PieChart
|
||||
from prefab_ui.components import Column, Heading
|
||||
from prefab_ui.components.charts import PieChart
|
||||
from fastmcp import FastMCP
|
||||
|
||||
mcp = FastMCP("Charts")
|
||||
|
|
@ -360,7 +363,7 @@ from prefab_ui.actions.mcp import CallTool
|
|||
from prefab_ui.app import PrefabApp
|
||||
from prefab_ui.components import (
|
||||
Badge, Button, Column, ForEach, Form, Heading,
|
||||
Input, Muted, Row, Select, Separator, Text, Textarea,
|
||||
Input, Muted, Row, Select, SelectOption, Separator, Text, Textarea,
|
||||
)
|
||||
from prefab_ui.rx import RESULT
|
||||
from fastmcp import FastMCP, FastMCPApp
|
||||
|
|
@ -407,11 +410,11 @@ def contact_form() -> PrefabApp:
|
|||
):
|
||||
Input(name="name", label="Full Name", required=True)
|
||||
Input(name="email", label="Email", input_type="email", required=True)
|
||||
Select(
|
||||
name="category",
|
||||
label="Category",
|
||||
options=["Customer", "Vendor", "Partner", "Other"],
|
||||
)
|
||||
with Select(name="category", label="Category"):
|
||||
SelectOption("Customer", value="Customer")
|
||||
SelectOption("Vendor", value="Vendor")
|
||||
SelectOption("Partner", value="Partner")
|
||||
SelectOption("Other", value="Other")
|
||||
Textarea(name="notes", label="Notes", placeholder="Optional notes...")
|
||||
Button("Save Contact")
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
|
|||
[Prefab](https://prefab.prefect.io) is in early, active development — its API changes frequently and breaking changes can occur with any release. Always pin `prefab-ui` to a specific version in your dependencies (see below).
|
||||
</Tip>
|
||||
|
||||
The fastest way to give a tool a visual UI: return a [Prefab](https://prefab.prefect.io) component or `PrefabApp` from an otherwise standard MCP tool. FastMCP registers the rendering engine, wires the protocol metadata, and delivers the component tree to the host. You write Python; the user sees an interactive UI.
|
||||
When a tool returns text, the LLM reads it and relays the information. But some data is better *seen* — a chart communicates trend at a glance, a sortable table lets the user explore without re-prompting, a dashboard with badges and progress bars gives immediate status.
|
||||
|
||||
Prefab apps transform your tools from text-returning functions into visual experiences. Add `app=True` to a tool, return a [Prefab](https://prefab.prefect.io) component, and the host renders an interactive UI instead of text. FastMCP handles the rendering engine, protocol metadata, and delivery. You write Python; the user sees charts, tables, and dashboards.
|
||||
|
||||
This works for everything from static charts to reactive dashboards with client-side state. When your app has heavy server-side interaction — multiple backend tools, forms, search, CRUD — consider [FastMCPApp](/apps/interactive-apps), which manages tool binding, visibility, and composition safety for you.
|
||||
|
||||
|
|
|
|||
|
|
@ -194,12 +194,19 @@
|
|||
"apps/overview",
|
||||
"apps/prefab",
|
||||
"apps/interactive-apps",
|
||||
"apps/components",
|
||||
"apps/patterns",
|
||||
"apps/generative",
|
||||
"apps/development",
|
||||
"apps/architecture",
|
||||
"apps/low-level"
|
||||
{
|
||||
"collapsed": true,
|
||||
"group": "Reference",
|
||||
"icon": "book",
|
||||
"pages": [
|
||||
"apps/components",
|
||||
"apps/patterns",
|
||||
"apps/architecture",
|
||||
"apps/low-level"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue