fastmcp-tasks 4.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ build/
6
+ dist/
7
+ wheels/
8
+ *.egg-info/
9
+ *.egg
10
+ MANIFEST
11
+ .pytest_cache/
12
+ .loq_cache
13
+ .coverage
14
+ htmlcov/
15
+ .tox/
16
+ nosetests.xml
17
+ coverage.xml
18
+ *.cover
19
+
20
+ # Virtual environments
21
+ .venv
22
+ venv/
23
+ env/
24
+ ENV/
25
+ .env
26
+
27
+ # System files
28
+ .DS_Store
29
+
30
+ # Version file
31
+ src/fastmcp/_version.py
32
+
33
+ # Editors and IDEs
34
+ .cursorrules
35
+ .vscode/
36
+ .idea/
37
+ *.swp
38
+ *.swo
39
+ *~
40
+ .project
41
+ .pydevproject
42
+ .settings/
43
+
44
+ # Jupyter Notebook
45
+ .ipynb_checkpoints
46
+
47
+ # Type checking
48
+ .mypy_cache/
49
+ .dmypy.json
50
+ dmypy.json
51
+ .pyre/
52
+ .pytype/
53
+
54
+ # Local development
55
+ .python-version
56
+ .envrc
57
+ .envrc.private
58
+ .direnv/
59
+
60
+ # Logs and databases
61
+ *.log
62
+ *.sqlite
63
+ *.db
64
+ *.ddb
65
+
66
+ # Claude worktree management
67
+ .claude-wt/worktrees
68
+ .claude/worktrees/
69
+
70
+ # Agents
71
+ /PLAN.md
72
+ /TODO.md
73
+ /STATUS.md
74
+ plans/
75
+
76
+ # Common FastMCP test files
77
+ /test.py
78
+ /server.py
79
+ /client.py
80
+ /test.json
@@ -0,0 +1,107 @@
1
+ Metadata-Version: 2.5
2
+ Name: fastmcp-tasks
3
+ Version: 4.0.0
4
+ Summary: Background task execution for FastMCP servers via the io.modelcontextprotocol/tasks extension (SEP-2663).
5
+ Project-URL: Homepage, https://gofastmcp.com
6
+ Project-URL: Repository, https://github.com/PrefectHQ/fastmcp
7
+ Project-URL: Documentation, https://gofastmcp.com
8
+ Author: Jeremiah Lowin, Nate Nowack
9
+ License-Expression: Apache-2.0
10
+ Keywords: background tasks,fastmcp,fastmcp tasks,mcp,model context protocol
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: cryptography>=43.0.0
21
+ Requires-Dist: fastmcp-slim[server]==4.0.0
22
+ Requires-Dist: pydocket>=0.24.1
23
+ Description-Content-Type: text/markdown
24
+
25
+ # fastmcp-tasks
26
+
27
+ A complete implementation of background tasks for the Model Context Protocol — the `io.modelcontextprotocol/tasks` extension defined in [SEP-2663](https://github.com/modelcontextprotocol/ext-tasks).
28
+
29
+ The MCP tasks extension is a Final SEP, but as of this writing it ships in the ecosystem as a schema and a prose specification — no language SDK provides a working runtime for it. `fastmcp-tasks` is, to our knowledge, the first: a full server-side implementation of the protocol, built on the durable execution engine ([docket](https://github.com/chrisguidry/docket)) that FastMCP has run in production since v3. If you want to actually *run* MCP background tasks today, this is the implementation.
30
+
31
+ ## What background tasks are
32
+
33
+ Most tool calls are synchronous: the client sends `tools/call` and holds the request open until the tool returns. That breaks down for work that takes minutes or hours — a long analysis, a batch job, a slow external API. The tasks extension lets a server answer such a call *immediately* with a durable task handle, then run the work in the background while the client polls for completion on its own schedule.
34
+
35
+ The model is poll-based and stateless by construction, which is what makes it survive disconnects, server restarts, and load balancers:
36
+
37
+ 1. A client that supports tasks issues a normal `tools/call` with a per-request opt-in.
38
+ 2. The server decides whether to run it as a task. If it does, it returns a `CreateTaskResult` carrying a server-generated task id — right away, before the work starts.
39
+ 3. The client polls `tasks/get` until the task reaches a terminal state, then reads the result inlined in the response.
40
+ 4. `tasks/cancel` requests cancellation; `tasks/update` answers any input the task asks for mid-run.
41
+
42
+ The server owns the task's durable state, so the client can poll across independent requests — from any process, after a crash, through any replica — with no session affinity required.
43
+
44
+ ## Usage
45
+
46
+ Install it as the `tasks` extra on FastMCP:
47
+
48
+ ```bash
49
+ uv pip install "fastmcp[tasks]"
50
+ ```
51
+
52
+ Register the extension on your server and mark the tools that may run as tasks. The extension is where the backend is configured — point it at Redis for a distributed deployment, or leave it on the in-memory default for a single process:
53
+
54
+ ```python
55
+ from fastmcp import FastMCP
56
+ from fastmcp_tasks import TasksExtension
57
+
58
+ mcp = FastMCP("Analytics")
59
+ mcp.add_extension(TasksExtension(url="redis://localhost:6379/0"))
60
+
61
+
62
+ @mcp.tool(task=True)
63
+ async def analyze(dataset: str) -> str:
64
+ # Long-running work. The client gets a task handle immediately and
65
+ # polls for the result; this runs in a background worker.
66
+ ...
67
+ ```
68
+
69
+ `task=True` is a declaration of intent — this tool *may* run as a task — while the server, per the spec, decides per call whether to actually task it. Use `TaskConfig` for finer control:
70
+
71
+ ```python
72
+ from fastmcp.utilities.tasks import TaskConfig
73
+
74
+
75
+ @mcp.tool(task=TaskConfig(mode="required"))
76
+ async def must_run_async(n: int) -> int:
77
+ # Always runs as a task; a client that has not opted in is told so.
78
+ ...
79
+ ```
80
+
81
+ Registering `TasksExtension` is required to serve `task=True` tools — the tool declares intent, the extension provides the engine. A `task=True` tool on a server with no tasks extension registered fails loudly at startup rather than silently running inline.
82
+
83
+ ### Running out-of-process workers
84
+
85
+ For distributed deployments backed by Redis, run dedicated worker processes alongside your server:
86
+
87
+ ```bash
88
+ python -m fastmcp_tasks.worker_cli worker server.py
89
+ ```
90
+
91
+ Workers and servers that share a backend URL and queue name share a task queue, so you can scale execution independently of your request-serving frontends.
92
+
93
+ ## Configuration
94
+
95
+ The backend is configured on the extension. Every option also has a `FASTMCP_DOCKET_*` environment variable, so an env-configured deployment can construct `TasksExtension()` with no arguments:
96
+
97
+ | Option | Env var | Default | Description |
98
+ | --- | --- | --- | --- |
99
+ | `url` | `FASTMCP_DOCKET_URL` | `memory://` | Backend URL. `memory://` for single-process; `redis://host:port/db` for distributed workers. |
100
+ | `name` | `FASTMCP_DOCKET_NAME` | `fastmcp` | Queue name. Servers and workers sharing a name and URL share a queue. |
101
+ | `concurrency` | `FASTMCP_DOCKET_CONCURRENCY` | `10` | Maximum concurrent tasks per worker. |
102
+
103
+ See the [FastMCP task documentation](https://gofastmcp.com/servers/tasks) for the full reference.
104
+
105
+ ## Status
106
+
107
+ The tasks extension is an experimental MCP extension, and `fastmcp-tasks` tracks its draft schema. The protocol's shape is settled — SEP-2663 is Final — but field-level details may still move; this package versions independently so it can follow the schema without waiting on a FastMCP release.
@@ -0,0 +1,83 @@
1
+ # fastmcp-tasks
2
+
3
+ A complete implementation of background tasks for the Model Context Protocol — the `io.modelcontextprotocol/tasks` extension defined in [SEP-2663](https://github.com/modelcontextprotocol/ext-tasks).
4
+
5
+ The MCP tasks extension is a Final SEP, but as of this writing it ships in the ecosystem as a schema and a prose specification — no language SDK provides a working runtime for it. `fastmcp-tasks` is, to our knowledge, the first: a full server-side implementation of the protocol, built on the durable execution engine ([docket](https://github.com/chrisguidry/docket)) that FastMCP has run in production since v3. If you want to actually *run* MCP background tasks today, this is the implementation.
6
+
7
+ ## What background tasks are
8
+
9
+ Most tool calls are synchronous: the client sends `tools/call` and holds the request open until the tool returns. That breaks down for work that takes minutes or hours — a long analysis, a batch job, a slow external API. The tasks extension lets a server answer such a call *immediately* with a durable task handle, then run the work in the background while the client polls for completion on its own schedule.
10
+
11
+ The model is poll-based and stateless by construction, which is what makes it survive disconnects, server restarts, and load balancers:
12
+
13
+ 1. A client that supports tasks issues a normal `tools/call` with a per-request opt-in.
14
+ 2. The server decides whether to run it as a task. If it does, it returns a `CreateTaskResult` carrying a server-generated task id — right away, before the work starts.
15
+ 3. The client polls `tasks/get` until the task reaches a terminal state, then reads the result inlined in the response.
16
+ 4. `tasks/cancel` requests cancellation; `tasks/update` answers any input the task asks for mid-run.
17
+
18
+ The server owns the task's durable state, so the client can poll across independent requests — from any process, after a crash, through any replica — with no session affinity required.
19
+
20
+ ## Usage
21
+
22
+ Install it as the `tasks` extra on FastMCP:
23
+
24
+ ```bash
25
+ uv pip install "fastmcp[tasks]"
26
+ ```
27
+
28
+ Register the extension on your server and mark the tools that may run as tasks. The extension is where the backend is configured — point it at Redis for a distributed deployment, or leave it on the in-memory default for a single process:
29
+
30
+ ```python
31
+ from fastmcp import FastMCP
32
+ from fastmcp_tasks import TasksExtension
33
+
34
+ mcp = FastMCP("Analytics")
35
+ mcp.add_extension(TasksExtension(url="redis://localhost:6379/0"))
36
+
37
+
38
+ @mcp.tool(task=True)
39
+ async def analyze(dataset: str) -> str:
40
+ # Long-running work. The client gets a task handle immediately and
41
+ # polls for the result; this runs in a background worker.
42
+ ...
43
+ ```
44
+
45
+ `task=True` is a declaration of intent — this tool *may* run as a task — while the server, per the spec, decides per call whether to actually task it. Use `TaskConfig` for finer control:
46
+
47
+ ```python
48
+ from fastmcp.utilities.tasks import TaskConfig
49
+
50
+
51
+ @mcp.tool(task=TaskConfig(mode="required"))
52
+ async def must_run_async(n: int) -> int:
53
+ # Always runs as a task; a client that has not opted in is told so.
54
+ ...
55
+ ```
56
+
57
+ Registering `TasksExtension` is required to serve `task=True` tools — the tool declares intent, the extension provides the engine. A `task=True` tool on a server with no tasks extension registered fails loudly at startup rather than silently running inline.
58
+
59
+ ### Running out-of-process workers
60
+
61
+ For distributed deployments backed by Redis, run dedicated worker processes alongside your server:
62
+
63
+ ```bash
64
+ python -m fastmcp_tasks.worker_cli worker server.py
65
+ ```
66
+
67
+ Workers and servers that share a backend URL and queue name share a task queue, so you can scale execution independently of your request-serving frontends.
68
+
69
+ ## Configuration
70
+
71
+ The backend is configured on the extension. Every option also has a `FASTMCP_DOCKET_*` environment variable, so an env-configured deployment can construct `TasksExtension()` with no arguments:
72
+
73
+ | Option | Env var | Default | Description |
74
+ | --- | --- | --- | --- |
75
+ | `url` | `FASTMCP_DOCKET_URL` | `memory://` | Backend URL. `memory://` for single-process; `redis://host:port/db` for distributed workers. |
76
+ | `name` | `FASTMCP_DOCKET_NAME` | `fastmcp` | Queue name. Servers and workers sharing a name and URL share a queue. |
77
+ | `concurrency` | `FASTMCP_DOCKET_CONCURRENCY` | `10` | Maximum concurrent tasks per worker. |
78
+
79
+ See the [FastMCP task documentation](https://gofastmcp.com/servers/tasks) for the full reference.
80
+
81
+ ## Status
82
+
83
+ The tasks extension is an experimental MCP extension, and `fastmcp-tasks` tracks its draft schema. The protocol's shape is settled — SEP-2663 is Final — but field-level details may still move; this package versions independently so it can follow the schema without waiting on a FastMCP release.
@@ -0,0 +1,20 @@
1
+ """Background task execution for FastMCP via the SEP-2663 tasks extension."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ from fastmcp.client.extension_hooks import register_internal_client_extension_factory
6
+ from fastmcp_tasks.client import ToolTask, _build_tasks_client_extension, call_tool_task
7
+ from fastmcp_tasks.extension import TasksExtension
8
+
9
+ try:
10
+ __version__ = version("fastmcp-tasks")
11
+ except PackageNotFoundError:
12
+ __version__ = "0.0.0"
13
+
14
+ # Register the client half so every FastMCP `Client` transparently drives a
15
+ # task-serving backend's background tasks (see `fastmcp_tasks.client`). Importing
16
+ # this package — which any task deployment does, server or client side — is what
17
+ # turns on client task support.
18
+ register_internal_client_extension_factory(_build_tasks_client_extension)
19
+
20
+ __all__ = ["TasksExtension", "ToolTask", "call_tool_task", "__version__"]