From 0889af7dfc41c6201e2d888ef98f377a9db3bc22 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Sun, 28 Jun 2026 14:46:01 +0100 Subject: [PATCH] Always install ``fastmcp`` in preparation for pydantic-ai 2.0.0, which replaced the dependency on `fastmcp` with `fastmcp-slim[client]`. Otherwise Galaxy fails to start with: ``` Traceback (most recent call last): File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/fastmcp/server/__init__.py", line 6, in from .context import Context File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/fastmcp/server/context.py", line 28, in from uncalled_for import SharedContext ModuleNotFoundError: No module named 'uncalled_for' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/fastmcp/__init__.py", line 57, in __getattr__ from fastmcp.server.context import Context File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/fastmcp/server/__init__.py", line 9, in raise ImportError(_install_hints.SERVER_SUPPORT) from exc ImportError: FastMCP server support is not installed. Install `fastmcp` or `fastmcp-slim[server]`. The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/bin/gunicorn", line 10, in sys.exit(run()) File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 66, in run WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]", prog=prog).run() File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 235, in run super().run() File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 71, in run Arbiter(self).run() File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/arbiter.py", line 63, in __init__ self.setup(app) File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/arbiter.py", line 139, in setup self.app.wsgi() File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 66, in wsgi self.callable = self.load() File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 57, in load return self.load_wsgiapp() File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 47, in load_wsgiapp return util.import_app(self.app_uri) File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/gunicorn/util.py", line 464, in import_app app = app(*args, **kwargs) File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/lib/galaxy/webapps/galaxy/fast_factory.py", line 63, in factory gx_wsgi_webapp, gx_app = app_pair( File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/lib/galaxy/webapps/galaxy/buildapp.py", line 178, in app_pair populate_api_routes(webapp, app) File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/lib/galaxy/webapps/galaxy/buildapp.py", line 362, in populate_api_routes webapp.add_api_controllers("galaxy.webapps.galaxy.api", app) File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/lib/galaxy/webapps/base/webapp.py", line 252, in add_api_controllers for name, module in base.walk_controller_modules(package_name): File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/lib/galaxy/web/framework/base.py", line 624, in walk_controller_modules module = import_module(module_name) File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "", line 1050, in _gcd_import File "", line 1027, in _find_and_load File "", line 1006, in _find_and_load_unlocked File "", line 688, in _load_unlocked File "", line 883, in exec_module File "", line 241, in _call_with_frames_removed File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/lib/galaxy/webapps/galaxy/api/mcp.py", line 15, in from fastmcp import ( File "/usr/users/ga002/soranzon/software/nsoranzo_galaxy/.venv/lib/python3.10/site-packages/fastmcp/__init__.py", line 59, in __getattr__ raise ImportError(_install_hints.SERVER_SUPPORT) from exc ImportError: FastMCP server support is not installed. Install `fastmcp` or `fastmcp-slim[server]`. ``` --- lib/galaxy/dependencies/__init__.py | 3 --- lib/galaxy/dependencies/conditional-requirements.txt | 1 - lib/galaxy/webapps/galaxy/fast_app.py | 6 +----- packages/web_apps/pyproject.toml | 1 + pyproject.toml | 1 + 5 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/galaxy/dependencies/__init__.py b/lib/galaxy/dependencies/__init__.py index f1aff439037..99c72662cce 100644 --- a/lib/galaxy/dependencies/__init__.py +++ b/lib/galaxy/dependencies/__init__.py @@ -318,9 +318,6 @@ class ConditionalDependencies: self.config.get("ai_api_key", None) is not None or self.config.get("inference_services", None) is not None ) - def check_fastmcp(self): - return asbool(self.config.get("enable_mcp_server", False)) - def check_weasyprint(self): # See notes in ./conditional-requirements.txt for more information. return os.environ.get("GALAXY_DEPENDENCIES_INSTALL_WEASYPRINT") == "1" diff --git a/lib/galaxy/dependencies/conditional-requirements.txt b/lib/galaxy/dependencies/conditional-requirements.txt index 5ddb0f37b26..e1a5ef8577c 100644 --- a/lib/galaxy/dependencies/conditional-requirements.txt +++ b/lib/galaxy/dependencies/conditional-requirements.txt @@ -16,7 +16,6 @@ galaxycloudrunner pkce total-perspective-vortex>=3.2.1,<4 openai -fastmcp>=2.13.0 # upper version constraint because of https://github.com/galaxyproject/galaxy/issues/20600 redis>=5.3.0,<6 diff --git a/lib/galaxy/webapps/galaxy/fast_app.py b/lib/galaxy/webapps/galaxy/fast_app.py index f6440ca03af..f4e386d654a 100644 --- a/lib/galaxy/webapps/galaxy/fast_app.py +++ b/lib/galaxy/webapps/galaxy/fast_app.py @@ -36,6 +36,7 @@ from galaxy.webapps.base.webapp import ( _is_embed_request, config_allows_origin, ) +from galaxy.webapps.galaxy.api.mcp import get_mcp_app from galaxy.webapps.openapi._compat.v2 import GenerateJsonSchema from galaxy.webapps.openapi.utils import get_openapi @@ -267,13 +268,8 @@ def get_mcp_lifespan(gx_app): return None, None try: - from galaxy.webapps.galaxy.api.mcp import get_mcp_app - mcp_app = get_mcp_app(gx_app) return mcp_app, mcp_app.lifespan - except ImportError: - log.info("MCP server dependencies not installed (fastmcp), skipping") - return None, None except Exception: log.exception("Failed to initialize MCP server") return None, None diff --git a/packages/web_apps/pyproject.toml b/packages/web_apps/pyproject.toml index bafb9f424a8..da8f1c02847 100644 --- a/packages/web_apps/pyproject.toml +++ b/packages/web_apps/pyproject.toml @@ -28,6 +28,7 @@ dependencies = [ "Babel", "CT3>=3.3.3", "fastapi>=0.133.0", + "fastmcp>=2.13.0", "gunicorn!=25.1.0", "httpx", "gxformat2>=0.27.0", diff --git a/pyproject.toml b/pyproject.toml index ea38192daef..bcef73cf3be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ dependencies = [ "dparse", "edam-ontology", "fastapi>=0.133.0", # First version compatible with starlette>=1.0.0 + "fastmcp>=2.13.0", "fissix", "fs", "future>=1.0.0", # Python 3.12 support