mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 14:04:18 +02:00
Incorporate enabled property
This commit is contained in:
parent
ad45f0572a
commit
7224295f93
2 changed files with 32 additions and 32 deletions
|
|
@ -555,7 +555,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
# Get tool, checking first from our tools, then from the mounted servers
|
||||
if self._tool_manager.has_tool(key):
|
||||
tool = self._tool_manager.get_tool(key)
|
||||
if not tool.enabled:
|
||||
if not self._should_enable_component(tool):
|
||||
raise DisabledError(f"Tool {key!r} is disabled")
|
||||
return await self._tool_manager.call_tool(key, arguments)
|
||||
|
||||
|
|
@ -592,7 +592,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
"""
|
||||
if self._resource_manager.has_resource(uri):
|
||||
resource = await self._resource_manager.get_resource(uri)
|
||||
if not resource.enabled:
|
||||
if not self._should_enable_component(resource):
|
||||
raise DisabledError(f"Resource {str(uri)!r} is disabled")
|
||||
content = await self._resource_manager.read_resource(uri)
|
||||
return [
|
||||
|
|
@ -646,7 +646,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
# Get prompt, checking first from our prompts, then from the mounted servers
|
||||
if self._prompt_manager.has_prompt(name):
|
||||
prompt = self._prompt_manager.get_prompt(name)
|
||||
if not prompt.enabled:
|
||||
if not self._should_enable_component(prompt):
|
||||
raise DisabledError(f"Prompt {name!r} is disabled")
|
||||
return await self._prompt_manager.render_prompt(name, arguments)
|
||||
|
||||
|
|
|
|||
|
|
@ -1242,7 +1242,7 @@ class TestShouldIncludeComponent:
|
|||
"""Test that when no include or exclude filters are provided, always returns True."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool])
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is True
|
||||
|
||||
def test_exclude_string_tag_present_returns_false(self):
|
||||
|
|
@ -1251,28 +1251,28 @@ class TestShouldIncludeComponent:
|
|||
name="test_tool", tags={"tag1", "tag2", "exclude_me"}, parameters={}
|
||||
)
|
||||
mcp = FastMCP(tools=[tool], exclude_tags={"exclude_me"})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_exclude_string_tag_absent_returns_true(self):
|
||||
"""Test that when an exclude string tag is not present in tags, returns True."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], exclude_tags={"exclude_me"})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is True
|
||||
|
||||
def test_exclude_tuple_all_present_returns_false(self):
|
||||
"""Test that when all tags in exclude tuple are present, returns False."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag2", "tag3"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], exclude_tags={("tag1", "tag2")})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_exclude_tuple_partial_present_returns_true(self):
|
||||
"""Test that when only some tags in exclude tuple are present, returns True."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag3"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], exclude_tags={("tag1", "tag2")})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is True
|
||||
|
||||
def test_multiple_exclude_tags_any_match_returns_false(self):
|
||||
|
|
@ -1281,7 +1281,7 @@ class TestShouldIncludeComponent:
|
|||
mcp = FastMCP(
|
||||
tools=[tool], exclude_tags={"not_present", "tag2", "also_not_present"}
|
||||
)
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_include_string_tag_present_returns_true(self):
|
||||
|
|
@ -1290,28 +1290,28 @@ class TestShouldIncludeComponent:
|
|||
name="test_tool", tags={"tag1", "include_me", "tag2"}, parameters={}
|
||||
)
|
||||
mcp = FastMCP(tools=[tool], include_tags={"include_me"})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is True
|
||||
|
||||
def test_include_string_tag_absent_returns_false(self):
|
||||
"""Test that when an include string tag is not present in tags, returns False."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], include_tags={"include_me"})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_include_tuple_all_present_returns_true(self):
|
||||
"""Test that when all tags in include tuple are present, returns True."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag2", "tag3"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], include_tags={("tag1", "tag2")})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is True
|
||||
|
||||
def test_include_tuple_partial_present_returns_false(self):
|
||||
"""Test that when only some tags in include tuple are present, returns False."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag3"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], include_tags={("tag1", "tag2")})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_multiple_include_tags_any_match_returns_true(self):
|
||||
|
|
@ -1320,14 +1320,14 @@ class TestShouldIncludeComponent:
|
|||
mcp = FastMCP(
|
||||
tools=[tool], include_tags={"not_present", "tag2", "also_not_present"}
|
||||
)
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is True
|
||||
|
||||
def test_multiple_include_tags_none_match_returns_false(self):
|
||||
"""Test that when no include tags match, returns False."""
|
||||
tool = Tool(name="test_tool", tags={"tag1", "tag2", "tag3"}, parameters={})
|
||||
mcp = FastMCP(tools=[tool], include_tags={"not_present", "also_not_present"})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_exclude_takes_precedence_over_include(self):
|
||||
|
|
@ -1336,7 +1336,7 @@ class TestShouldIncludeComponent:
|
|||
name="test_tool", tags={"tag1", "tag2", "exclude_me"}, parameters={}
|
||||
)
|
||||
mcp = FastMCP(tools=[tool], include_tags={"tag1"}, exclude_tags={"exclude_me"})
|
||||
result = mcp.should_include_component(tool)
|
||||
result = mcp._should_enable_component(tool)
|
||||
assert result is False
|
||||
|
||||
def test_mixed_string_and_tuple_exclude_tags(self):
|
||||
|
|
@ -1346,13 +1346,13 @@ class TestShouldIncludeComponent:
|
|||
name="test_tool", tags={"tag1", "tag2", "tag3", "tag4"}, parameters={}
|
||||
)
|
||||
mcp1 = FastMCP(tools=[tool1], exclude_tags={"tag1", ("tag2", "tag3")})
|
||||
result = mcp1.should_include_component(tool1)
|
||||
result = mcp1._should_enable_component(tool1)
|
||||
assert result is False
|
||||
|
||||
# Remove tag1, should still be excluded because both tag2 and tag3 are present
|
||||
tool2 = Tool(name="test_tool", tags={"tag2", "tag3", "tag4"}, parameters={})
|
||||
mcp2 = FastMCP(tools=[tool2], exclude_tags={"tag1", ("tag2", "tag3")})
|
||||
result = mcp2.should_include_component(tool2)
|
||||
result = mcp2._should_enable_component(tool2)
|
||||
assert result is False
|
||||
|
||||
# Remove tag2, should not be excluded
|
||||
|
|
@ -1360,7 +1360,7 @@ class TestShouldIncludeComponent:
|
|||
name="test_tool", tags={"tag1_removed", "tag3", "tag4"}, parameters={}
|
||||
)
|
||||
mcp3 = FastMCP(tools=[tool3], exclude_tags={("tag2", "tag3")})
|
||||
result = mcp3.should_include_component(tool3)
|
||||
result = mcp3._should_enable_component(tool3)
|
||||
assert result is True
|
||||
|
||||
def test_mixed_string_and_tuple_include_tags(self):
|
||||
|
|
@ -1368,7 +1368,7 @@ class TestShouldIncludeComponent:
|
|||
# Should be included because both tag1 and tag2 are present (tuple match)
|
||||
tool1 = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp1 = FastMCP(tools=[tool1], include_tags={"not_present", ("tag1", "tag2")})
|
||||
result = mcp1.should_include_component(tool1)
|
||||
result = mcp1._should_enable_component(tool1)
|
||||
assert result is True
|
||||
|
||||
# Should be included because tag1 is present (string match)
|
||||
|
|
@ -1376,7 +1376,7 @@ class TestShouldIncludeComponent:
|
|||
mcp2 = FastMCP(
|
||||
tools=[tool2], include_tags={"tag1", ("not_present1", "not_present2")}
|
||||
)
|
||||
result = mcp2.should_include_component(tool2)
|
||||
result = mcp2._should_enable_component(tool2)
|
||||
assert result is True
|
||||
|
||||
# Should not be included because no conditions are met
|
||||
|
|
@ -1385,7 +1385,7 @@ class TestShouldIncludeComponent:
|
|||
tools=[tool3],
|
||||
include_tags={"not_present", ("not_present1", "not_present2")},
|
||||
)
|
||||
result = mcp3.should_include_component(tool3)
|
||||
result = mcp3._should_enable_component(tool3)
|
||||
assert result is False
|
||||
|
||||
def test_complex_scenario_with_both_filters(self):
|
||||
|
|
@ -1399,7 +1399,7 @@ class TestShouldIncludeComponent:
|
|||
include_tags={"api", ("read", "admin")},
|
||||
exclude_tags={"sensitive"},
|
||||
)
|
||||
result = mcp1.should_include_component(tool1)
|
||||
result = mcp1._should_enable_component(tool1)
|
||||
assert result is False
|
||||
|
||||
# Remove sensitive tag, should now be included
|
||||
|
|
@ -1409,7 +1409,7 @@ class TestShouldIncludeComponent:
|
|||
include_tags={"api", ("read", "admin")},
|
||||
exclude_tags={"sensitive"},
|
||||
)
|
||||
result = mcp2.should_include_component(tool2)
|
||||
result = mcp2._should_enable_component(tool2)
|
||||
assert result is True
|
||||
|
||||
def test_empty_include_exclude_sets(self):
|
||||
|
|
@ -1417,13 +1417,13 @@ class TestShouldIncludeComponent:
|
|||
# Empty include set means nothing matches
|
||||
tool1 = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp1 = FastMCP(tools=[tool1], include_tags=set())
|
||||
result = mcp1.should_include_component(tool1)
|
||||
result = mcp1._should_enable_component(tool1)
|
||||
assert result is False
|
||||
|
||||
# Empty exclude set means nothing excluded
|
||||
tool2 = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp2 = FastMCP(tools=[tool2], exclude_tags=set())
|
||||
result = mcp2.should_include_component(tool2)
|
||||
result = mcp2._should_enable_component(tool2)
|
||||
assert result is True
|
||||
|
||||
def test_empty_tags_with_filters(self):
|
||||
|
|
@ -1431,24 +1431,24 @@ class TestShouldIncludeComponent:
|
|||
# With include filters, empty tags should not match
|
||||
tool1 = Tool(name="test_tool", tags=set(), parameters={})
|
||||
mcp1 = FastMCP(tools=[tool1], include_tags={"required_tag"})
|
||||
result = mcp1.should_include_component(tool1)
|
||||
result = mcp1._should_enable_component(tool1)
|
||||
assert result is False
|
||||
|
||||
# With exclude filters but no include, empty tags should pass
|
||||
tool2 = Tool(name="test_tool", tags=set(), parameters={})
|
||||
mcp2 = FastMCP(tools=[tool2], exclude_tags={"bad_tag"})
|
||||
result = mcp2.should_include_component(tool2)
|
||||
result = mcp2._should_enable_component(tool2)
|
||||
assert result is True
|
||||
|
||||
# Tuple filters with empty tags
|
||||
tool3 = Tool(name="test_tool", tags=set(), parameters={})
|
||||
mcp3 = FastMCP(tools=[tool3], include_tags={("tag1", "tag2")})
|
||||
result = mcp3.should_include_component(tool3)
|
||||
result = mcp3._should_enable_component(tool3)
|
||||
assert result is False
|
||||
|
||||
tool4 = Tool(name="test_tool", tags=set(), parameters={})
|
||||
mcp4 = FastMCP(tools=[tool4], exclude_tags={("tag1", "tag2")})
|
||||
result = mcp4.should_include_component(tool4)
|
||||
result = mcp4._should_enable_component(tool4)
|
||||
assert result is True
|
||||
|
||||
def test_single_element_tuples(self):
|
||||
|
|
@ -1456,10 +1456,10 @@ class TestShouldIncludeComponent:
|
|||
# Single-element tuple should behave like a string
|
||||
tool1 = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp1 = FastMCP(tools=[tool1], include_tags={("tag1",)})
|
||||
result = mcp1.should_include_component(tool1)
|
||||
result = mcp1._should_enable_component(tool1)
|
||||
assert result is True
|
||||
|
||||
tool2 = Tool(name="test_tool", tags={"tag1", "tag2"}, parameters={})
|
||||
mcp2 = FastMCP(tools=[tool2], exclude_tags={("tag1",)})
|
||||
result = mcp2.should_include_component(tool2)
|
||||
result = mcp2._should_enable_component(tool2)
|
||||
assert result is False
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue