mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 07:09:11 +02:00
Repoint tests and examples off removed deprecations
Replaces FastMCP.as_proxy() helper calls with create_proxy(), rewrites the mount() as_proxy=/prefix= kwarg tests to plain mount() (the params are gone), and deletes deprecation-only tests for as_proxy() and remove_tool().
This commit is contained in:
parent
e5d9d1f17d
commit
6a6fdcb2bb
11 changed files with 39 additions and 176 deletions
|
|
@ -3,7 +3,7 @@ This example demonstrates how to set up and use an in-memory FastMCP proxy.
|
||||||
|
|
||||||
It illustrates the pattern:
|
It illustrates the pattern:
|
||||||
1. Create an original FastMCP server with some tools.
|
1. Create an original FastMCP server with some tools.
|
||||||
2. Create a proxy FastMCP server using ``FastMCP.as_proxy(original_server)``.
|
2. Create a proxy FastMCP server using ``create_proxy(original_server)``.
|
||||||
3. Use another Client to connect to the proxy server (in-memory) and interact with the original server's tools through the proxy.
|
3. Use another Client to connect to the proxy server (in-memory) and interact with the original server's tools through the proxy.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -13,6 +13,7 @@ from mcp.types import TextContent
|
||||||
|
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
from fastmcp.client import Client
|
from fastmcp.client import Client
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
|
|
||||||
|
|
||||||
class EchoService:
|
class EchoService:
|
||||||
|
|
@ -38,9 +39,9 @@ async def main():
|
||||||
# 2. Proxy Server Creation
|
# 2. Proxy Server Creation
|
||||||
print("\nStep 2: Creating the Proxy Server (InMemoryProxy)...")
|
print("\nStep 2: Creating the Proxy Server (InMemoryProxy)...")
|
||||||
print(
|
print(
|
||||||
f" (Using FastMCP.as_proxy to wrap '{original_server.name}' directly)"
|
f" (Using create_proxy to wrap '{original_server.name}' directly)"
|
||||||
)
|
)
|
||||||
proxy_server = FastMCP.as_proxy(original_server, name="InMemoryProxy")
|
proxy_server = create_proxy(original_server, name="InMemoryProxy")
|
||||||
print(
|
print(
|
||||||
f" -> Proxy Server '{proxy_server.name}' created, proxying '{original_server.name}'."
|
f" -> Proxy Server '{proxy_server.name}' created, proxying '{original_server.name}'."
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,9 @@ def check_app_status() -> dict[str, str]:
|
||||||
|
|
||||||
|
|
||||||
# Mount sub-applications
|
# Mount sub-applications
|
||||||
app.mount(server=weather_app, prefix="weather")
|
app.mount(server=weather_app, namespace="weather")
|
||||||
|
|
||||||
app.mount(server=news_app, prefix="news")
|
app.mount(server=news_app, namespace="news")
|
||||||
|
|
||||||
|
|
||||||
async def get_server_details():
|
async def get_server_details():
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ from mcp_types import TextResourceContents
|
||||||
|
|
||||||
from fastmcp import Client, FastMCP
|
from fastmcp import Client, FastMCP
|
||||||
from fastmcp.client.transports import SSETransport, StreamableHttpTransport
|
from fastmcp.client.transports import SSETransport, StreamableHttpTransport
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
from fastmcp.server.providers.openapi import MCPType, RouteMap
|
from fastmcp.server.providers.openapi import MCPType, RouteMap
|
||||||
from fastmcp.utilities.tests import run_server_async
|
from fastmcp.utilities.tests import run_server_async
|
||||||
|
|
||||||
|
|
@ -63,7 +64,7 @@ async def sse_server():
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def proxy_server(shttp_server: str):
|
async def proxy_server(shttp_server: str):
|
||||||
"""Start a proxy server."""
|
"""Start a proxy server."""
|
||||||
proxy = FastMCP.as_proxy(StreamableHttpTransport(shttp_server))
|
proxy = create_proxy(StreamableHttpTransport(shttp_server))
|
||||||
async with run_server_async(proxy, transport="http") as url:
|
async with run_server_async(proxy, transport="http") as url:
|
||||||
yield url
|
yield url
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,12 @@ class TestParallelCalls:
|
||||||
return script_file
|
return script_file
|
||||||
|
|
||||||
async def test_parallel_calls(self, stdio_script):
|
async def test_parallel_calls(self, stdio_script):
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
|
|
||||||
backend_transport = PythonStdioTransport(script_path=stdio_script)
|
backend_transport = PythonStdioTransport(script_path=stdio_script)
|
||||||
backend_client = Client(transport=backend_transport)
|
backend_client = Client(transport=backend_transport)
|
||||||
|
|
||||||
proxy = FastMCP.as_proxy(backend=backend_client, name="PROXY")
|
proxy = create_proxy(backend_client, name="PROXY")
|
||||||
|
|
||||||
count = 10
|
count = 10
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from mcp.server.context import ServerRequestContext
|
||||||
|
|
||||||
from fastmcp import Client, FastMCP
|
from fastmcp import Client, FastMCP
|
||||||
from fastmcp.exceptions import ToolError
|
from fastmcp.exceptions import ToolError
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
from fastmcp.server.context import Context
|
from fastmcp.server.context import Context
|
||||||
from fastmcp.server.middleware import CallNext, Middleware, MiddlewareContext
|
from fastmcp.server.middleware import CallNext, Middleware, MiddlewareContext
|
||||||
from fastmcp.tools.base import ToolResult
|
from fastmcp.tools.base import ToolResult
|
||||||
|
|
@ -475,7 +476,7 @@ class TestProxyServer:
|
||||||
):
|
):
|
||||||
# proxy server will have its tools listed as well as called in order to
|
# proxy server will have its tools listed as well as called in order to
|
||||||
# apply transforms and filters prior to the call.
|
# apply transforms and filters prior to the call.
|
||||||
proxy_server = FastMCP.as_proxy(mcp_server, name="Proxy Server")
|
proxy_server = create_proxy(mcp_server, name="Proxy Server")
|
||||||
async with Client(proxy_server) as client:
|
async with Client(proxy_server) as client:
|
||||||
await client.call_tool("add", {"a": 1, "b": 2})
|
await client.call_tool("add", {"a": 1, "b": 2})
|
||||||
|
|
||||||
|
|
@ -492,7 +493,7 @@ class TestProxyServer:
|
||||||
):
|
):
|
||||||
"""Tests that tags on remote FastMCP servers are visible to middleware
|
"""Tests that tags on remote FastMCP servers are visible to middleware
|
||||||
via proxy. See https://github.com/PrefectHQ/fastmcp/issues/1300"""
|
via proxy. See https://github.com/PrefectHQ/fastmcp/issues/1300"""
|
||||||
proxy_server = FastMCP.as_proxy(mcp_server, name="Proxy Server")
|
proxy_server = create_proxy(mcp_server, name="Proxy Server")
|
||||||
|
|
||||||
TAGS = []
|
TAGS = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from mcp_types import TextContent
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
from fastmcp.client import Client
|
from fastmcp.client import Client
|
||||||
from fastmcp.client.transports import SSETransport
|
from fastmcp.client.transports import SSETransport
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
from fastmcp.tools.base import Tool
|
from fastmcp.tools.base import Tool
|
||||||
from fastmcp.tools.tool_transform import TransformedTool
|
from fastmcp.tools.tool_transform import TransformedTool
|
||||||
|
|
||||||
|
|
@ -272,7 +273,7 @@ class TestMultipleServerMount:
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a proxy server that will fail to connect
|
# Create a proxy server that will fail to connect
|
||||||
unreachable_proxy = FastMCP.as_proxy(
|
unreachable_proxy = create_proxy(
|
||||||
unreachable_client, name="unreachable_proxy"
|
unreachable_client, name="unreachable_proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ from contextlib import asynccontextmanager
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
from fastmcp.client import Client
|
from fastmcp.client import Client
|
||||||
from fastmcp.client.transports import FastMCPTransport
|
from fastmcp.client.transports import FastMCPTransport
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
from fastmcp.server.providers import FastMCPProvider
|
from fastmcp.server.providers import FastMCPProvider
|
||||||
from fastmcp.server.providers.proxy import FastMCPProxy
|
|
||||||
from fastmcp.server.providers.wrapped_provider import _WrappedProvider
|
from fastmcp.server.providers.wrapped_provider import _WrappedProvider
|
||||||
from fastmcp.server.transforms import Namespace
|
from fastmcp.server.transforms import Namespace
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ class TestProxyServer:
|
||||||
return f"Data for {query}"
|
return f"Data for {query}"
|
||||||
|
|
||||||
# Create proxy server
|
# Create proxy server
|
||||||
proxy_server = FastMCP.as_proxy(FastMCPTransport(original_server))
|
proxy_server = create_proxy(FastMCPTransport(original_server))
|
||||||
|
|
||||||
# Mount proxy server
|
# Mount proxy server
|
||||||
main_app = FastMCP("MainApp")
|
main_app = FastMCP("MainApp")
|
||||||
|
|
@ -45,7 +45,7 @@ class TestProxyServer:
|
||||||
original_server = FastMCP("OriginalServer")
|
original_server = FastMCP("OriginalServer")
|
||||||
|
|
||||||
# Create proxy server
|
# Create proxy server
|
||||||
proxy_server = FastMCP.as_proxy(FastMCPTransport(original_server))
|
proxy_server = create_proxy(FastMCPTransport(original_server))
|
||||||
|
|
||||||
# Mount proxy server
|
# Mount proxy server
|
||||||
main_app = FastMCP("MainApp")
|
main_app = FastMCP("MainApp")
|
||||||
|
|
@ -74,7 +74,7 @@ class TestProxyServer:
|
||||||
return json.dumps({"api_key": "12345"})
|
return json.dumps({"api_key": "12345"})
|
||||||
|
|
||||||
# Create proxy server
|
# Create proxy server
|
||||||
proxy_server = FastMCP.as_proxy(FastMCPTransport(original_server))
|
proxy_server = create_proxy(FastMCPTransport(original_server))
|
||||||
|
|
||||||
# Mount proxy server
|
# Mount proxy server
|
||||||
main_app = FastMCP("MainApp")
|
main_app = FastMCP("MainApp")
|
||||||
|
|
@ -96,7 +96,7 @@ class TestProxyServer:
|
||||||
return f"Welcome, {name}!"
|
return f"Welcome, {name}!"
|
||||||
|
|
||||||
# Create proxy server
|
# Create proxy server
|
||||||
proxy_server = FastMCP.as_proxy(FastMCPTransport(original_server))
|
proxy_server = create_proxy(FastMCPTransport(original_server))
|
||||||
|
|
||||||
# Mount proxy server
|
# Mount proxy server
|
||||||
main_app = FastMCP("MainApp")
|
main_app = FastMCP("MainApp")
|
||||||
|
|
@ -108,10 +108,10 @@ class TestProxyServer:
|
||||||
# The message should contain our welcome text
|
# The message should contain our welcome text
|
||||||
|
|
||||||
|
|
||||||
class TestAsProxyKwarg:
|
class TestMountProviderStructure:
|
||||||
"""Test the as_proxy kwarg."""
|
"""Test the provider structure produced by mounting."""
|
||||||
|
|
||||||
async def test_as_proxy_defaults_false(self):
|
async def test_mount_wraps_in_fastmcp_provider(self):
|
||||||
mcp = FastMCP("Main")
|
mcp = FastMCP("Main")
|
||||||
sub = FastMCP("Sub")
|
sub = FastMCP("Sub")
|
||||||
|
|
||||||
|
|
@ -133,53 +133,6 @@ class TestAsProxyKwarg:
|
||||||
tools = await mcp.list_tools()
|
tools = await mcp.list_tools()
|
||||||
assert {t.name for t in tools} == {"sub_sub_tool"}
|
assert {t.name for t in tools} == {"sub_sub_tool"}
|
||||||
|
|
||||||
async def test_as_proxy_false(self):
|
|
||||||
mcp = FastMCP("Main")
|
|
||||||
sub = FastMCP("Sub")
|
|
||||||
|
|
||||||
@sub.tool
|
|
||||||
def sub_tool() -> str:
|
|
||||||
return "test"
|
|
||||||
|
|
||||||
mcp.mount(sub, "sub", as_proxy=False)
|
|
||||||
|
|
||||||
# Index 1 because LocalProvider is at index 0
|
|
||||||
provider = mcp.providers[1]
|
|
||||||
# Provider is wrapped with Namespace transform
|
|
||||||
assert isinstance(provider, _WrappedProvider)
|
|
||||||
assert len(provider._transforms) == 1
|
|
||||||
assert isinstance(provider._transforms[0], Namespace)
|
|
||||||
# Inner provider is FastMCPProvider
|
|
||||||
assert isinstance(provider._inner, FastMCPProvider)
|
|
||||||
assert provider._inner.server is sub
|
|
||||||
# Verify namespace is applied
|
|
||||||
tools = await mcp.list_tools()
|
|
||||||
assert {t.name for t in tools} == {"sub_sub_tool"}
|
|
||||||
|
|
||||||
async def test_as_proxy_true(self):
|
|
||||||
mcp = FastMCP("Main")
|
|
||||||
sub = FastMCP("Sub")
|
|
||||||
|
|
||||||
@sub.tool
|
|
||||||
def sub_tool() -> str:
|
|
||||||
return "test"
|
|
||||||
|
|
||||||
mcp.mount(sub, "sub", as_proxy=True)
|
|
||||||
|
|
||||||
# Index 1 because LocalProvider is at index 0
|
|
||||||
provider = mcp.providers[1]
|
|
||||||
# Provider is wrapped with Namespace transform
|
|
||||||
assert isinstance(provider, _WrappedProvider)
|
|
||||||
assert len(provider._transforms) == 1
|
|
||||||
assert isinstance(provider._transforms[0], Namespace)
|
|
||||||
# Inner provider is FastMCPProvider wrapping a proxy
|
|
||||||
assert isinstance(provider._inner, FastMCPProvider)
|
|
||||||
assert provider._inner.server is not sub
|
|
||||||
assert isinstance(provider._inner.server, FastMCPProxy)
|
|
||||||
# Verify namespace is applied
|
|
||||||
tools = await mcp.list_tools()
|
|
||||||
assert {t.name for t in tools} == {"sub_sub_tool"}
|
|
||||||
|
|
||||||
async def test_lifespan_server_mounted_directly(self):
|
async def test_lifespan_server_mounted_directly(self):
|
||||||
"""Test that servers with lifespan are mounted directly (not auto-proxied).
|
"""Test that servers with lifespan are mounted directly (not auto-proxied).
|
||||||
|
|
||||||
|
|
@ -214,10 +167,10 @@ class TestAsProxyKwarg:
|
||||||
tools = await mcp.list_tools()
|
tools = await mcp.list_tools()
|
||||||
assert {t.name for t in tools} == {"sub_sub_tool"}
|
assert {t.name for t in tools} == {"sub_sub_tool"}
|
||||||
|
|
||||||
async def test_as_proxy_ignored_for_proxy_mounts_default(self):
|
async def test_mounting_a_proxy_preserves_the_proxy(self):
|
||||||
mcp = FastMCP("Main")
|
mcp = FastMCP("Main")
|
||||||
sub = FastMCP("Sub")
|
sub = FastMCP("Sub")
|
||||||
sub_proxy = FastMCP.as_proxy(FastMCPTransport(sub))
|
sub_proxy = create_proxy(FastMCPTransport(sub))
|
||||||
|
|
||||||
mcp.mount(sub_proxy, "sub")
|
mcp.mount(sub_proxy, "sub")
|
||||||
|
|
||||||
|
|
@ -231,45 +184,11 @@ class TestAsProxyKwarg:
|
||||||
assert isinstance(provider._inner, FastMCPProvider)
|
assert isinstance(provider._inner, FastMCPProvider)
|
||||||
assert provider._inner.server is sub_proxy
|
assert provider._inner.server is sub_proxy
|
||||||
|
|
||||||
async def test_as_proxy_ignored_for_proxy_mounts_false(self):
|
async def test_mounts_have_live_link(self):
|
||||||
mcp = FastMCP("Main")
|
|
||||||
sub = FastMCP("Sub")
|
|
||||||
sub_proxy = FastMCP.as_proxy(FastMCPTransport(sub))
|
|
||||||
|
|
||||||
mcp.mount(sub_proxy, "sub", as_proxy=False)
|
|
||||||
|
|
||||||
# Index 1 because LocalProvider is at index 0
|
|
||||||
provider = mcp.providers[1]
|
|
||||||
# Provider is wrapped with Namespace transform
|
|
||||||
assert isinstance(provider, _WrappedProvider)
|
|
||||||
assert len(provider._transforms) == 1
|
|
||||||
assert isinstance(provider._transforms[0], Namespace)
|
|
||||||
# Inner provider is FastMCPProvider
|
|
||||||
assert isinstance(provider._inner, FastMCPProvider)
|
|
||||||
assert provider._inner.server is sub_proxy
|
|
||||||
|
|
||||||
async def test_as_proxy_ignored_for_proxy_mounts_true(self):
|
|
||||||
mcp = FastMCP("Main")
|
|
||||||
sub = FastMCP("Sub")
|
|
||||||
sub_proxy = FastMCP.as_proxy(FastMCPTransport(sub))
|
|
||||||
|
|
||||||
mcp.mount(sub_proxy, "sub", as_proxy=True)
|
|
||||||
|
|
||||||
# Index 1 because LocalProvider is at index 0
|
|
||||||
provider = mcp.providers[1]
|
|
||||||
# Provider is wrapped with Namespace transform
|
|
||||||
assert isinstance(provider, _WrappedProvider)
|
|
||||||
assert len(provider._transforms) == 1
|
|
||||||
assert isinstance(provider._transforms[0], Namespace)
|
|
||||||
# Inner provider is FastMCPProvider
|
|
||||||
assert isinstance(provider._inner, FastMCPProvider)
|
|
||||||
assert provider._inner.server is sub_proxy
|
|
||||||
|
|
||||||
async def test_as_proxy_mounts_still_have_live_link(self):
|
|
||||||
mcp = FastMCP("Main")
|
mcp = FastMCP("Main")
|
||||||
sub = FastMCP("Sub")
|
sub = FastMCP("Sub")
|
||||||
|
|
||||||
mcp.mount(sub, "sub", as_proxy=True)
|
mcp.mount(sub, "sub")
|
||||||
|
|
||||||
assert len(await mcp.list_tools()) == 0
|
assert len(await mcp.list_tools()) == 0
|
||||||
|
|
||||||
|
|
@ -294,7 +213,7 @@ class TestAsProxyKwarg:
|
||||||
def hello():
|
def hello():
|
||||||
return "hi"
|
return "hi"
|
||||||
|
|
||||||
mcp.mount(sub, as_proxy=True)
|
mcp.mount(sub)
|
||||||
|
|
||||||
assert lifespan_check == []
|
assert lifespan_check == []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ from mcp_types import (
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from fastmcp import Client, Context, FastMCP
|
from fastmcp import Client, Context, FastMCP
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
from fastmcp.client.elicitation import ElicitRequestParams, ElicitResult
|
from fastmcp.client.elicitation import ElicitRequestParams, ElicitResult
|
||||||
from fastmcp.client.logging import LogMessage
|
from fastmcp.client.logging import LogMessage
|
||||||
from fastmcp.client.sampling import RequestContext, SamplingMessage, SamplingParams
|
from fastmcp.client.sampling import RequestContext, SamplingMessage, SamplingParams
|
||||||
|
|
@ -88,7 +89,7 @@ async def proxy_server(fastmcp_server: FastMCP):
|
||||||
"""
|
"""
|
||||||
A proxy server that forwards interactions with the proxy client to the given fastmcp server.
|
A proxy server that forwards interactions with the proxy client to the given fastmcp server.
|
||||||
"""
|
"""
|
||||||
return FastMCP.as_proxy(ProxyClient(fastmcp_server))
|
return create_proxy(ProxyClient(fastmcp_server))
|
||||||
|
|
||||||
|
|
||||||
class TestProxyClient:
|
class TestProxyClient:
|
||||||
|
|
@ -377,7 +378,7 @@ class TestProxyClient:
|
||||||
else:
|
else:
|
||||||
return f"Elicitation {result.action}"
|
return f"Elicitation {result.action}"
|
||||||
|
|
||||||
proxy_server = FastMCP.as_proxy(ProxyClient(fastmcp_server))
|
proxy_server = create_proxy(ProxyClient(fastmcp_server))
|
||||||
|
|
||||||
# Test that elicitation works correctly through the proxy
|
# Test that elicitation works correctly through the proxy
|
||||||
async def elicitation_handler(
|
async def elicitation_handler(
|
||||||
|
|
@ -407,16 +408,16 @@ class TestProxyClient:
|
||||||
# Create a disconnected client (should use fresh sessions per request)
|
# Create a disconnected client (should use fresh sessions per request)
|
||||||
base_client = Client(fastmcp_server)
|
base_client = Client(fastmcp_server)
|
||||||
|
|
||||||
# Test both as_proxy convenience method and direct client_factory usage
|
# Test both create_proxy convenience function and direct client_factory usage
|
||||||
proxy_via_as_proxy = FastMCP.as_proxy(base_client)
|
proxy_via_create_proxy = create_proxy(base_client)
|
||||||
proxy_via_factory = FastMCPProxy(client_factory=base_client.new)
|
proxy_via_factory = FastMCPProxy(client_factory=base_client.new)
|
||||||
|
|
||||||
# Verify the proxies are created successfully - this tests the client factory pattern
|
# Verify the proxies are created successfully - this tests the client factory pattern
|
||||||
assert proxy_via_as_proxy is not None
|
assert proxy_via_create_proxy is not None
|
||||||
assert proxy_via_factory is not None
|
assert proxy_via_factory is not None
|
||||||
|
|
||||||
# Verify they have the expected client factory behavior
|
# Verify they have the expected client factory behavior
|
||||||
assert hasattr(proxy_via_as_proxy, "_local_provider")
|
assert hasattr(proxy_via_create_proxy, "_local_provider")
|
||||||
assert hasattr(proxy_via_factory, "_local_provider")
|
assert hasattr(proxy_via_factory, "_local_provider")
|
||||||
|
|
||||||
async def test_connected_proxy_client_uses_fresh_sessions(
|
async def test_connected_proxy_client_uses_fresh_sessions(
|
||||||
|
|
@ -464,7 +465,7 @@ def roots_backend_server():
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def roots_proxy_server(roots_backend_server: FastMCP):
|
async def roots_proxy_server(roots_backend_server: FastMCP):
|
||||||
return FastMCP.as_proxy(ProxyClient(roots_backend_server))
|
return create_proxy(ProxyClient(roots_backend_server))
|
||||||
|
|
||||||
|
|
||||||
class TestProxyServerInitiatedForwardingNonTool:
|
class TestProxyServerInitiatedForwardingNonTool:
|
||||||
|
|
|
||||||
|
|
@ -198,38 +198,6 @@ def test_create_proxy_with_url():
|
||||||
assert client.transport.url == "http://example.com/mcp/"
|
assert client.transport.url == "http://example.com/mcp/"
|
||||||
|
|
||||||
|
|
||||||
# --- Deprecated as_proxy tests (verify backwards compatibility) ---
|
|
||||||
|
|
||||||
|
|
||||||
async def test_as_proxy_deprecated_with_server(fastmcp_server):
|
|
||||||
"""FastMCP.as_proxy should work but emit deprecation warning."""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
|
||||||
warnings.simplefilter("always")
|
|
||||||
proxy = FastMCP.as_proxy(fastmcp_server)
|
|
||||||
assert len(w) == 1
|
|
||||||
assert issubclass(w[0].category, DeprecationWarning)
|
|
||||||
assert "create_proxy" in str(w[0].message)
|
|
||||||
|
|
||||||
async with Client(proxy) as client:
|
|
||||||
result = await client.call_tool("greet", {"name": "Test"})
|
|
||||||
assert result.data == "Hello, Test!"
|
|
||||||
|
|
||||||
|
|
||||||
def test_as_proxy_deprecated_with_url():
|
|
||||||
"""FastMCP.as_proxy should work but emit deprecation warning."""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
|
||||||
warnings.simplefilter("always")
|
|
||||||
proxy = FastMCP.as_proxy("http://example.com/mcp/")
|
|
||||||
assert len(w) == 1
|
|
||||||
assert issubclass(w[0].category, DeprecationWarning)
|
|
||||||
|
|
||||||
assert isinstance(proxy, FastMCPProxy)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_proxy_with_async_client_factory():
|
async def test_proxy_with_async_client_factory():
|
||||||
"""FastMCPProxy should accept an async client_factory."""
|
"""FastMCPProxy should accept an async client_factory."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import os
|
import os
|
||||||
import warnings
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
@ -161,37 +160,6 @@ class TestLocalProviderProperty:
|
||||||
assert not any(p.name == "my_prompt" for p in prompts)
|
assert not any(p.name == "my_prompt" for p in prompts)
|
||||||
|
|
||||||
|
|
||||||
class TestRemoveToolDeprecation:
|
|
||||||
async def test_remove_tool_emits_deprecation_warning(self):
|
|
||||||
mcp = FastMCP()
|
|
||||||
|
|
||||||
@mcp.tool
|
|
||||||
def my_tool() -> str:
|
|
||||||
return "result"
|
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
|
||||||
warnings.simplefilter("always")
|
|
||||||
mcp.remove_tool("my_tool")
|
|
||||||
|
|
||||||
assert len(w) == 1
|
|
||||||
assert issubclass(w[0].category, DeprecationWarning)
|
|
||||||
assert "local_provider" in str(w[0].message)
|
|
||||||
|
|
||||||
async def test_remove_tool_still_works(self):
|
|
||||||
mcp = FastMCP()
|
|
||||||
|
|
||||||
@mcp.tool
|
|
||||||
def my_tool() -> str:
|
|
||||||
return "result"
|
|
||||||
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.simplefilter("ignore", DeprecationWarning)
|
|
||||||
mcp.remove_tool("my_tool")
|
|
||||||
|
|
||||||
tools = await mcp.list_tools()
|
|
||||||
assert not any(t.name == "my_tool" for t in tools)
|
|
||||||
|
|
||||||
|
|
||||||
class TestResourcePrefixMounting:
|
class TestResourcePrefixMounting:
|
||||||
"""Test resource prefixing in mounted servers."""
|
"""Test resource prefixing in mounted servers."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -719,8 +719,9 @@ class TestProxy:
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def proxy_server(self, mcp_server: FastMCP) -> FastMCP:
|
def proxy_server(self, mcp_server: FastMCP) -> FastMCP:
|
||||||
from fastmcp.client.transports import FastMCPTransport
|
from fastmcp.client.transports import FastMCPTransport
|
||||||
|
from fastmcp.server import create_proxy
|
||||||
|
|
||||||
proxy = FastMCP.as_proxy(FastMCPTransport(mcp_server))
|
proxy = create_proxy(FastMCPTransport(mcp_server))
|
||||||
return proxy
|
return proxy
|
||||||
|
|
||||||
async def test_transform_proxy(self, proxy_server: FastMCP):
|
async def test_transform_proxy(self, proxy_server: FastMCP):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue