mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 05:54:19 +02:00
Expose local_provider property, deprecate FastMCP.remove_tool() (#3155)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
This commit is contained in:
parent
fe57c3d689
commit
a307e9c3cc
7 changed files with 170 additions and 54 deletions
|
|
@ -53,8 +53,8 @@ class TestDynamicChanges:
|
|||
tools = await main_app.list_tools()
|
||||
assert any(t.name == "sub_temp_tool" for t in tools)
|
||||
|
||||
# Remove the tool from sub_app using public API
|
||||
sub_app.remove_tool("temp_tool")
|
||||
# Remove the tool from sub_app
|
||||
sub_app.local_provider.remove_tool("temp_tool")
|
||||
|
||||
# The tool should no longer be accessible
|
||||
tools = await main_app.list_tools()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from textwrap import dedent
|
||||
|
|
@ -7,6 +8,7 @@ from unittest import mock
|
|||
from mcp.types import TextContent, TextResourceContents
|
||||
|
||||
from fastmcp import Client, FastMCP
|
||||
from fastmcp.server.providers import LocalProvider
|
||||
from fastmcp.tools import FunctionTool
|
||||
from fastmcp.tools.tool import Tool
|
||||
from fastmcp.utilities.tests import temporary_settings
|
||||
|
|
@ -116,6 +118,80 @@ class TestServerDelegation:
|
|||
assert any(t.name == "local_tool" for t in tools)
|
||||
|
||||
|
||||
class TestLocalProviderProperty:
|
||||
"""Test the public local_provider property."""
|
||||
|
||||
async def test_local_provider_returns_local_provider(self):
|
||||
mcp = FastMCP()
|
||||
assert isinstance(mcp.local_provider, LocalProvider)
|
||||
assert mcp.local_provider is mcp._local_provider
|
||||
|
||||
async def test_remove_tool_via_local_provider(self):
|
||||
mcp = FastMCP()
|
||||
|
||||
@mcp.tool
|
||||
def my_tool() -> str:
|
||||
return "result"
|
||||
|
||||
assert await mcp.local_provider.get_tool("my_tool") is not None
|
||||
mcp.local_provider.remove_tool("my_tool")
|
||||
tools = await mcp.list_tools()
|
||||
assert not any(t.name == "my_tool" for t in tools)
|
||||
|
||||
async def test_remove_resource_via_local_provider(self):
|
||||
mcp = FastMCP()
|
||||
|
||||
@mcp.resource("resource://test")
|
||||
def my_resource() -> str:
|
||||
return "data"
|
||||
|
||||
mcp.local_provider.remove_resource("resource://test")
|
||||
resources = await mcp.list_resources()
|
||||
assert not any(r.uri == "resource://test" for r in resources)
|
||||
|
||||
async def test_remove_prompt_via_local_provider(self):
|
||||
mcp = FastMCP()
|
||||
|
||||
@mcp.prompt
|
||||
def my_prompt() -> str:
|
||||
return "hello"
|
||||
|
||||
mcp.local_provider.remove_prompt("my_prompt")
|
||||
prompts = await mcp.list_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:
|
||||
"""Test resource prefixing in mounted servers."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue