fastmcp/examples/tasks
Jeremiah Lowin f81d6c07d8
Load task settings from .env; gate root publish on fastmcp-tasks; fix worker command
DocketSettings now loads the same dotenv source as core settings, so a
FASTMCP_DOCKET_* value in .env configures the backend instead of silently
using memory://. The root fastmcp publish waits for the matching fastmcp-tasks
to appear on PyPI before uploading, so the [tasks] extra is never installable
but unresolvable. And the example README uses the real worker entry point
(python -m fastmcp_tasks.worker_cli worker).
2026-07-23 18:30:52 -04:00
..
.envrc Rework tasks example into a runnable HTTP client/server pair 2026-07-23 16:44:53 -04:00
client.py Rework tasks example into a runnable HTTP client/server pair 2026-07-23 16:44:53 -04:00
docker-compose.yml [2.14] SEP-1686 tasks (#2378) 2025-12-04 20:10:35 -05:00
README.md Load task settings from .env; gate root publish on fastmcp-tasks; fix worker command 2026-07-23 18:30:52 -04:00
server.py Rework tasks example into a runnable HTTP client/server pair 2026-07-23 16:44:53 -04:00

FastMCP Background Tasks Example

A runnable client/server pair for SEP-2663 background tasks. The server exposes one task=True tool that reports progress as it works; the client drives it three ways — transparently, through an explicit handle, and several at once in parallel.

This runs on the in-memory backend by default, so there's nothing to install or start beyond the two processes.

Run it

In one terminal, start the server:

uv sync                              # from the fastmcp root, once
python examples/tasks/server.py      # listens on http://127.0.0.1:8000/mcp

In another terminal, drive it from the client:

# Transparent — call_tool runs the background task and returns its result
python examples/tasks/client.py --duration 8

# Explicit handle — returns immediately, poll it yourself, then collect
python examples/tasks/client.py handle --duration 6

# Parallel — fire several tasks at once and watch them overlap
python examples/tasks/client.py parallel
python examples/tasks/client.py parallel 8 6 4 2

The parallel run is the one to watch: four tasks of decreasing duration all start at once and total wall-clock tracks the longest task rather than the sum, because the worker runs them concurrently.

How it works

The server enables tasks with one line:

mcp = FastMCP("Tasks Example")
mcp.add_extension(TasksExtension())

The client opts in by importing fastmcp_tasks (which it does to use call_tool_task). That single import enables task support for every Client in the process — without it, a Client never advertises the tasks capability, so the server would run the calls synchronously.

Distributed workers (optional)

The default memory:// backend runs the worker in the server process. To run workers as separate processes, point Docket at Redis and start it first:

cd examples/tasks
docker compose up -d
export FASTMCP_DOCKET_URL=redis://localhost:24242/0   # or: direnv allow

python server.py                                        # in one terminal
python -m fastmcp_tasks.worker_cli worker server.py     # extra worker(s) in others
Backend Workers
memory:// in-process only (default)
redis://… distributed across processes

Learn more