From 3a9c97d608f24d24211e2d66557a67670434d0f7 Mon Sep 17 00:00:00 2001 From: Max Isbey <224885523+maxisbey@users.noreply.github.com> Date: Thu, 26 Mar 2026 23:02:55 +0000 Subject: [PATCH 1/2] feat(server): restore dependencies parameter on MCPServer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restores the `dependencies` parameter that was removed in #1877. The parameter is read by the `mcp dev` and `mcp install` CLI commands to auto-populate `uv run --with ` flags. Removal without a working replacement breaks high-profile consumers (awslabs/mcp uses it in 47 servers, mindsdb, redis/mcp-redis). While PEP 723 inline script metadata is the intended replacement, the CLI doesn't currently parse it — `uv` only reads PEP 723 when the script is the direct target, not when wrapped in `mcp run `. Long-term design (deprecate vs. keep vs. config file) is tracked in the linked issue. Github-Issue:#2354 --- src/mcp/server/mcpserver/server.py | 8 +++++++- tests/server/mcpserver/test_server.py | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/mcp/server/mcpserver/server.py b/src/mcp/server/mcpserver/server.py index 2a7a58117..1c1653364 100644 --- a/src/mcp/server/mcpserver/server.py +++ b/src/mcp/server/mcpserver/server.py @@ -6,7 +6,7 @@ import inspect import json import re -from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence +from collections.abc import AsyncIterator, Awaitable, Callable, Collection, Iterable, Sequence from contextlib import AbstractAsyncContextManager, asynccontextmanager from typing import Any, Generic, Literal, TypeVar, overload @@ -105,6 +105,9 @@ class Settings(BaseSettings, Generic[LifespanResultT]): # prompt settings warn_on_duplicate_prompts: bool + dependencies: list[str] + """List of dependencies to install in the server environment. Used by the `mcp install` and `mcp dev` CLI.""" + lifespan: Callable[[MCPServer[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None """An async context manager that will be called when the server is started.""" @@ -142,6 +145,7 @@ def __init__( warn_on_duplicate_resources: bool = True, warn_on_duplicate_tools: bool = True, warn_on_duplicate_prompts: bool = True, + dependencies: Collection[str] = (), lifespan: Callable[[MCPServer[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None = None, auth: AuthSettings | None = None, ): @@ -151,9 +155,11 @@ def __init__( warn_on_duplicate_resources=warn_on_duplicate_resources, warn_on_duplicate_tools=warn_on_duplicate_tools, warn_on_duplicate_prompts=warn_on_duplicate_prompts, + dependencies=list(dependencies), lifespan=lifespan, auth=auth, ) + self.dependencies = self.settings.dependencies self._tool_manager = ToolManager(tools=tools, warn_on_duplicate_tools=self.settings.warn_on_duplicate_tools) self._resource_manager = ResourceManager(warn_on_duplicate_resources=self.settings.warn_on_duplicate_resources) diff --git a/tests/server/mcpserver/test_server.py b/tests/server/mcpserver/test_server.py index 3ef06d038..49b6deb4b 100644 --- a/tests/server/mcpserver/test_server.py +++ b/tests/server/mcpserver/test_server.py @@ -65,6 +65,15 @@ async def test_create_server(self): assert len(mcp.icons) == 1 assert mcp.icons[0].src == "https://example.com/icon.png" + def test_dependencies(self): + """Dependencies list is read by `mcp install` / `mcp dev` CLI commands.""" + mcp = MCPServer("test", dependencies=["pandas", "numpy"]) + assert mcp.dependencies == ["pandas", "numpy"] + assert mcp.settings.dependencies == ["pandas", "numpy"] + + mcp_no_deps = MCPServer("test") + assert mcp_no_deps.dependencies == [] + async def test_sse_app_returns_starlette_app(self): """Test that sse_app returns a Starlette application with correct routes.""" mcp = MCPServer("test") From ddb631f232238a6713dc86fa3605e8a656c773ad Mon Sep 17 00:00:00 2001 From: Max Isbey <224885523+maxisbey@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:23:45 +0000 Subject: [PATCH 2/2] refactor: use list[str] | None for dependencies parameter Matches the convention used by other sequence parameters in the same constructor (icons, tools) and avoids the Collection[str] footgun where a bare string like dependencies="pandas" would be iterated as chars. --- src/mcp/server/mcpserver/server.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mcp/server/mcpserver/server.py b/src/mcp/server/mcpserver/server.py index 1c1653364..6f9bb0e28 100644 --- a/src/mcp/server/mcpserver/server.py +++ b/src/mcp/server/mcpserver/server.py @@ -6,7 +6,7 @@ import inspect import json import re -from collections.abc import AsyncIterator, Awaitable, Callable, Collection, Iterable, Sequence +from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence from contextlib import AbstractAsyncContextManager, asynccontextmanager from typing import Any, Generic, Literal, TypeVar, overload @@ -145,7 +145,7 @@ def __init__( warn_on_duplicate_resources: bool = True, warn_on_duplicate_tools: bool = True, warn_on_duplicate_prompts: bool = True, - dependencies: Collection[str] = (), + dependencies: list[str] | None = None, lifespan: Callable[[MCPServer[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None = None, auth: AuthSettings | None = None, ): @@ -155,7 +155,7 @@ def __init__( warn_on_duplicate_resources=warn_on_duplicate_resources, warn_on_duplicate_tools=warn_on_duplicate_tools, warn_on_duplicate_prompts=warn_on_duplicate_prompts, - dependencies=list(dependencies), + dependencies=dependencies or [], lifespan=lifespan, auth=auth, )