From ee48a0fd6e077e1c32e996f7b51fd442e31c514f Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Tue, 12 May 2026 10:11:57 -0400 Subject: [PATCH] Refine fastmcp-slim packaging (#4125) * Refine fastmcp-slim packaging * Format install hints --- .github/workflows/run-tests.yml | 32 +++++- fastmcp_slim/fastmcp/__init__.py | 31 ++---- fastmcp_slim/fastmcp/_install_hints.py | 25 +++++ fastmcp_slim/fastmcp/cli/__init__.py | 7 +- fastmcp_slim/fastmcp/cli/__main__.py | 2 +- fastmcp_slim/fastmcp/client/__init__.py | 7 +- .../fastmcp/client/transports/config.py | 4 +- .../fastmcp/client/transports/memory.py | 6 +- fastmcp_slim/fastmcp/mcp_config.py | 12 ++- fastmcp_slim/fastmcp/server/__init__.py | 7 +- fastmcp_slim/pyproject.toml | 92 +++++++--------- pyproject.toml | 23 ++-- uv.lock | 100 +++++++----------- 13 files changed, 175 insertions(+), 173 deletions(-) create mode 100644 fastmcp_slim/fastmcp/_install_hints.py diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c2f77cc18..a3a144677 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -145,7 +145,14 @@ jobs: import fastmcp import fastmcp.settings - assert not any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts")) + assert any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts")) + + try: + from fastmcp.cli import app + except ImportError as exc: + assert "FastMCP CLI support is not installed" in str(exc) + else: + raise AssertionError(f"bare fastmcp-slim unexpectedly imported CLI app {app!r}") try: fastmcp.FastMCP @@ -167,7 +174,14 @@ jobs: from fastmcp.client.transports import StdioTransport, StreamableHttpTransport from fastmcp.mcp_config import MCPConfig - assert not any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts")) + assert any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts")) + + try: + from fastmcp.cli import app + except ImportError as exc: + assert "FastMCP CLI support is not installed" in str(exc) + else: + raise AssertionError(f"client-only slim unexpectedly imported CLI app {app!r}") assert Client("https://example.com/mcp") assert StreamableHttpTransport("https://example.com/mcp") @@ -188,9 +202,18 @@ jobs: SLIM_WHEEL=$(ls /tmp/fastmcp-dist/fastmcp_slim-*.whl) uv pip install --python /tmp/fastmcp-slim-server-smoke/bin/python "${SLIM_WHEEL}[server]" /tmp/fastmcp-slim-server-smoke/bin/python - <<'PY' + from importlib.metadata import entry_points + from fastmcp import FastMCP + from fastmcp.cli import app + + assert any( + ep.name == "fastmcp" and ep.value == "fastmcp.cli:app" + for ep in entry_points(group="console_scripts") + ) mcp = FastMCP("smoke") + assert app is not None assert mcp.name == "smoke" PY @@ -201,11 +224,16 @@ jobs: uv pip install --python /tmp/fastmcp-full-smoke/bin/python --find-links /tmp/fastmcp-dist "$FULL_WHEEL" /tmp/fastmcp-full-smoke/bin/python - <<'PY' from importlib.metadata import entry_points + from importlib.metadata import requires from fastmcp import Client, FastMCP from fastmcp.client.client import CallToolResult from fastmcp.exceptions import ToolError + fastmcp_reqs = requires("fastmcp") or [] + assert any("fastmcp-slim[client,server]" in req for req in fastmcp_reqs) + assert not any("fastmcp-slim[full" in req for req in fastmcp_reqs) + assert any( ep.name == "fastmcp" and ep.value == "fastmcp.cli:app" for ep in entry_points(group="console_scripts") diff --git a/fastmcp_slim/fastmcp/__init__.py b/fastmcp_slim/fastmcp/__init__.py index 592d5066e..ab9f9358d 100644 --- a/fastmcp_slim/fastmcp/__init__.py +++ b/fastmcp_slim/fastmcp/__init__.py @@ -5,6 +5,7 @@ import warnings from importlib.metadata import PackageNotFoundError, version as _version from typing import TYPE_CHECKING +from fastmcp import _install_hints from fastmcp.settings import Settings from fastmcp.utilities.logging import configure_logging as _configure_logging @@ -48,40 +49,28 @@ def __getattr__(name: str) -> object: try: from fastmcp.client import Client except ImportError as exc: - raise ImportError( - "FastMCP client support is not installed. Install " - "`fastmcp-slim[client]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.CLIENT_SUPPORT) from exc return Client if name == "Context": try: from fastmcp.server.context import Context except ImportError as exc: - raise ImportError( - "FastMCP server support is not installed. Install " - "`fastmcp-slim[server]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.SERVER_SUPPORT) from exc return Context if name == "FastMCP": try: from fastmcp.server.server import FastMCP except ImportError as exc: - raise ImportError( - "FastMCP server support is not installed. Install " - "`fastmcp-slim[server]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.SERVER_SUPPORT) from exc return FastMCP if name == "FastMCPApp": try: from fastmcp.apps.app import FastMCPApp except ImportError as exc: - raise ImportError( - "FastMCP app support is not installed. Install " - "`fastmcp-slim[server,apps]` or `fastmcp[apps]`." - ) from exc + raise ImportError(_install_hints.APP_SUPPORT) from exc return FastMCPApp if name == "FastMCPDeprecationWarning": @@ -92,18 +81,12 @@ def __getattr__(name: str) -> object: try: return importlib.import_module("fastmcp.client") except ImportError as exc: - raise ImportError( - "FastMCP client support is not installed. Install " - "`fastmcp-slim[client]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.CLIENT_SUPPORT) from exc if name == "server": try: return importlib.import_module("fastmcp.server") except ImportError as exc: - raise ImportError( - "FastMCP server support is not installed. Install " - "`fastmcp-slim[server]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.SERVER_SUPPORT) from exc raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/fastmcp_slim/fastmcp/_install_hints.py b/fastmcp_slim/fastmcp/_install_hints.py new file mode 100644 index 000000000..89c25f490 --- /dev/null +++ b/fastmcp_slim/fastmcp/_install_hints.py @@ -0,0 +1,25 @@ +CLIENT_SUPPORT = ( + "FastMCP client support is not installed. Install `fastmcp` or " + "`fastmcp-slim[client]`." +) + +SERVER_SUPPORT = ( + "FastMCP server support is not installed. Install `fastmcp` or " + "`fastmcp-slim[server]`." +) + +APP_SUPPORT = ( + "FastMCP app support is not installed. Install `fastmcp[apps]` or " + "`fastmcp-slim[server,apps]`." +) + +CLI_SUPPORT = ( + "FastMCP CLI support is not installed. Install `fastmcp` or `fastmcp-slim[server]`." +) + + +def full_package(feature: str) -> str: + return ( + f"{feature} require the full `fastmcp` package. " + "Install it with `pip install fastmcp`." + ) diff --git a/fastmcp_slim/fastmcp/cli/__init__.py b/fastmcp_slim/fastmcp/cli/__init__.py index 091667730..9afa62132 100644 --- a/fastmcp_slim/fastmcp/cli/__init__.py +++ b/fastmcp_slim/fastmcp/cli/__init__.py @@ -1,3 +1,8 @@ """FastMCP CLI package.""" -from .cli import app +try: + from .cli import app +except ImportError as exc: + from fastmcp import _install_hints + + raise ImportError(_install_hints.CLI_SUPPORT) from exc diff --git a/fastmcp_slim/fastmcp/cli/__main__.py b/fastmcp_slim/fastmcp/cli/__main__.py index aca24b145..92500fb7c 100644 --- a/fastmcp_slim/fastmcp/cli/__main__.py +++ b/fastmcp_slim/fastmcp/cli/__main__.py @@ -1,5 +1,5 @@ """FastMCP CLI as a runnable package""" -from .cli import app +from . import app app() diff --git a/fastmcp_slim/fastmcp/client/__init__.py b/fastmcp_slim/fastmcp/client/__init__.py index 02e0c1079..d5e65e229 100644 --- a/fastmcp_slim/fastmcp/client/__init__.py +++ b/fastmcp_slim/fastmcp/client/__init__.py @@ -1,3 +1,5 @@ +from fastmcp import _install_hints + try: from .auth import OAuth, BearerAuth from .client import Client @@ -14,10 +16,7 @@ try: UvxStdioTransport, ) except ImportError as exc: - raise ImportError( - "FastMCP client support is not installed. Install " - "`fastmcp-slim[client]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.CLIENT_SUPPORT) from exc __all__ = [ "BearerAuth", diff --git a/fastmcp_slim/fastmcp/client/transports/config.py b/fastmcp_slim/fastmcp/client/transports/config.py index 97208174b..f272c0126 100644 --- a/fastmcp_slim/fastmcp/client/transports/config.py +++ b/fastmcp_slim/fastmcp/client/transports/config.py @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any from mcp import ClientSession from typing_extensions import Unpack +from fastmcp import _install_hints from fastmcp.client.transports.base import ClientTransport, SessionKwargs from fastmcp.client.transports.memory import FastMCPTransport from fastmcp.mcp_config import ( @@ -105,8 +106,7 @@ class MCPConfigTransport(ClientTransport): from fastmcp.server.server import FastMCP except ImportError as exc: raise ImportError( - "MCP configs with multiple servers require the full `fastmcp` " - "package for now. Install it with `pip install fastmcp`." + _install_hints.full_package("MCP configs with multiple servers") ) from exc timeout = session_kwargs.get("read_timeout_seconds") diff --git a/fastmcp_slim/fastmcp/client/transports/memory.py b/fastmcp_slim/fastmcp/client/transports/memory.py index d74708029..5a52191ed 100644 --- a/fastmcp_slim/fastmcp/client/transports/memory.py +++ b/fastmcp_slim/fastmcp/client/transports/memory.py @@ -9,6 +9,7 @@ from mcp.server.fastmcp import FastMCP as FastMCP1Server from mcp.shared.memory import create_client_server_memory_streams from typing_extensions import Unpack +from fastmcp import _install_hints from fastmcp.client.transports.base import ClientTransport, SessionKwargs if TYPE_CHECKING: @@ -103,10 +104,7 @@ async def _enter_server_lifespan( FastMCP2 = None if FastMCP2 is None and not isinstance(server, FastMCP1Server): - raise ImportError( - "In-memory FastMCP transports require the full `fastmcp` package. " - "Install it with `pip install fastmcp`." - ) + raise ImportError(_install_hints.full_package("In-memory FastMCP transports")) if FastMCP2 is not None and isinstance(server, FastMCP2): async with server._lifespan_manager(): diff --git a/fastmcp_slim/fastmcp/mcp_config.py b/fastmcp_slim/fastmcp/mcp_config.py index 13c1abd6a..81f71beba 100644 --- a/fastmcp_slim/fastmcp/mcp_config.py +++ b/fastmcp_slim/fastmcp/mcp_config.py @@ -40,6 +40,8 @@ from pydantic import ( ) from typing_extensions import Self, override +from fastmcp import _install_hints + if TYPE_CHECKING: from fastmcp.client.transports import ( ClientTransport, @@ -129,8 +131,9 @@ class _TransformingMCPServerMixin(BaseModel): from fastmcp.server.transforms import ToolTransform except ImportError as exc: raise ImportError( - "MCP configs that use FastMCP-specific tool transforms or tag filters " - "require the full `fastmcp` package. Install it with `pip install fastmcp`." + _install_hints.full_package( + "MCP configs that use FastMCP-specific tool transforms or tag filters" + ) ) from exc transport = cast("ClientTransport", super().to_transport()) # ty: ignore[unresolved-attribute] @@ -154,8 +157,9 @@ class _TransformingMCPServerMixin(BaseModel): from fastmcp.client.transports import FastMCPTransport except ImportError as exc: raise ImportError( - "MCP configs that use FastMCP-specific tool transforms or tag filters " - "require the full `fastmcp` package. Install it with `pip install fastmcp`." + _install_hints.full_package( + "MCP configs that use FastMCP-specific tool transforms or tag filters" + ) ) from exc return FastMCPTransport(mcp=self._to_server_and_underlying_transport()[0]) diff --git a/fastmcp_slim/fastmcp/server/__init__.py b/fastmcp_slim/fastmcp/server/__init__.py index 08ac85c34..d6edbc4f1 100644 --- a/fastmcp_slim/fastmcp/server/__init__.py +++ b/fastmcp_slim/fastmcp/server/__init__.py @@ -1,13 +1,12 @@ import importlib +from fastmcp import _install_hints + try: from .context import Context from .server import FastMCP, create_proxy except ImportError as exc: - raise ImportError( - "FastMCP server support is not installed. Install " - "`fastmcp-slim[server]` or `fastmcp`." - ) from exc + raise ImportError(_install_hints.SERVER_SUPPORT) from exc def __getattr__(name: str) -> object: diff --git a/fastmcp_slim/pyproject.toml b/fastmcp_slim/pyproject.toml index 0f69170f7..df1274fd5 100644 --- a/fastmcp_slim/pyproject.toml +++ b/fastmcp_slim/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "fastmcp-slim" -dynamic = ["version"] +dynamic = ["version", "optional-dependencies"] description = "The dependency-slim FastMCP package." authors = [{ name = "Jeremiah Lowin" }] dependencies = [ @@ -36,32 +36,60 @@ classifiers = [ "Typing :: Typed", ] -[project.optional-dependencies] +[project.urls] +Homepage = "https://gofastmcp.com" +Repository = "https://github.com/PrefectHQ/fastmcp" +Documentation = "https://gofastmcp.com" + +[project.scripts] +fastmcp = "fastmcp.cli:app" + +[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"] + +[tool.uv-dynamic-versioning] +vcs = "git" +style = "pep440" +bump = true +fallback-version = "0.0.0" + +[tool.hatch.metadata.hooks.uv-dynamic-versioning.optional-dependencies] anthropic = ["anthropic>=0.48.0"] apps = ["prefab-ui>=0.18.0"] # PyJWT floor: transitive via msal; CVE-2026-32597 affects <= 2.11.0 azure = ["azure-identity>=1.16.0", "PyJWT>=2.12.0"] client = [ + "fastmcp-slim[mcp]=={{ version }}", "authlib>=1.6.11", - "exceptiongroup>=1.2.2", - "httpx>=0.28.1,<1.0", - "mcp>=1.24.0,<2.0", - "opentelemetry-api>=1.20.0", "py-key-value-aio[filetree,keyring,memory]>=0.4.4,<0.5.0", ] code-mode = ["pydantic-monty==0.0.16"] gemini = ["google-genai>=1.18.0", "jsonref>=1.1.0"] -full = [ +mcp = [ + "exceptiongroup>=1.2.2", + "httpx>=0.28.1,<1.0", + "mcp>=1.24.0,<2.0", + "opentelemetry-api>=1.20.0", +] +openai = ["openai>=1.102.0"] +server = [ + "fastmcp-slim[mcp]=={{ version }}", "authlib>=1.6.11", "cyclopts>=4.0.0", - "exceptiongroup>=1.2.2", "griffelib>=2.0.0", - "httpx>=0.28.1,<1.0", "jsonref>=1.1.0", "jsonschema-path>=0.3.4", - "mcp>=1.24.0,<2.0", "openapi-pydantic>=0.5.1", - "opentelemetry-api>=1.20.0", "packaging>=24.0", "py-key-value-aio[filetree,keyring,memory]>=0.4.4,<0.5.0", "pyperclip>=1.9.0", @@ -72,46 +100,4 @@ full = [ "watchfiles>=1.0.0", "websockets>=15.0.1", ] -openai = ["openai>=1.102.0"] -server = [ - "authlib>=1.6.11", - "exceptiongroup>=1.2.2", - "griffelib>=2.0.0", - "httpx>=0.28.1,<1.0", - "jsonref>=1.1.0", - "jsonschema-path>=0.3.4", - "mcp>=1.24.0,<2.0", - "openapi-pydantic>=0.5.1", - "opentelemetry-api>=1.20.0", - "packaging>=24.0", - "py-key-value-aio[filetree,keyring,memory]>=0.4.4,<0.5.0", - "python-multipart>=0.0.26", - "pyyaml>=6.0,<7.0", - "uncalled-for>=0.2.0", - "uvicorn>=0.35", - "watchfiles>=1.0.0", - "websockets>=15.0.1", -] tasks = ["pydocket>=0.20.0"] - -[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.build.targets.wheel] -packages = ["fastmcp"] - - -[tool.uv-dynamic-versioning] -vcs = "git" -style = "pep440" -bump = true -fallback-version = "0.0.0" diff --git a/pyproject.toml b/pyproject.toml index 5e1cee944..1813bf0e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,9 +31,6 @@ Homepage = "https://gofastmcp.com" Repository = "https://github.com/PrefectHQ/fastmcp" Documentation = "https://gofastmcp.com" -[project.scripts] -fastmcp = "fastmcp.cli:app" - [build-system] requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"] build-backend = "hatchling.build" @@ -43,21 +40,25 @@ source = "uv-dynamic-versioning" [tool.hatch.build.targets.wheel] bypass-selection = true +only-include = [] +exclude = ["/*"] [tool.hatch.metadata] allow-direct-references = true [tool.hatch.metadata.hooks.uv-dynamic-versioning] -dependencies = ["fastmcp-slim[full]=={{ version }}"] +dependencies = [ + "fastmcp-slim[client,server]=={{ version }}", +] [tool.hatch.metadata.hooks.uv-dynamic-versioning.optional-dependencies] -anthropic = ["fastmcp-slim[full,anthropic]=={{ version }}"] -apps = ["fastmcp-slim[full,apps]=={{ version }}"] -azure = ["fastmcp-slim[full,azure]=={{ version }}"] -code-mode = ["fastmcp-slim[full,code-mode]=={{ version }}"] -gemini = ["fastmcp-slim[full,gemini]=={{ version }}"] -openai = ["fastmcp-slim[full,openai]=={{ version }}"] -tasks = ["fastmcp-slim[full,tasks]=={{ version }}"] +anthropic = ["fastmcp-slim[anthropic]=={{ version }}"] +apps = ["fastmcp-slim[apps]=={{ version }}"] +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 }}"] [tool.uv-dynamic-versioning] vcs = "git" diff --git a/uv.lock b/uv.lock index 5246f4cc7..414e445b9 100644 --- a/uv.lock +++ b/uv.lock @@ -830,30 +830,30 @@ wheels = [ name = "fastmcp" source = { editable = "." } dependencies = [ - { name = "fastmcp-slim", extra = ["full"] }, + { name = "fastmcp-slim", extra = ["client", "server"] }, ] [package.optional-dependencies] anthropic = [ - { name = "fastmcp-slim", extra = ["anthropic", "full"] }, + { name = "fastmcp-slim", extra = ["anthropic"] }, ] apps = [ - { name = "fastmcp-slim", extra = ["apps", "full"] }, + { name = "fastmcp-slim", extra = ["apps"] }, ] azure = [ - { name = "fastmcp-slim", extra = ["azure", "full"] }, + { name = "fastmcp-slim", extra = ["azure"] }, ] code-mode = [ - { name = "fastmcp-slim", extra = ["code-mode", "full"] }, + { name = "fastmcp-slim", extra = ["code-mode"] }, ] gemini = [ - { name = "fastmcp-slim", extra = ["full", "gemini"] }, + { name = "fastmcp-slim", extra = ["gemini"] }, ] openai = [ - { name = "fastmcp-slim", extra = ["full", "openai"] }, + { name = "fastmcp-slim", extra = ["openai"] }, ] tasks = [ - { name = "fastmcp-slim", extra = ["full", "tasks"] }, + { name = "fastmcp-slim", extra = ["tasks"] }, ] [package.dev-dependencies] @@ -890,14 +890,14 @@ dev = [ [package.metadata] requires-dist = [ - { name = "fastmcp-slim", extras = ["anthropic", "full"], marker = "extra == 'anthropic'", editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["apps", "full"], marker = "extra == 'apps'", editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["azure", "full"], marker = "extra == 'azure'", editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["code-mode", "full"], marker = "extra == 'code-mode'", editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["full"], editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["full", "gemini"], marker = "extra == 'gemini'", editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["full", "openai"], marker = "extra == 'openai'", editable = "fastmcp_slim" }, - { name = "fastmcp-slim", extras = ["full", "tasks"], marker = "extra == 'tasks'", editable = "fastmcp_slim" }, + { name = "fastmcp-slim", extras = ["anthropic"], marker = "extra == 'anthropic'", editable = "fastmcp_slim" }, + { name = "fastmcp-slim", extras = ["apps"], marker = "extra == 'apps'", editable = "fastmcp_slim" }, + { name = "fastmcp-slim", extras = ["azure"], marker = "extra == 'azure'", editable = "fastmcp_slim" }, + { name = "fastmcp-slim", extras = ["client", "server"], editable = "fastmcp_slim" }, + { 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" }, ] provides-extras = ["anthropic", "apps", "azure", "code-mode", "gemini", "openai", "tasks"] @@ -965,7 +965,20 @@ client = [ code-mode = [ { name = "pydantic-monty" }, ] -full = [ +gemini = [ + { name = "google-genai" }, + { name = "jsonref" }, +] +mcp = [ + { name = "exceptiongroup" }, + { name = "httpx" }, + { name = "mcp" }, + { name = "opentelemetry-api" }, +] +openai = [ + { name = "openai" }, +] +server = [ { name = "authlib" }, { name = "cyclopts" }, { name = "exceptiongroup" }, @@ -986,32 +999,6 @@ full = [ { name = "watchfiles" }, { name = "websockets" }, ] -gemini = [ - { name = "google-genai" }, - { name = "jsonref" }, -] -openai = [ - { name = "openai" }, -] -server = [ - { name = "authlib" }, - { name = "exceptiongroup" }, - { name = "griffelib" }, - { name = "httpx" }, - { name = "jsonref" }, - { name = "jsonschema-path" }, - { name = "mcp" }, - { name = "openapi-pydantic" }, - { name = "opentelemetry-api" }, - { name = "packaging" }, - { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"] }, - { name = "python-multipart" }, - { name = "pyyaml" }, - { name = "uncalled-for" }, - { name = "uvicorn" }, - { name = "watchfiles" }, - { name = "websockets" }, -] tasks = [ { name = "pydocket" }, ] @@ -1020,63 +1007,50 @@ tasks = [ requires-dist = [ { name = "anthropic", marker = "extra == 'anthropic'", specifier = ">=0.48.0" }, { name = "authlib", marker = "extra == 'client'", specifier = ">=1.6.11" }, - { name = "authlib", marker = "extra == 'full'", specifier = ">=1.6.11" }, { name = "authlib", marker = "extra == 'server'", specifier = ">=1.6.11" }, { name = "azure-identity", marker = "extra == 'azure'", specifier = ">=1.16.0" }, - { name = "cyclopts", marker = "extra == 'full'", specifier = ">=4.0.0" }, + { name = "cyclopts", marker = "extra == 'server'", specifier = ">=4.0.0" }, { name = "exceptiongroup", marker = "extra == 'client'", specifier = ">=1.2.2" }, - { name = "exceptiongroup", marker = "extra == 'full'", specifier = ">=1.2.2" }, + { name = "exceptiongroup", marker = "extra == 'mcp'", specifier = ">=1.2.2" }, { name = "exceptiongroup", marker = "extra == 'server'", specifier = ">=1.2.2" }, { name = "google-genai", marker = "extra == 'gemini'", specifier = ">=1.18.0" }, - { name = "griffelib", marker = "extra == 'full'", specifier = ">=2.0.0" }, { name = "griffelib", marker = "extra == 'server'", specifier = ">=2.0.0" }, { name = "httpx", marker = "extra == 'client'", specifier = ">=0.28.1,<1.0" }, - { name = "httpx", marker = "extra == 'full'", specifier = ">=0.28.1,<1.0" }, + { name = "httpx", marker = "extra == 'mcp'", specifier = ">=0.28.1,<1.0" }, { name = "httpx", marker = "extra == 'server'", specifier = ">=0.28.1,<1.0" }, - { name = "jsonref", marker = "extra == 'full'", specifier = ">=1.1.0" }, { name = "jsonref", marker = "extra == 'gemini'", specifier = ">=1.1.0" }, { name = "jsonref", marker = "extra == 'server'", specifier = ">=1.1.0" }, - { name = "jsonschema-path", marker = "extra == 'full'", specifier = ">=0.3.4" }, { name = "jsonschema-path", marker = "extra == 'server'", specifier = ">=0.3.4" }, { name = "mcp", marker = "extra == 'client'", specifier = ">=1.24.0,<2.0" }, - { name = "mcp", marker = "extra == 'full'", specifier = ">=1.24.0,<2.0" }, + { name = "mcp", marker = "extra == 'mcp'", specifier = ">=1.24.0,<2.0" }, { name = "mcp", marker = "extra == 'server'", specifier = ">=1.24.0,<2.0" }, { name = "openai", marker = "extra == 'openai'", specifier = ">=1.102.0" }, - { name = "openapi-pydantic", marker = "extra == 'full'", specifier = ">=0.5.1" }, { name = "openapi-pydantic", marker = "extra == 'server'", specifier = ">=0.5.1" }, { name = "opentelemetry-api", marker = "extra == 'client'", specifier = ">=1.20.0" }, - { name = "opentelemetry-api", marker = "extra == 'full'", specifier = ">=1.20.0" }, + { name = "opentelemetry-api", marker = "extra == 'mcp'", specifier = ">=1.20.0" }, { name = "opentelemetry-api", marker = "extra == 'server'", specifier = ">=1.20.0" }, - { name = "packaging", marker = "extra == 'full'", specifier = ">=24.0" }, { name = "packaging", marker = "extra == 'server'", specifier = ">=24.0" }, { name = "platformdirs", specifier = ">=4.0.0" }, { name = "prefab-ui", marker = "extra == 'apps'", specifier = ">=0.18.0" }, { name = "py-key-value-aio", extras = ["filetree", "keyring", "memory"], marker = "extra == 'client'", specifier = ">=0.4.4,<0.5.0" }, - { name = "py-key-value-aio", extras = ["filetree", "keyring", "memory"], marker = "extra == 'full'", specifier = ">=0.4.4,<0.5.0" }, { name = "py-key-value-aio", extras = ["filetree", "keyring", "memory"], marker = "extra == 'server'", specifier = ">=0.4.4,<0.5.0" }, { name = "pydantic", extras = ["email"], specifier = ">=2.11.7" }, { name = "pydantic-monty", marker = "extra == 'code-mode'", specifier = "==0.0.16" }, { 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 == 'full'", specifier = ">=1.9.0" }, + { name = "pyperclip", marker = "extra == 'server'", specifier = ">=1.9.0" }, { name = "python-dotenv", specifier = ">=1.1.0" }, - { name = "python-multipart", marker = "extra == 'full'", specifier = ">=0.0.26" }, { name = "python-multipart", marker = "extra == 'server'", specifier = ">=0.0.26" }, - { name = "pyyaml", marker = "extra == 'full'", specifier = ">=6.0,<7.0" }, { name = "pyyaml", marker = "extra == 'server'", specifier = ">=6.0,<7.0" }, { name = "rich", specifier = ">=13.9.4" }, { name = "typing-extensions", specifier = ">=4.0.0" }, - { name = "uncalled-for", marker = "extra == 'full'", specifier = ">=0.2.0" }, { name = "uncalled-for", marker = "extra == 'server'", specifier = ">=0.2.0" }, - { name = "uvicorn", marker = "extra == 'full'", specifier = ">=0.35" }, { name = "uvicorn", marker = "extra == 'server'", specifier = ">=0.35" }, - { name = "watchfiles", marker = "extra == 'full'", specifier = ">=1.0.0" }, { name = "watchfiles", marker = "extra == 'server'", specifier = ">=1.0.0" }, - { name = "websockets", marker = "extra == 'full'", specifier = ">=15.0.1" }, { name = "websockets", marker = "extra == 'server'", specifier = ">=15.0.1" }, ] -provides-extras = ["anthropic", "apps", "azure", "client", "code-mode", "full", "gemini", "openai", "server", "tasks"] +provides-extras = ["anthropic", "apps", "azure", "client", "code-mode", "gemini", "mcp", "openai", "server", "tasks"] [[package]] name = "google-auth"