mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 07:09:11 +02:00
* Archive v3 docs under /v3 and publish v4 as the primary version * Label primary docs version v4.0.0 (alpha 1) * Add What's New in v4 page; fix upgrade-guide phrasing; point banner at What's New * Rewrite What's New around v4's new capabilities, not the sampling deprecation * Lead What's New with the SDK v2 engine swap and the SEPs it brings * State ships now (link Session State); tasks arrive next alpha * Exclude docs/v3 frozen snapshots from doc-example import validation
72 lines
2.3 KiB
Text
72 lines
2.3 KiB
Text
---
|
|
title: Choice
|
|
sidebarTitle: Choice
|
|
description: Present clickable options instead of free-text responses
|
|
icon: list-check
|
|
tag: NEW
|
|
---
|
|
|
|
import { VersionBadge } from '/snippets/version-badge.mdx'
|
|
|
|
<VersionBadge version="3.2.0" />
|
|
|
|
`Choice` lets the LLM present a set of options as clickable buttons instead of asking the user to type a response. The selection flows back into the conversation as a message, giving the LLM clean structured input.
|
|
|
|
<Frame>
|
|
<img src="/apps/images/app-choice.png" alt="The Choice provider shown in Goose, with four lunch options as clickable buttons" />
|
|
</Frame>
|
|
|
|
```python
|
|
from fastmcp import FastMCP
|
|
from fastmcp.apps.choice import Choice
|
|
|
|
mcp = FastMCP("My Server")
|
|
mcp.add_provider(Choice())
|
|
```
|
|
|
|
This registers a single tool:
|
|
|
|
| Tool | Visibility | Purpose |
|
|
|------|-----------|---------|
|
|
| `choose` | Model | Shows a card with clickable options, sends the selection back as a message |
|
|
|
|
The LLM calls `choose` with a prompt and a list of options. The user sees a card with one button per option. Clicking one sends a message back into the conversation:
|
|
|
|
```
|
|
"Which deployment strategy?" — I selected: Blue-green
|
|
```
|
|
|
|
<Note>
|
|
This is an advisory interaction, not an enforcement mechanism. The conversation isn't blocked while the card is open — the user can keep typing, and the LLM could proceed without waiting. The tool description instructs the LLM to stop and wait for the "I selected:" response, but for hard enforcement, implement selection logic server-side.
|
|
</Note>
|
|
|
|
## Configuration
|
|
|
|
The constructor sets defaults; the LLM can override `title` per-call.
|
|
|
|
```python
|
|
Choice(
|
|
name="Choice", # App name
|
|
title="Choose an Option", # Default card heading
|
|
variant="outline", # Button style for all options
|
|
)
|
|
```
|
|
|
|
The LLM provides the options per-call:
|
|
|
|
```python
|
|
choose(
|
|
prompt="What should we have for lunch?",
|
|
options=["Pizza", "Tacos", "Ramen", "Salad"],
|
|
title="The Important Questions",
|
|
)
|
|
```
|
|
|
|
## How it works
|
|
|
|
Each option renders as a full-width button in a vertical stack. When the user clicks one:
|
|
|
|
1. `SendMessage` pushes the selection into the conversation as a user message
|
|
2. `SetState("decided", True)` replaces the buttons with "Response sent."
|
|
|
|
The tool description instructs the LLM to stop and wait for the "I selected:" message before proceeding with whatever the user chose.
|