Scaffold fastmcp-tasks workspace package

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jeremiah Lowin 2026-07-21 20:44:54 -04:00
commit 242850c0f3
No known key found for this signature in database
7 changed files with 101 additions and 13 deletions

View file

@ -108,4 +108,3 @@ server = [
"watchfiles>=1.0.0",
"websockets>=15.0.1",
]
tasks = ["pydocket>=0.20.0"]

9
fastmcp_tasks/README.md Normal file
View file

@ -0,0 +1,9 @@
# fastmcp-tasks
`fastmcp-tasks` provides background task execution for FastMCP servers via the `io.modelcontextprotocol/tasks` extension ([SEP-2663](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2663)).
It bundles the task-queue dependencies (powered by [docket](https://github.com/chrisguidry/docket)) that FastMCP's `tasks` extra requires. Install it alongside [FastMCP](https://gofastmcp.com) to run long-lived tools as background tasks instead of blocking a request for their full duration.
```bash
uv pip install "fastmcp[tasks]"
```

View file

@ -0,0 +1,10 @@
"""Background task execution for FastMCP via the SEP-2663 tasks extension."""
from importlib.metadata import PackageNotFoundError, version
try:
__version__ = version("fastmcp-tasks")
except PackageNotFoundError:
__version__ = "0.0.0"
__all__ = ["__version__"]

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,57 @@
[project]
name = "fastmcp-tasks"
dynamic = ["version", "dependencies"]
description = "Background task execution for FastMCP servers via the io.modelcontextprotocol/tasks extension (SEP-2663)."
authors = [{ name = "Jeremiah Lowin" }]
requires-python = ">=3.10"
readme = "README.md"
license = "Apache-2.0"
keywords = [
"mcp",
"fastmcp tasks",
"background tasks",
"model context protocol",
"fastmcp",
]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Typing :: Typed",
]
[project.urls]
Homepage = "https://gofastmcp.com"
Repository = "https://github.com/PrefectHQ/fastmcp"
Documentation = "https://gofastmcp.com"
[build-system]
requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"]
build-backend = "hatchling.build"
[tool.hatch.version]
source = "uv-dynamic-versioning"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["fastmcp_tasks"]
[tool.uv-dynamic-versioning]
vcs = "git"
style = "pep440"
bump = true
fallback-version = "0.0.0"
[tool.hatch.metadata.hooks.uv-dynamic-versioning]
dependencies = [
"fastmcp-slim[server]=={{ version }}",
"pydocket>=0.20.0",
]

View file

@ -58,7 +58,7 @@ azure = ["fastmcp-slim[azure]=={{ version }}"]
code-mode = ["fastmcp-slim[code-mode]=={{ version }}"]
gemini = ["fastmcp-slim[gemini]=={{ version }}"]
openai = ["fastmcp-slim[openai]=={{ version }}"]
tasks = ["fastmcp-slim[tasks]=={{ version }}"]
tasks = ["fastmcp-tasks=={{ version }}"]
[tool.uv-dynamic-versioning]
vcs = "git"
@ -67,7 +67,7 @@ bump = true
fallback-version = "0.0.0"
[tool.uv.workspace]
members = ["fastmcp_slim", "fastmcp_remote"]
members = ["fastmcp_slim", "fastmcp_remote", "fastmcp_tasks"]
[tool.uv]
default-groups = ["dev"]
@ -108,6 +108,7 @@ dev = [
fastmcp = { workspace = true }
fastmcp-slim = { workspace = true }
fastmcp-remote = { workspace = true }
fastmcp-tasks = { workspace = true }
[tool.pytest.ini_options]
asyncio_mode = "auto"
@ -129,7 +130,7 @@ markers = [
"subprocess_heavy: marks tests that spawn a fresh Python interpreter which imports FastMCP. Each one costs a full interpreter's memory and startup, so they run serially alongside client_process tests rather than competing with parallel xdist workers.",
"conformance: marks MCP conformance tests (require Node.js/npx)",
]
pythonpath = ["fastmcp_slim", "fastmcp_remote"]
pythonpath = ["fastmcp_slim", "fastmcp_remote", "fastmcp_tasks"]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
@ -137,7 +138,7 @@ python_functions = ["test_*"]
addopts = ["--inline-snapshot=disable"]
[tool.ty.src]
include = ["fastmcp_slim", "fastmcp_remote", "tests", "examples"]
include = ["fastmcp_slim", "fastmcp_remote", "fastmcp_tasks", "tests", "examples"]
exclude = [
"**/node_modules",
"**/__pycache__",

27
uv.lock generated
View file

@ -10,7 +10,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2026-07-07T19:26:14.279827Z"
exclude-newer = "2026-07-15T00:39:08.277536Z"
exclude-newer-span = "P1W"
[options.exclude-newer-package]
@ -26,6 +26,7 @@ members = [
"fastmcp",
"fastmcp-remote",
"fastmcp-slim",
"fastmcp-tasks",
]
[[package]]
@ -864,7 +865,7 @@ openai = [
{ name = "fastmcp-slim", extra = ["openai"] },
]
tasks = [
{ name = "fastmcp-slim", extra = ["tasks"] },
{ name = "fastmcp-tasks" },
]
[package.dev-dependencies]
@ -908,7 +909,7 @@ requires-dist = [
{ name = "fastmcp-slim", extras = ["code-mode"], marker = "extra == 'code-mode'", editable = "fastmcp_slim" },
{ name = "fastmcp-slim", extras = ["gemini"], marker = "extra == 'gemini'", editable = "fastmcp_slim" },
{ name = "fastmcp-slim", extras = ["openai"], marker = "extra == 'openai'", editable = "fastmcp_slim" },
{ name = "fastmcp-slim", extras = ["tasks"], marker = "extra == 'tasks'", editable = "fastmcp_slim" },
{ name = "fastmcp-tasks", marker = "extra == 'tasks'", editable = "fastmcp_tasks" },
]
provides-extras = ["anthropic", "apps", "azure", "code-mode", "gemini", "openai", "tasks"]
@ -1025,9 +1026,6 @@ server = [
{ name = "watchfiles" },
{ name = "websockets" },
]
tasks = [
{ name = "pydocket" },
]
[package.metadata]
requires-dist = [
@ -1065,7 +1063,6 @@ requires-dist = [
{ name = "pydantic", extras = ["email"], specifier = ">=2.12.0" },
{ name = "pydantic-monty", marker = "extra == 'code-mode'", specifier = "==0.0.17" },
{ name = "pydantic-settings", specifier = ">=2.0.0" },
{ name = "pydocket", marker = "extra == 'tasks'", specifier = ">=0.20.0" },
{ name = "pyjwt", marker = "extra == 'azure'", specifier = ">=2.12.0" },
{ name = "pyperclip", marker = "extra == 'server'", specifier = ">=1.9.0" },
{ name = "python-dotenv", specifier = ">=1.1.0" },
@ -1081,7 +1078,21 @@ requires-dist = [
{ name = "watchfiles", marker = "extra == 'server'", specifier = ">=1.0.0" },
{ name = "websockets", marker = "extra == 'server'", specifier = ">=15.0.1" },
]
provides-extras = ["anthropic", "apps", "azure", "client", "code-mode", "gemini", "mcp", "openai", "server", "tasks"]
provides-extras = ["anthropic", "apps", "azure", "client", "code-mode", "gemini", "mcp", "openai", "server"]
[[package]]
name = "fastmcp-tasks"
source = { editable = "fastmcp_tasks" }
dependencies = [
{ name = "fastmcp-slim", extra = ["server"] },
{ name = "pydocket" },
]
[package.metadata]
requires-dist = [
{ name = "fastmcp-slim", extras = ["server"], editable = "fastmcp_slim" },
{ name = "pydocket", specifier = ">=0.20.0" },
]
[[package]]
name = "google-auth"