osw[workflow] and osw[mcp] cannot be installed into the same environment.
osw[workflow] pins anyio>=4.4.0,<4.7
mcp>=2 requires anyio>=4.9 (anyio>=4.10 on Python 3.14+)
No anyio version satisfies both, so uv lock fails when both extras are resolvable together.
Why the anyio cap exists
prefect 2.20.25's GatherTaskGroup subclasses anyio's TaskGroup but does not
implement create_task, which newer anyio made abstract. Broken on anyio 4.14,
verified good on 4.6.2. prefect 2.20.25 is the final 2.x release, so no backport
is coming.
Current workaround
Applied in #133:
[tool.uv] conflicts declares the mcp extra mutually exclusive with both the
workflow extra and the dev dependency-group.
mcp is excluded from the all extra and from the dev group, so the default
resolution keeps the workflow-compatible anyio.
- The
dev group lists prefect and anyio directly instead of inheriting them
from osw[workflow]. Being in a conflict set, a self-referential osw[workflow]
entry would only activate under --extra workflow, leaving a bare uv sync on
anyio 4.14 (the version that breaks prefect). These pins now have to be kept in
sync with the workflow extra by hand.
- The pytest stack moved into its own
test group, since dev conflicts with the
mcp extra and there would otherwise be no environment containing both pytest
and mcp.
src/osw/mcp is excluded from ty, since its imports are unresolvable in the
default dev environment.
- The MCP unit tests use
importorskip, so they skip in the default suite.
Cost
The MCP server module is neither type-checked nor unit-tested in the default
environment. Its tests pass (32 passed against mcp==2.0.0) but only when run
explicitly:
uv sync --extra mcp --group test --no-dev
uv run --extra mcp --group test --no-dev --no-sync python -m pytest tests/test_mcp_*.py
CI does not currently run that second environment.
What to check
Whether the anyio cap is still needed, either because a newer anyio restored the
non-abstract create_task path, or because the workflow extra can move to
prefect 3.x. If the cap can be lifted, revert all six workarounds above and put
mcp back into all and dev.
osw[workflow]andosw[mcp]cannot be installed into the same environment.osw[workflow]pinsanyio>=4.4.0,<4.7mcp>=2requiresanyio>=4.9(anyio>=4.10on Python 3.14+)No anyio version satisfies both, so
uv lockfails when both extras are resolvable together.Why the anyio cap exists
prefect 2.20.25's
GatherTaskGroupsubclasses anyio'sTaskGroupbut does notimplement
create_task, which newer anyio made abstract. Broken on anyio 4.14,verified good on 4.6.2. prefect 2.20.25 is the final 2.x release, so no backport
is coming.
Current workaround
Applied in #133:
[tool.uv] conflictsdeclares themcpextra mutually exclusive with both theworkflowextra and thedevdependency-group.mcpis excluded from theallextra and from thedevgroup, so the defaultresolution keeps the workflow-compatible anyio.
devgroup listsprefectandanyiodirectly instead of inheriting themfrom
osw[workflow]. Being in a conflict set, a self-referentialosw[workflow]entry would only activate under
--extra workflow, leaving a bareuv synconanyio 4.14 (the version that breaks prefect). These pins now have to be kept in
sync with the workflow extra by hand.
testgroup, sincedevconflicts with themcpextra and there would otherwise be no environment containing both pytestand mcp.
src/osw/mcpis excluded fromty, since its imports are unresolvable in thedefault dev environment.
importorskip, so they skip in the default suite.Cost
The MCP server module is neither type-checked nor unit-tested in the default
environment. Its tests pass (32 passed against
mcp==2.0.0) but only when runexplicitly:
CI does not currently run that second environment.
What to check
Whether the anyio cap is still needed, either because a newer anyio restored the
non-abstract
create_taskpath, or because the workflow extra can move toprefect 3.x. If the cap can be lifted, revert all six workarounds above and put
mcpback intoallanddev.