Jeremiah Lowin commited on
Commit
38888f9
·
1 Parent(s): d4465eb

Update test_mount.py

Browse files
Files changed (1) hide show
  1. tests/server/test_mount.py +109 -0
tests/server/test_mount.py CHANGED
@@ -1,4 +1,5 @@
1
  import json
 
2
 
3
  import pytest
4
  from mcp.server.lowlevel.helper_types import ReadResourceContents
@@ -8,6 +9,7 @@ from fastmcp import FastMCP
8
  from fastmcp.client import Client
9
  from fastmcp.client.transports import FastMCPTransport
10
  from fastmcp.exceptions import NotFoundError
 
11
 
12
 
13
  class TestBasicMount:
@@ -427,3 +429,110 @@ class TestProxyServer:
427
  result = await main_app._mcp_get_prompt("proxy_welcome", {"name": "World"})
428
  assert result.messages is not None
429
  # The message should contain our welcome text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import json
2
+ from contextlib import asynccontextmanager
3
 
4
  import pytest
5
  from mcp.server.lowlevel.helper_types import ReadResourceContents
 
9
  from fastmcp.client import Client
10
  from fastmcp.client.transports import FastMCPTransport
11
  from fastmcp.exceptions import NotFoundError
12
+ from fastmcp.server.proxy import FastMCPProxy
13
 
14
 
15
  class TestBasicMount:
 
429
  result = await main_app._mcp_get_prompt("proxy_welcome", {"name": "World"})
430
  assert result.messages is not None
431
  # The message should contain our welcome text
432
+
433
+
434
+ class TestAsProxyKwarg:
435
+ """Test the as_proxy kwarg."""
436
+
437
+ async def test_as_proxy_defaults_false(self):
438
+ mcp = FastMCP("Main")
439
+ sub = FastMCP("Sub")
440
+
441
+ mcp.mount("sub", sub)
442
+
443
+ assert mcp._mounted_servers["sub"].server is sub
444
+
445
+ async def test_as_proxy_false(self):
446
+ mcp = FastMCP("Main")
447
+ sub = FastMCP("Sub")
448
+
449
+ mcp.mount("sub", sub, as_proxy=False)
450
+
451
+ assert mcp._mounted_servers["sub"].server is sub
452
+
453
+ async def test_as_proxy_true(self):
454
+ mcp = FastMCP("Main")
455
+ sub = FastMCP("Sub")
456
+
457
+ mcp.mount("sub", sub, as_proxy=True)
458
+
459
+ assert mcp._mounted_servers["sub"].server is not sub
460
+ assert isinstance(mcp._mounted_servers["sub"].server, FastMCPProxy)
461
+
462
+ async def test_as_proxy_defaults_true_if_lifespan(self):
463
+ @asynccontextmanager
464
+ async def lifespan(mcp: FastMCP):
465
+ yield
466
+
467
+ mcp = FastMCP("Main")
468
+ sub = FastMCP("Sub", lifespan=lifespan)
469
+
470
+ mcp.mount("sub", sub)
471
+
472
+ assert mcp._mounted_servers["sub"].server is not sub
473
+ assert isinstance(mcp._mounted_servers["sub"].server, FastMCPProxy)
474
+
475
+ async def test_as_proxy_ignored_for_proxy_mounts_default(self):
476
+ mcp = FastMCP("Main")
477
+ sub = FastMCP("Sub")
478
+ sub_proxy = FastMCP.from_client(Client(transport=FastMCPTransport(sub)))
479
+
480
+ mcp.mount("sub", sub_proxy)
481
+
482
+ assert mcp._mounted_servers["sub"].server is sub_proxy
483
+
484
+ async def test_as_proxy_ignored_for_proxy_mounts_false(self):
485
+ mcp = FastMCP("Main")
486
+ sub = FastMCP("Sub")
487
+ sub_proxy = FastMCP.from_client(Client(transport=FastMCPTransport(sub)))
488
+
489
+ mcp.mount("sub", sub_proxy, as_proxy=False)
490
+
491
+ assert mcp._mounted_servers["sub"].server is sub_proxy
492
+
493
+ async def test_as_proxy_ignored_for_proxy_mounts_true(self):
494
+ mcp = FastMCP("Main")
495
+ sub = FastMCP("Sub")
496
+ sub_proxy = FastMCP.from_client(Client(transport=FastMCPTransport(sub)))
497
+
498
+ mcp.mount("sub", sub_proxy, as_proxy=True)
499
+
500
+ assert mcp._mounted_servers["sub"].server is sub_proxy
501
+
502
+ async def test_as_proxy_mounts_still_have_live_link(self):
503
+ mcp = FastMCP("Main")
504
+ sub = FastMCP("Sub")
505
+
506
+ mcp.mount("sub", sub, as_proxy=True)
507
+
508
+ assert len(await mcp.get_tools()) == 0
509
+
510
+ @sub.tool()
511
+ def hello():
512
+ return "hi"
513
+
514
+ assert len(await mcp.get_tools()) == 1
515
+
516
+ async def test_sub_lifespan_is_executed(self):
517
+ lifespan_check = []
518
+
519
+ @asynccontextmanager
520
+ async def lifespan(mcp: FastMCP):
521
+ lifespan_check.append("start")
522
+ yield
523
+
524
+ mcp = FastMCP("Main")
525
+ sub = FastMCP("Sub", lifespan=lifespan)
526
+
527
+ @sub.tool()
528
+ def hello():
529
+ return "hi"
530
+
531
+ mcp.mount("sub", sub, as_proxy=True)
532
+
533
+ assert lifespan_check == []
534
+
535
+ async with Client(mcp) as client:
536
+ await client.call_tool("sub_hello", {})
537
+
538
+ assert lifespan_check == ["start"]