Files
wehub-resource-sync 60e0ffc959
Upgrade checks / Notify on failure (push) Has been cancelled
Upgrade checks / Close issue on success (push) Has been cancelled
Schema Crash Test / Real-world schema crash test (232K schemas) (push) Has been cancelled
Run static analysis / static_analysis (push) Has been cancelled
Tests / Tests: Python 3.10 on ubuntu-latest (push) Has been cancelled
Tests / Tests: Python 3.13 on ubuntu-latest (push) Has been cancelled
Tests / Tests: Python 3.10 on windows-latest (push) Has been cancelled
Tests / Tests with lowest-direct dependencies (push) Has been cancelled
Tests / MCP conformance tests (push) Has been cancelled
Tests / Integration tests (push) Has been cancelled
Tests / Package install smoke (push) Has been cancelled
Upgrade checks / Static analysis (push) Has been cancelled
Upgrade checks / Tests: Python 3.10 on ubuntu-latest (push) Has been cancelled
Upgrade checks / Tests: Python 3.13 on ubuntu-latest (push) Has been cancelled
Upgrade checks / Tests: Python 3.10 on windows-latest (push) Has been cancelled
Upgrade checks / Integration tests (push) Has been cancelled
Update MCPServerConfig Schema / update-config-schema (push) Has been cancelled
Update SDK Documentation / update-sdk-docs (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:59 +08:00

190 lines
5.7 KiB
Plaintext

---
title: Progress Reporting
sidebarTitle: Progress
description: Update clients on the progress of long-running operations through the MCP context.
icon: chart-line
---
import { VersionBadge } from '/snippets/version-badge.mdx'
Progress reporting allows MCP tools to notify clients about the progress of long-running operations. This enables clients to display progress indicators and provide better user experience during time-consuming tasks.
## Why Use Progress Reporting?
Progress reporting is valuable for:
- **User experience**: Keep users informed about long-running operations
- **Progress indicators**: Enable clients to show progress bars or percentages
- **Timeout prevention**: Demonstrate that operations are actively progressing
- **Debugging**: Track execution progress for performance analysis
### Basic Usage
Use `ctx.report_progress()` to send progress updates to the client:
```python {14, 21}
from fastmcp import FastMCP, Context
import asyncio
mcp = FastMCP("ProgressDemo")
@mcp.tool
async def process_items(items: list[str], ctx: Context) -> dict:
"""Process a list of items with progress updates."""
total = len(items)
results = []
for i, item in enumerate(items):
# Report progress as we process each item
await ctx.report_progress(progress=i, total=total)
# Simulate processing time
await asyncio.sleep(0.1)
results.append(item.upper())
# Report 100% completion
await ctx.report_progress(progress=total, total=total)
return {"processed": len(results), "results": results}
```
## Method Signature
<Card icon="code" title="Context Progress Method">
<ResponseField name="ctx.report_progress" type="async method">
Report progress to the client for long-running operations
<Expandable title="Parameters">
<ResponseField name="progress" type="float">
Current progress value (e.g., 24, 0.75, 1500)
</ResponseField>
<ResponseField name="total" type="float | None" default="None">
Optional total value (e.g., 100, 1.0, 2000). When provided, clients may interpret this as enabling percentage calculation.
</ResponseField>
</Expandable>
</ResponseField>
</Card>
## Progress Patterns
### Percentage-Based Progress
Report progress as a percentage (0-100):
```python {13-14}
@mcp.tool
async def download_file(url: str, ctx: Context) -> str:
"""Download a file with percentage progress."""
total_size = 1000 # KB
downloaded = 0
while downloaded < total_size:
# Download chunk
chunk_size = min(50, total_size - downloaded)
downloaded += chunk_size
# Report percentage progress
percentage = (downloaded / total_size) * 100
await ctx.report_progress(progress=percentage, total=100)
await asyncio.sleep(0.1) # Simulate download time
return f"Downloaded file from {url}"
```
### Absolute Progress
Report progress with absolute values:
```python {10}
@mcp.tool
async def backup_database(ctx: Context) -> str:
"""Backup database tables with absolute progress."""
tables = ["users", "orders", "products", "inventory", "logs"]
for i, table in enumerate(tables):
await ctx.info(f"Backing up table: {table}")
# Report absolute progress
await ctx.report_progress(progress=i + 1, total=len(tables))
# Simulate backup time
await asyncio.sleep(0.5)
return "Database backup completed"
```
### Indeterminate Progress
Report progress without a known total for operations where the endpoint is unknown:
```python {11}
@mcp.tool
async def scan_directory(directory: str, ctx: Context) -> dict:
"""Scan directory with indeterminate progress."""
files_found = 0
# Simulate directory scanning
for i in range(10): # Unknown number of files
files_found += 1
# Report progress without total for indeterminate operations
await ctx.report_progress(progress=files_found)
await asyncio.sleep(0.2)
return {"files_found": files_found, "directory": directory}
```
### Multi-Stage Operations
Break complex operations into stages with progress for each:
```python
@mcp.tool
async def data_migration(source: str, destination: str, ctx: Context) -> str:
"""Migrate data with multi-stage progress reporting."""
# Stage 1: Validation (0-25%)
await ctx.info("Validating source data")
for i in range(5):
await ctx.report_progress(progress=i * 5, total=100)
await asyncio.sleep(0.1)
# Stage 2: Export (25-60%)
await ctx.info("Exporting data from source")
for i in range(7):
progress = 25 + (i * 5)
await ctx.report_progress(progress=progress, total=100)
await asyncio.sleep(0.1)
# Stage 3: Transform (60-80%)
await ctx.info("Transforming data format")
for i in range(4):
progress = 60 + (i * 5)
await ctx.report_progress(progress=progress, total=100)
await asyncio.sleep(0.1)
# Stage 4: Import (80-100%)
await ctx.info("Importing to destination")
for i in range(4):
progress = 80 + (i * 5)
await ctx.report_progress(progress=progress, total=100)
await asyncio.sleep(0.1)
# Final completion
await ctx.report_progress(progress=100, total=100)
return f"Migration from {source} to {destination} completed"
```
## Client Requirements
Progress reporting requires clients to support progress handling:
- Clients must send a `progressToken` in the initial request to receive progress updates
- If no progress token is provided, progress calls will have no effect (they won't error)
- See [Client Progress](/v2/clients/progress) for details on implementing client-side progress handling