diff --git a/docs/servers/proxy.mdx b/docs/servers/proxy.mdx index 7cbb6d90cc..354db48835 100644 --- a/docs/servers/proxy.mdx +++ b/docs/servers/proxy.mdx @@ -317,7 +317,6 @@ proxy = FastMCPProxy(client_factory=create_client) ### Parameters -- **`client`**: **[DEPRECATED]** A `Client` instance. Use `client_factory` instead for explicit session management. - **`client_factory`**: A callable that returns a `Client` instance when called. This gives you full control over session creation and reuse strategies. ### Explicit Session Management diff --git a/src/fastmcp/server/proxy.py b/src/fastmcp/server/proxy.py index dc87e98b7c..0632f37746 100644 --- a/src/fastmcp/server/proxy.py +++ b/src/fastmcp/server/proxy.py @@ -1,7 +1,6 @@ from __future__ import annotations import inspect -import warnings from collections.abc import Awaitable, Callable from pathlib import Path from typing import TYPE_CHECKING, Any, cast @@ -20,7 +19,6 @@ ) from pydantic.networks import AnyUrl -import fastmcp from fastmcp.client.client import Client, FastMCP1Server from fastmcp.client.elicitation import ElicitResult from fastmcp.client.logging import LogMessage @@ -461,9 +459,8 @@ class FastMCPProxy(FastMCP): def __init__( self, - client: Client | None = None, *, - client_factory: ClientFactoryT | None = None, + client_factory: ClientFactoryT, **kwargs, ): """ @@ -473,9 +470,6 @@ def __init__( Use FastMCP.as_proxy() for convenience with automatic session strategy. Args: - client: [DEPRECATED] A Client instance. Use client_factory instead for explicit - session management. When provided, a client_factory will be automatically - created that provides session isolation for backwards compatibility. client_factory: A callable that returns a Client instance when called. This gives you full control over session creation and reuse. Can be either a synchronous or asynchronous function. @@ -484,29 +478,7 @@ def __init__( super().__init__(**kwargs) - # Handle client and client_factory parameters - if client is not None and client_factory is not None: - raise ValueError("Cannot specify both 'client' and 'client_factory'") - - if client is not None: - # Deprecated in 2.10.3 - if fastmcp.settings.deprecation_warnings: - warnings.warn( - "Passing 'client' to FastMCPProxy is deprecated. Use 'client_factory' instead for explicit session management. " - "For automatic session strategy, use FastMCP.as_proxy().", - DeprecationWarning, - stacklevel=2, - ) - - # Create a factory that provides session isolation for backwards compatibility - def deprecated_client_factory(): - return client.new() - - self.client_factory = deprecated_client_factory - elif client_factory is not None: - self.client_factory = client_factory - else: - raise ValueError("Must specify 'client_factory'") + self.client_factory = client_factory # Replace the default managers with our specialized proxy managers. self._tool_manager = ProxyToolManager( diff --git a/tests/deprecated/test_proxy_client.py b/tests/deprecated/test_proxy_client.py deleted file mode 100644 index f278c812c0..0000000000 --- a/tests/deprecated/test_proxy_client.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Tests for deprecated FastMCPProxy client parameter.""" - -import warnings - -import pytest - -from fastmcp import Client, FastMCP -from fastmcp.server.proxy import FastMCPProxy, ProxyClient - - -@pytest.fixture -def simple_server(): - """Create a simple FastMCP server for testing.""" - server = FastMCP("TestServer") - - @server.tool - def simple_tool() -> str: - return "test_result" - - return server - - -class TestDeprecatedClientParameter: - """Test the deprecated client parameter in FastMCPProxy.""" - - def test_client_parameter_deprecation_warning(self, simple_server): - """Test that using the client parameter raises a deprecation warning.""" - client = Client(simple_server) - - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") # Ensure all warnings are captured - - FastMCPProxy(client=client) - - # Verify a deprecation warning was raised - assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) - assert "client' to FastMCPProxy is deprecated" in str(w[0].message) - assert "client_factory" in str(w[0].message) - - def test_client_parameter_still_works(self, simple_server): - """Test that the deprecated client parameter still functions.""" - client = ProxyClient(simple_server) - - with warnings.catch_warnings(): - warnings.simplefilter("ignore") # Suppress warnings for functionality test - - proxy = FastMCPProxy(client=client) - - # Verify the proxy was created successfully - assert proxy is not None - assert hasattr(proxy, "client_factory") - assert callable(proxy.client_factory) - - # Verify the factory returns a new client instance (session isolation for backwards compatibility) - returned_client = proxy.client_factory() - assert returned_client is not client - assert isinstance(returned_client, type(client)) - - def test_cannot_specify_both_client_and_factory(self, simple_server): - """Test that specifying both client and client_factory raises an error.""" - client = Client(simple_server) - - def factory(): - return Client(simple_server) - - with pytest.raises( - ValueError, match="Cannot specify both 'client' and 'client_factory'" - ): - FastMCPProxy(client=client, client_factory=factory) - - def test_must_specify_client_factory_when_no_client(self): - """Test that client_factory is required when client is not provided.""" - with pytest.raises(ValueError, match="Must specify 'client_factory'"): - FastMCPProxy() - - def test_client_factory_preferred_over_deprecated_client(self, simple_server): - """Test that the recommended client_factory approach works without warnings.""" - - def factory(): - return ProxyClient(simple_server) - - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - - proxy = FastMCPProxy(client_factory=factory) - - # Verify no warnings were raised - assert len(w) == 0 - - # Verify the proxy works correctly - assert proxy is not None - assert proxy.client_factory is factory - - async def test_deprecated_client_functional_test(self, simple_server): - """End-to-end test that deprecated client parameter still works functionally.""" - client = ProxyClient(simple_server) - - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - - proxy = FastMCPProxy(client=client) - - # Test that the proxy can actually handle requests - async with Client(proxy) as proxy_client: - result = await proxy_client.call_tool("simple_tool", {}) - assert result.data == "test_result"