From 84eb35bcb4fb359dff5b023a113d46519032b230 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Sun, 18 Jan 2026 15:08:39 -0500 Subject: [PATCH] Simplify disable calls to use keys only; fix filtering docs --- docs/servers/enabled.mdx | 11 ++++---- .../server/providers/local_provider.py | 25 +++---------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/docs/servers/enabled.mdx b/docs/servers/enabled.mdx index fe4836a26..af47f30dd 100644 --- a/docs/servers/enabled.mdx +++ b/docs/servers/enabled.mdx @@ -305,14 +305,13 @@ mcp.disable(tags={"maintenance"}) Understanding the filtering logic helps when debugging enabled state issues. -The `is_enabled()` function checks components in this order: +The `is_enabled()` function checks a component's internal metadata: -1. **Blocklist by key**: If the component's key is in `_disabled_keys`, it's disabled -2. **Blocklist by tag**: If any of the component's tags are in `_disabled_tags`, it's disabled -3. **Allowlist check**: If default enabled is off (allowlist mode) and the component isn't in the allowlist, it's disabled -4. **Default**: Otherwise, the component is enabled +1. If the component has `meta.fastmcp._internal.enabled = False`, it's disabled +2. If the component has `meta.fastmcp._internal.enabled = True`, it's enabled +3. If no enabled state is set, the component is enabled by default -The blocklist always wins over the allowlist. A component that matches both is disabled. +When multiple `enable()` and `disable()` calls are made, transforms are applied in order. **Later transforms override earlier ones**, so the last matching transform wins. ## The Enabled Transform diff --git a/src/fastmcp/server/providers/local_provider.py b/src/fastmcp/server/providers/local_provider.py index abdcdbd65..1bc507ce3 100644 --- a/src/fastmcp/server/providers/local_provider.py +++ b/src/fastmcp/server/providers/local_provider.py @@ -283,7 +283,7 @@ class LocalProvider(Provider): tool = Tool.from_function(tool) self._add_component(tool) if not enabled: - self.disable(keys={tool.key}, components=["tool"], version=tool.version) + self.disable(keys={tool.key}) return tool def remove_tool(self, name: str, version: str | None = None) -> None: @@ -374,18 +374,7 @@ class LocalProvider(Provider): ) self._add_component(resource) if not enabled: - if isinstance(resource, ResourceTemplate): - self.disable( - keys={resource.key}, - components=["template"], - version=resource.version, - ) - else: - self.disable( - keys={resource.key}, - components=["resource"], - version=resource.version, - ) + self.disable(keys={resource.key}) return resource def remove_resource(self, uri: str, version: str | None = None) -> None: @@ -483,9 +472,7 @@ class LocalProvider(Provider): ) self._add_component(prompt) if not enabled: - self.disable( - keys={prompt.key}, components=["prompt"], version=prompt.version - ) + self.disable(keys={prompt.key}) return prompt def remove_prompt(self, name: str, version: str | None = None) -> None: @@ -809,11 +796,7 @@ class LocalProvider(Provider): ) self._add_component(tool_obj) if not enabled: - self.disable( - keys={tool_obj.key}, - components=["tool"], - version=tool_obj.version, - ) + self.disable(keys={tool_obj.key}) return tool_obj else: from fastmcp.tools.function_tool import ToolMeta