diff --git a/docs/development/v3-notes/v3-features.mdx b/docs/development/v3-notes/v3-features.mdx
index 86a78afdd7..be92595eef 100644
--- a/docs/development/v3-notes/v3-features.mdx
+++ b/docs/development/v3-notes/v3-features.mdx
@@ -23,7 +23,7 @@ class Provider:
Providers support:
- **Lifecycle management**: `async def lifespan()` for setup/teardown
-- **Enabled control**: `enable()` / `disable()` with name, version, tags, components, and allowlist mode
+- **Visibility control**: `enable()` / `disable()` with name, version, tags, components, and allowlist mode
- **Transform stacking**: `provider.add_transform(Namespace(...))`, `provider.add_transform(ToolTransform(...))`
### LocalProvider
@@ -106,7 +106,7 @@ Transforms modify components (tools, resources, prompts) as they flow from provi
- `Namespace` - adds prefixes to names (`tool` → `api_tool`) and path segments to URIs (`data://x` → `data://api/x`)
- `ToolTransform` - modifies tool schemas (rename, description, tags, argument transforms)
-- `Enabled` - sets enabled state on components by key or tag (backs `enable()`/`disable()` API)
+- `Visibility` - sets visibility state on components by key or tag (backs `enable()`/`disable()` API)
- `VersionFilter` - filters components by version range (`version_gte`, `version_lt`)
- `ResourcesAsTools` - exposes resources as tools for tool-only clients
- `PromptsAsTools` - exposes prompts as tools for tool-only clients
@@ -149,7 +149,7 @@ Transforms apply at two levels:
- **Provider-level**: `provider.add_transform()` - affects only that provider's components
- **Server-level**: `server.add_transform()` - affects all components from all providers
-Documentation: `docs/servers/providers/transforms.mdx`, `docs/servers/enabled.mdx`
+Documentation: `docs/servers/providers/transforms.mdx`, `docs/servers/visibility.mdx`
### ResourcesAsTools and PromptsAsTools
@@ -232,9 +232,9 @@ Documentation: `docs/servers/context.mdx`
---
-## Enabled System
+## Visibility System
-Components can be enabled/disabled using the enabled system. Each `enable()` or `disable()` call adds a stateless Enabled transform that marks components via internal metadata. Later transforms override earlier ones.
+Components can be enabled/disabled using the visibility system. Each `enable()` or `disable()` call adds a stateless Visibility transform that marks components via internal metadata. Later transforms override earlier ones.
```python
mcp = FastMCP("Server")
@@ -261,7 +261,7 @@ Works at both server and provider level. Supports:
- **Allowlist mode** (`only=True`): Only explicitly enabled components visible
- **Tag-based filtering**: Enable/disable groups of components by tag
- **Override semantics**: Later transforms override earlier marks (enable after disable = enabled)
-- **Transform ordering**: Enabled transforms are injected at the point you call them, so component state is known
+- **Transform ordering**: Visibility transforms are injected at the point you call them, so component state is known
### Per-Session Visibility
@@ -286,7 +286,7 @@ async def unlock_premium(ctx: Context) -> str:
@mcp.tool
async def reset_features(ctx: Context) -> str:
"""Reset to default feature set."""
- await ctx.reset_components()
+ await ctx.reset_visibility()
return "Features reset to defaults"
# Globally disabled - sessions unlock individually
@@ -296,11 +296,11 @@ mcp.disable(tags={"premium"})
Session visibility methods:
- `await ctx.enable_components(...)`: Enable components for this session
- `await ctx.disable_components(...)`: Disable components for this session
-- `await ctx.reset_components()`: Clear session rules, return to global defaults
+- `await ctx.reset_visibility()`: Clear session rules, return to global defaults
Session rules override global transforms. FastMCP automatically sends `ToolListChangedNotification` (and resource/prompt equivalents) to affected sessions when visibility changes.
-Documentation: `docs/servers/enabled.mdx`
+Documentation: `docs/servers/visibility.mdx`
---
diff --git a/docs/docs.json b/docs/docs.json
index 61259d7739..cfc5f54e8b 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -137,7 +137,7 @@
"servers/tasks",
"servers/telemetry",
"servers/versioning",
- "servers/enabled"
+ "servers/visibility"
]
},
{
@@ -563,7 +563,7 @@
"group": "transforms",
"pages": [
"python-sdk/fastmcp-server-transforms-__init__",
- "python-sdk/fastmcp-server-transforms-enabled",
+ "python-sdk/fastmcp-server-transforms-visibility",
"python-sdk/fastmcp-server-transforms-namespace",
"python-sdk/fastmcp-server-transforms-prompts_as_tools",
"python-sdk/fastmcp-server-transforms-resources_as_tools",
diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index 85688d54fc..1edf918c8d 100644
--- a/docs/python-sdk/fastmcp-server-context.mdx
+++ b/docs/python-sdk/fastmcp-server-context.mdx
@@ -591,7 +591,7 @@ Enable components matching criteria for this session only.
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
-(Enabled transform semantics).
+(Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -615,7 +615,7 @@ Disable components matching criteria for this session only.
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
-(Enabled transform semantics).
+(Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -629,10 +629,10 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-#### `reset_components`
+#### `reset_visibility`
```python
-reset_components(self) -> None
+reset_visibility(self) -> None
```
Clear all session visibility rules.
diff --git a/docs/python-sdk/fastmcp-server-providers-base.mdx b/docs/python-sdk/fastmcp-server-providers-base.mdx
index 730fe973dc..ee80c310fd 100644
--- a/docs/python-sdk/fastmcp-server-providers-base.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-base.mdx
@@ -121,7 +121,7 @@ get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
Get tool by transformed name with all transforms applied.
Note: This method does NOT filter disabled components. The Server
-(FastMCP) performs enabled filtering after all transforms complete,
+(FastMCP) performs visibility filtering after all transforms complete,
allowing session-level transforms to override provider-level disables.
**Args:**
@@ -152,7 +152,7 @@ get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | N
Get resource by transformed URI with all transforms applied.
Note: This method does NOT filter disabled components. The Server
-(FastMCP) performs enabled filtering after all transforms complete.
+(FastMCP) performs visibility filtering after all transforms complete.
**Args:**
- `uri`: The transformed resource URI to look up.
@@ -182,7 +182,7 @@ get_resource_template(self, uri: str, version: VersionSpec | None = None) -> Res
Get resource template by transformed URI with all transforms applied.
Note: This method does NOT filter disabled components. The Server
-(FastMCP) performs enabled filtering after all transforms complete.
+(FastMCP) performs visibility filtering after all transforms complete.
**Args:**
- `uri`: The transformed template URI to look up.
@@ -212,7 +212,7 @@ get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
Get prompt by transformed name with all transforms applied.
Note: This method does NOT filter disabled components. The Server
-(FastMCP) performs enabled filtering after all transforms complete.
+(FastMCP) performs visibility filtering after all transforms complete.
**Args:**
- `name`: The transformed prompt name to look up.
@@ -289,7 +289,7 @@ disable(self) -> Self
Disable components matching all specified criteria.
-Adds an enabled transform that marks matching components as disabled.
+Adds a visibility transform that marks matching components as disabled.
Components can be re-enabled by calling enable() with matching criteria
(the later transform wins).
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 353023918d..21db24fadc 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -191,7 +191,7 @@ list_tools(self) -> Sequence[Tool]
List all enabled tools from providers.
-Overrides Provider.list_tools() to add enabled filtering, auth filtering,
+Overrides Provider.list_tools() to add visibility filtering, auth filtering,
and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
@@ -204,7 +204,7 @@ get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
Get a tool by name, filtering disabled tools.
-Overrides Provider.get_tool() to add enabled filtering after all
+Overrides Provider.get_tool() to add visibility filtering after all
transforms (including session-level) have been applied. This ensures
session transforms can override provider-level disables.
@@ -224,7 +224,7 @@ list_resources(self) -> Sequence[Resource]
List all enabled resources from providers.
-Overrides Provider.list_resources() to add enabled filtering, auth filtering,
+Overrides Provider.list_resources() to add visibility filtering, auth filtering,
and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
@@ -237,7 +237,7 @@ get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | N
Get a resource by URI, filtering disabled resources.
-Overrides Provider.get_resource() to add enabled filtering after all
+Overrides Provider.get_resource() to add visibility filtering after all
transforms (including session-level) have been applied.
**Args:**
@@ -256,7 +256,7 @@ list_resource_templates(self) -> Sequence[ResourceTemplate]
List all enabled resource templates from providers.
-Overrides Provider.list_resource_templates() to add enabled filtering,
+Overrides Provider.list_resource_templates() to add visibility filtering,
auth filtering, and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
@@ -269,7 +269,7 @@ get_resource_template(self, uri: str, version: VersionSpec | None = None) -> Res
Get a resource template by URI, filtering disabled templates.
-Overrides Provider.get_resource_template() to add enabled filtering after
+Overrides Provider.get_resource_template() to add visibility filtering after
all transforms (including session-level) have been applied.
**Args:**
@@ -288,7 +288,7 @@ list_prompts(self) -> Sequence[Prompt]
List all enabled prompts from providers.
-Overrides Provider.list_prompts() to add enabled filtering, auth filtering,
+Overrides Provider.list_prompts() to add visibility filtering, auth filtering,
and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
@@ -301,7 +301,7 @@ get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
Get a prompt by name, filtering disabled prompts.
-Overrides Provider.get_prompt() to add enabled filtering after all
+Overrides Provider.get_prompt() to add visibility filtering after all
transforms (including session-level) have been applied.
**Args:**
diff --git a/docs/python-sdk/fastmcp-server-transforms-enabled.mdx b/docs/python-sdk/fastmcp-server-transforms-visibility.mdx
similarity index 60%
rename from docs/python-sdk/fastmcp-server-transforms-enabled.mdx
rename to docs/python-sdk/fastmcp-server-transforms-visibility.mdx
index a3b3f3b8d0..383eb0cc4d 100644
--- a/docs/python-sdk/fastmcp-server-transforms-enabled.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-visibility.mdx
@@ -1,21 +1,21 @@
---
-title: enabled
-sidebarTitle: enabled
+title: visibility
+sidebarTitle: visibility
---
-# `fastmcp.server.transforms.enabled`
+# `fastmcp.server.transforms.visibility`
-Enabled transform for marking component enabled state.
+Visibility transform for marking component visibility state.
-Each Enabled instance marks components via internal metadata. Multiple
-enabled transforms can be stacked - later transforms override earlier ones.
+Each Visibility instance marks components via internal metadata. Multiple
+visibility transforms can be stacked - later transforms override earlier ones.
Final filtering happens at the Provider level.
## Functions
-### `is_enabled`
+### `is_enabled`
```python
is_enabled(component: FastMCPComponent) -> bool
@@ -25,10 +25,10 @@ is_enabled(component: FastMCPComponent) -> bool
Check if component is enabled.
Returns True if:
-- No enabled mark exists (default is enabled)
-- Enabled mark is True
+- No visibility mark exists (default is enabled)
+- Visibility mark is True
-Returns False if enabled mark is False.
+Returns False if visibility mark is False.
**Args:**
- `component`: Component to check.
@@ -37,7 +37,7 @@ Returns False if enabled mark is False.
- True if component should be enabled/visible to clients.
-### `get_visibility_rules`
+### `get_visibility_rules`
```python
get_visibility_rules(context: Context) -> list[dict[str, Any]]
@@ -47,7 +47,7 @@ get_visibility_rules(context: Context) -> list[dict[str, Any]]
Load visibility rule dicts from session state.
-### `save_visibility_rules`
+### `save_visibility_rules`
```python
save_visibility_rules(context: Context, rules: list[dict[str, Any]]) -> None
@@ -64,27 +64,27 @@ If None, sends notifications for all types (safe default).
If provided, only sends notifications for specified types.
-### `create_enabled_transforms`
+### `create_visibility_transforms`
```python
-create_enabled_transforms(rules: list[dict[str, Any]]) -> list[Enabled]
+create_visibility_transforms(rules: list[dict[str, Any]]) -> list[Visibility]
```
-Convert rule dicts to Enabled transforms.
+Convert rule dicts to Visibility transforms.
-### `get_session_transforms`
+### `get_session_transforms`
```python
-get_session_transforms(context: Context) -> list[Enabled]
+get_session_transforms(context: Context) -> list[Visibility]
```
-Get session-specific Enabled transforms from state store.
+Get session-specific Visibility transforms from state store.
-### `enable_components`
+### `enable_components`
```python
enable_components(context: Context) -> None
@@ -95,7 +95,7 @@ Enable components matching criteria for this session only.
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
-(Enabled transform semantics).
+(Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -110,7 +110,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-### `disable_components`
+### `disable_components`
```python
disable_components(context: Context) -> None
@@ -121,7 +121,7 @@ Disable components matching criteria for this session only.
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
-(Enabled transform semantics).
+(Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -136,10 +136,10 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-### `reset_components`
+### `reset_visibility`
```python
-reset_components(context: Context) -> None
+reset_visibility(context: Context) -> None
```
@@ -154,7 +154,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `context`: The context for this session.
-### `apply_session_transforms`
+### `apply_session_transforms`
```python
apply_session_transforms(components: Sequence[ComponentT]) -> Sequence[ComponentT]
@@ -164,7 +164,7 @@ apply_session_transforms(components: Sequence[ComponentT]) -> Sequence[Component
Apply session-specific visibility transforms to components.
This helper applies session-level enable/disable rules by marking
-components with their enabled state. Session transforms override
+components with their visibility state. Session transforms override
global transforms due to mark-based semantics (later marks win).
**Args:**
@@ -176,28 +176,28 @@ global transforms due to mark-based semantics (later marks win).
## Classes
-### `Enabled`
+### `Visibility`
-Sets enabled state on matching components.
+Sets visibility state on matching components.
-Does NOT filter inline - just marks components with enabled state.
+Does NOT filter inline - just marks components with visibility state.
Later transforms in the chain can override earlier marks.
Final filtering happens at the Provider level after all transforms run.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
-Mark tools by enabled state.
+Mark tools by visibility state.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
@@ -206,16 +206,16 @@ get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
Mark tool if found.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
```
-Mark resources by enabled state.
+Mark resources by visibility state.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
@@ -224,16 +224,16 @@ get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
Mark resource if found.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
```
-Mark resource templates by enabled state.
+Mark resource templates by visibility state.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None
@@ -242,20 +242,19 @@ get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> Res
Mark resource template if found.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
```
-Mark prompts by enabled state.
+Mark prompts by visibility state.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None
```
Mark prompt if found.
-
diff --git a/docs/servers/context.mdx b/docs/servers/context.mdx
index 5dcea7f67b..e020db32e3 100644
--- a/docs/servers/context.mdx
+++ b/docs/servers/context.mdx
@@ -23,7 +23,7 @@ The `Context` object provides a clean interface to access MCP features within yo
- **LLM Sampling**: Request the client's LLM to generate text based on provided messages
- **User Elicitation**: Request structured input from users during tool execution
- **Session State**: Store data that persists across requests within an MCP session
-- **Session Visibility**: [Control which components are visible](/servers/enabled#per-session-visibility) to the current session
+- **Session Visibility**: [Control which components are visible](/servers/visibility#per-session-visibility) to the current session
- **Request Information**: Access metadata about the current request
- **Server Access**: When needed, access the underlying FastMCP server instance
@@ -266,7 +266,7 @@ State set during `on_initialize` middleware persists to subsequent tool calls wh
-Tools can customize which components are visible to their current session using `ctx.enable_components()`, `ctx.disable_components()`, and `ctx.reset_components()`. These methods apply visibility rules that affect only the calling session, leaving other sessions unchanged. See [Per-Session Visibility](/servers/enabled#per-session-visibility) for complete documentation, filter criteria, and patterns like namespace activation.
+Tools can customize which components are visible to their current session using `ctx.enable_components()`, `ctx.disable_components()`, and `ctx.reset_visibility()`. These methods apply visibility rules that affect only the calling session, leaving other sessions unchanged. See [Per-Session Visibility](/servers/visibility#per-session-visibility) for complete documentation, filter criteria, and patterns like namespace activation.
### Change Notifications
diff --git a/docs/servers/prompts.mdx b/docs/servers/prompts.mdx
index 47e3c48729..95b1bb64a2 100644
--- a/docs/servers/prompts.mdx
+++ b/docs/servers/prompts.mdx
@@ -354,7 +354,7 @@ mcp.disable(tags={"internal"})
mcp.enable(tags={"public"}, only=True)
```
-See [Enabled](/servers/enabled) for the complete enabled control API including key formats, tag-based filtering, and provider-level control.
+See [Visibility](/servers/visibility) for the complete visibility control API including key formats, tag-based filtering, and provider-level control.
### Async Prompts
diff --git a/docs/servers/providers/custom.mdx b/docs/servers/providers/custom.mdx
index 12daa4bdcf..248e32d20a 100644
--- a/docs/servers/providers/custom.mdx
+++ b/docs/servers/providers/custom.mdx
@@ -29,7 +29,7 @@ Both providers and [middleware](/servers/middleware) can influence what componen
**Middleware** intercepts individual requests. It's well-suited for request-specific decisions like logging, rate limiting, or authentication.
-You *could* use middleware to dynamically add tools based on request context. But it's often cleaner to have a provider source all possible tools, then use middleware or [enabled controls](/servers/enabled) to filter what each request can see. This separation makes it easier to reason about how components are sourced and how they interact with other server machinery.
+You *could* use middleware to dynamically add tools based on request context. But it's often cleaner to have a provider source all possible tools, then use middleware or [visibility controls](/servers/visibility) to filter what each request can see. This separation makes it easier to reason about how components are sourced and how they interact with other server machinery.
## The Provider Interface
diff --git a/docs/servers/providers/local.mdx b/docs/servers/providers/local.mdx
index 9765c4111f..7cdefa5e61 100644
--- a/docs/servers/providers/local.mdx
+++ b/docs/servers/providers/local.mdx
@@ -126,7 +126,7 @@ mcp.disable(tags={"admin"})
mcp.enable(keys={"tool:get_status"}, only=True)
```
-See [Enabled](/servers/enabled) for the full documentation on keys, tags, allowlist mode, and provider-level control.
+See [Visibility](/servers/visibility) for the full documentation on keys, tags, allowlist mode, and provider-level control.
## Standalone LocalProvider
@@ -157,4 +157,4 @@ This is useful for:
- Testing components in isolation
- Building reusable component libraries
-Standalone providers also support enabled control with `enable()` and `disable()`. See [Enabled](/servers/enabled) for details.
+Standalone providers also support visibility control with `enable()` and `disable()`. See [Visibility](/servers/visibility) for details.
diff --git a/docs/servers/providers/overview.mdx b/docs/servers/providers/overview.mdx
index c291f2eccb..07b9e8bceb 100644
--- a/docs/servers/providers/overview.mdx
+++ b/docs/servers/providers/overview.mdx
@@ -67,7 +67,7 @@ When a client requests a tool, FastMCP queries providers in registration order.
**Learn about providers when** you want to:
- [Mount another server](/servers/providers/mounting) into yours
- [Proxy a remote server](/servers/providers/proxy) through yours
-- [Control enabled state](/servers/enabled) of components
+- [Control visibility state](/servers/visibility) of components
- [Build dynamic sources](/servers/providers/custom) like database-backed tools
## Next Steps
@@ -76,5 +76,5 @@ When a client requests a tool, FastMCP queries providers in registration order.
- [Mounting](/servers/providers/mounting) - Compose servers together
- [Proxying](/servers/providers/proxy) - Connect to remote servers
- [Transforms](/servers/providers/transforms) - Namespace, rename, and modify components
-- [Enabled](/servers/enabled) - Control which components clients can access
+- [Visibility](/servers/visibility) - Control which components clients can access
- [Custom](/servers/providers/custom) - Build your own providers
diff --git a/docs/servers/resources.mdx b/docs/servers/resources.mdx
index b78b7568a0..1c24d524f4 100644
--- a/docs/servers/resources.mdx
+++ b/docs/servers/resources.mdx
@@ -240,7 +240,7 @@ mcp.disable(tags={"internal"})
mcp.enable(tags={"public"}, only=True)
```
-See [Enabled](/servers/enabled) for the complete enabled control API including key formats, tag-based filtering, and provider-level control.
+See [Visibility](/servers/visibility) for the complete visibility control API including key formats, tag-based filtering, and provider-level control.
### Accessing MCP Context
diff --git a/docs/servers/tools.mdx b/docs/servers/tools.mdx
index 483d0825b4..ce4cb9b888 100644
--- a/docs/servers/tools.mdx
+++ b/docs/servers/tools.mdx
@@ -862,7 +862,7 @@ mcp.disable(tags={"admin"})
mcp.enable(tags={"public"}, only=True)
```
-See [Enabled](/servers/enabled) for the complete enabled control API including key formats, tag-based filtering, and provider-level control.
+See [Visibility](/servers/visibility) for the complete visibility control API including key formats, tag-based filtering, and provider-level control.
## MCP Annotations
diff --git a/docs/servers/enabled.mdx b/docs/servers/visibility.mdx
similarity index 87%
rename from docs/servers/enabled.mdx
rename to docs/servers/visibility.mdx
index bd718aa149..ad378eacdc 100644
--- a/docs/servers/enabled.mdx
+++ b/docs/servers/visibility.mdx
@@ -59,7 +59,7 @@ mcp.enable(tags={"admin"})
## Keys and Tags
-Enabled filtering works with two identifiers: keys (for specific components) and tags (for groups).
+Visibility filtering works with two identifiers: keys (for specific components) and tags (for groups).
### Component Keys
@@ -123,7 +123,7 @@ mcp.disable(keys={"tool:debug_info"}, tags={"dangerous"})
## Allowlist Mode
-By default, enabled filtering uses blocklist mode: everything is enabled unless explicitly disabled. The `only=True` parameter switches to allowlist mode, where **only** specified components are enabled.
+By default, visibility filtering uses blocklist mode: everything is enabled unless explicitly disabled. The `only=True` parameter switches to allowlist mode, where **only** specified components are enabled.
```python
from fastmcp import FastMCP
@@ -159,7 +159,7 @@ Allowlist mode is useful for restrictive environments where you want to explicit
When you call `enable(only=True)`:
-1. Default enabled state switches to "disabled"
+1. Default visibility state switches to "disabled"
2. Previous allowlists are cleared
3. Only specified keys/tags become enabled
@@ -186,11 +186,11 @@ You can always re-enable something that was disabled by adding another `enable()
## Server vs Provider
-Enabled state operates at two levels: the server and individual providers.
+Visibility state operates at two levels: the server and individual providers.
### Server-Level
-Server-level enabled state applies to all components from all providers. When you call `mcp.enable()` or `mcp.disable()`, you're filtering the final view that clients see.
+Server-level visibility state applies to all components from all providers. When you call `mcp.enable()` or `mcp.disable()`, you're filtering the final view that clients see.
```python
from fastmcp import FastMCP
@@ -208,13 +208,13 @@ main.disable(tags={"internal"})
### Provider-Level
-Each provider can add its own enabled transforms. These run before server-level transforms, so the server can override provider-level disables.
+Each provider can add its own visibility transforms. These run before server-level transforms, so the server can override provider-level disables.
```python
from fastmcp import FastMCP
from fastmcp.server.providers import LocalProvider
-# Create provider with enabled control
+# Create provider with visibility control
admin_tools = LocalProvider()
@admin_tools.tool(tags={"admin"})
@@ -261,7 +261,7 @@ mcp.disable(tags={"beta"})
## Dynamic Changes
-Enabled state changes take effect immediately. You can adjust during request handling based on context.
+Visibility state changes take effect immediately. You can adjust during request handling based on context.
```python
from fastmcp import FastMCP
@@ -312,7 +312,7 @@ async def unlock_premium(ctx: Context) -> str:
@mcp.tool
async def reset_features(ctx: Context) -> str:
"""Reset to default feature set."""
- await ctx.reset_components()
+ await ctx.reset_visibility()
return "Features reset to defaults"
# Premium tools are disabled globally by default
@@ -419,7 +419,7 @@ async def activate_admin(ctx: Context) -> str:
@server.tool
async def deactivate_all(ctx: Context) -> str:
- await ctx.reset_components()
+ await ctx.reset_visibility()
return "All namespaces deactivated"
# Disable namespace tools globally
@@ -432,11 +432,11 @@ Sessions start seeing only the activation tools. Calling `activate_finance` reve
- **`await ctx.enable_components(...) -> None`**: Enable matching components for this session
- **`await ctx.disable_components(...) -> None`**: Disable matching components for this session
-- **`await ctx.reset_components() -> None`**: Clear all session rules, returning to global defaults
+- **`await ctx.reset_visibility() -> None`**: Clear all session rules, returning to global defaults
## Client Notifications
-When enabled state changes, FastMCP automatically notifies connected clients. Clients supporting the MCP notification protocol receive `list_changed` events and can refresh their component lists.
+When visibility state changes, FastMCP automatically notifies connected clients. Clients supporting the MCP notification protocol receive `list_changed` events and can refresh their component lists.
This happens automatically. You don't need to trigger notifications manually.
@@ -449,23 +449,23 @@ mcp.disable(tags={"maintenance"})
## Filtering Logic
-Understanding the filtering logic helps when debugging enabled state issues.
+Understanding the filtering logic helps when debugging visibility state issues.
The `is_enabled()` function checks a component's internal metadata:
-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
+1. If the component has `meta.fastmcp._internal.visibility = False`, it's disabled
+2. If the component has `meta.fastmcp._internal.visibility = True`, it's enabled
+3. If no visibility state is set, the component is enabled by default
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
+## The Visibility Transform
-Under the hood, `enable()` and `disable()` add `Enabled` transforms to the server or provider. The `Enabled` transform marks components with enabled metadata, and the server applies the final filter after all provider and server transforms complete.
+Under the hood, `enable()` and `disable()` add `Visibility` transforms to the server or provider. The `Visibility` transform marks components with visibility metadata, and the server applies the final filter after all provider and server transforms complete.
```python
from fastmcp import FastMCP
-from fastmcp.server.transforms import Enabled
+from fastmcp.server.transforms import Visibility
mcp = FastMCP("Server")
@@ -473,7 +473,7 @@ mcp = FastMCP("Server")
mcp.disable(names={"secret_tool"})
# Equivalent to:
-mcp.add_transform(Enabled(False, names={"secret_tool"}))
+mcp.add_transform(Visibility(False, names={"secret_tool"}))
```
Server-level transforms override provider-level transforms. If a component is disabled at the provider level but enabled at the server level, the server-level `enable()` can re-enable it.
diff --git a/examples/namespace_activation/server.py b/examples/namespace_activation/server.py
index 758790b0c9..f906d9f15c 100644
--- a/examples/namespace_activation/server.py
+++ b/examples/namespace_activation/server.py
@@ -61,7 +61,7 @@ async def activate_admin(ctx: Context) -> str:
@server.tool
async def deactivate_all(ctx: Context) -> str:
"""Deactivate all namespaces, returning to defaults."""
- await ctx.reset_components()
+ await ctx.reset_visibility()
return "All namespaces deactivated"
diff --git a/src/fastmcp/server/context.py b/src/fastmcp/server/context.py
index 9dbc9376cf..0fe505b16b 100644
--- a/src/fastmcp/server/context.py
+++ b/src/fastmcp/server/context.py
@@ -39,23 +39,23 @@
sample_step_impl,
)
from fastmcp.server.server import FastMCP, StateValue
-from fastmcp.server.transforms.enabled import (
- Enabled,
+from fastmcp.server.transforms.visibility import (
+ Visibility,
)
-from fastmcp.server.transforms.enabled import (
+from fastmcp.server.transforms.visibility import (
disable_components as _disable_components,
)
-from fastmcp.server.transforms.enabled import (
+from fastmcp.server.transforms.visibility import (
enable_components as _enable_components,
)
-from fastmcp.server.transforms.enabled import (
+from fastmcp.server.transforms.visibility import (
get_session_transforms as _get_session_transforms,
)
-from fastmcp.server.transforms.enabled import (
+from fastmcp.server.transforms.visibility import (
get_visibility_rules as _get_visibility_rules,
)
-from fastmcp.server.transforms.enabled import (
- reset_components as _reset_components,
+from fastmcp.server.transforms.visibility import (
+ reset_visibility as _reset_visibility,
)
from fastmcp.utilities.logging import _clamp_logger, get_logger
from fastmcp.utilities.versions import VersionSpec
@@ -990,8 +990,8 @@ async def _get_visibility_rules(self) -> list[dict[str, Any]]:
"""Load visibility rule dicts from session state."""
return await _get_visibility_rules(self)
- async def _get_session_transforms(self) -> list[Enabled]:
- """Get session-specific Enabled transforms from state store."""
+ async def _get_session_transforms(self) -> list[Visibility]:
+ """Get session-specific Visibility transforms from state store."""
return await _get_session_transforms(self)
async def enable_components(
@@ -1009,7 +1009,7 @@ async def enable_components(
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
- (Enabled transform semantics).
+ (Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -1047,7 +1047,7 @@ async def disable_components(
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
- (Enabled transform semantics).
+ (Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -1070,7 +1070,7 @@ async def disable_components(
match_all=match_all,
)
- async def reset_components(self) -> None:
+ async def reset_visibility(self) -> None:
"""Clear all session visibility rules.
Use this to reset session visibility back to global defaults.
@@ -1078,7 +1078,7 @@ async def reset_components(self) -> None:
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
"""
- await _reset_components(self)
+ await _reset_visibility(self)
async def _log_to_server_and_client(
diff --git a/src/fastmcp/server/providers/base.py b/src/fastmcp/server/providers/base.py
index 03c00a8a25..ccd48765f7 100644
--- a/src/fastmcp/server/providers/base.py
+++ b/src/fastmcp/server/providers/base.py
@@ -38,7 +38,7 @@ async def _get_tool(self, name: str) -> Tool | None:
from fastmcp.prompts.prompt import Prompt
from fastmcp.resources.resource import Resource
from fastmcp.resources.template import ResourceTemplate
-from fastmcp.server.transforms.enabled import Enabled
+from fastmcp.server.transforms.visibility import Visibility
from fastmcp.tools.tool import Tool
from fastmcp.utilities.async_utils import gather
from fastmcp.utilities.components import FastMCPComponent
@@ -502,7 +502,7 @@ def enable(
) -> Self:
"""Enable components matching all specified criteria.
- Adds an enabled transform that marks matching components as enabled.
+ Adds a visibility transform that marks matching components as enabled.
Later transforms override earlier ones, so enable after disable makes
the component enabled.
@@ -524,9 +524,9 @@ def enable(
if only:
# Allowlist: disable everything, then enable matching
# The enable transform runs later on return path, so it overrides
- self._transforms.append(Enabled(False, match_all=True))
+ self._transforms.append(Visibility(False, match_all=True))
self._transforms.append(
- Enabled(
+ Visibility(
True,
names=names,
keys=keys,
@@ -550,7 +550,7 @@ def disable(
) -> Self:
"""Disable components matching all specified criteria.
- Adds an enabled transform that marks matching components as disabled.
+ Adds a visibility transform that marks matching components as disabled.
Components can be re-enabled by calling enable() with matching criteria
(the later transform wins).
@@ -566,7 +566,7 @@ def disable(
Self for method chaining.
"""
self._transforms.append(
- Enabled(
+ Visibility(
False,
names=names,
keys=keys,
diff --git a/src/fastmcp/server/server.py b/src/fastmcp/server/server.py
index a1c328a0c6..48a2fdf933 100644
--- a/src/fastmcp/server/server.py
+++ b/src/fastmcp/server/server.py
@@ -72,7 +72,7 @@
ToolTransform,
Transform,
)
-from fastmcp.server.transforms.enabled import apply_session_transforms, is_enabled
+from fastmcp.server.transforms.visibility import apply_session_transforms, is_enabled
from fastmcp.settings import DuplicateBehavior as DuplicateBehaviorSetting
from fastmcp.settings import Settings
from fastmcp.tools.function_tool import FunctionTool
@@ -604,7 +604,7 @@ def remove_tool_transformation(self, _tool_name: str) -> None:
async def list_tools(self, *, run_middleware: bool = True) -> Sequence[Tool]:
"""List all enabled tools from providers.
- Overrides Provider.list_tools() to add enabled filtering, auth filtering,
+ Overrides Provider.list_tools() to add visibility filtering, auth filtering,
and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
"""
@@ -676,7 +676,7 @@ async def get_tool(
) -> Tool | None:
"""Get a tool by name, filtering disabled tools.
- Overrides Provider.get_tool() to add enabled filtering after all
+ Overrides Provider.get_tool() to add visibility filtering after all
transforms (including session-level) have been applied. This ensures
session transforms can override provider-level disables.
@@ -702,7 +702,7 @@ async def list_resources(
) -> Sequence[Resource]:
"""List all enabled resources from providers.
- Overrides Provider.list_resources() to add enabled filtering, auth filtering,
+ Overrides Provider.list_resources() to add visibility filtering, auth filtering,
and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
"""
@@ -774,7 +774,7 @@ async def get_resource(
) -> Resource | None:
"""Get a resource by URI, filtering disabled resources.
- Overrides Provider.get_resource() to add enabled filtering after all
+ Overrides Provider.get_resource() to add visibility filtering after all
transforms (including session-level) have been applied.
Args:
@@ -799,7 +799,7 @@ async def list_resource_templates(
) -> Sequence[ResourceTemplate]:
"""List all enabled resource templates from providers.
- Overrides Provider.list_resource_templates() to add enabled filtering,
+ Overrides Provider.list_resource_templates() to add visibility filtering,
auth filtering, and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
"""
@@ -873,7 +873,7 @@ async def get_resource_template(
) -> ResourceTemplate | None:
"""Get a resource template by URI, filtering disabled templates.
- Overrides Provider.get_resource_template() to add enabled filtering after
+ Overrides Provider.get_resource_template() to add visibility filtering after
all transforms (including session-level) have been applied.
Args:
@@ -896,7 +896,7 @@ async def get_resource_template(
async def list_prompts(self, *, run_middleware: bool = True) -> Sequence[Prompt]:
"""List all enabled prompts from providers.
- Overrides Provider.list_prompts() to add enabled filtering, auth filtering,
+ Overrides Provider.list_prompts() to add visibility filtering, auth filtering,
and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
"""
@@ -968,7 +968,7 @@ async def get_prompt(
) -> Prompt | None:
"""Get a prompt by name, filtering disabled prompts.
- Overrides Provider.get_prompt() to add enabled filtering after all
+ Overrides Provider.get_prompt() to add visibility filtering after all
transforms (including session-level) have been applied.
Args:
diff --git a/src/fastmcp/server/transforms/__init__.py b/src/fastmcp/server/transforms/__init__.py
index 63225854ae..9e55cc9035 100644
--- a/src/fastmcp/server/transforms/__init__.py
+++ b/src/fastmcp/server/transforms/__init__.py
@@ -220,7 +220,7 @@ async def get_prompt(
# Re-export built-in transforms (must be after Transform class to avoid circular imports)
-from fastmcp.server.transforms.enabled import Enabled, is_enabled # noqa: E402
+from fastmcp.server.transforms.visibility import Visibility, is_enabled # noqa: E402
from fastmcp.server.transforms.namespace import Namespace # noqa: E402
from fastmcp.server.transforms.prompts_as_tools import PromptsAsTools # noqa: E402
from fastmcp.server.transforms.resources_as_tools import ResourcesAsTools # noqa: E402
@@ -228,7 +228,6 @@ async def get_prompt(
from fastmcp.server.transforms.version_filter import VersionFilter # noqa: E402
__all__ = [
- "Enabled",
"GetPromptNext",
"GetResourceNext",
"GetResourceTemplateNext",
@@ -240,5 +239,6 @@ async def get_prompt(
"Transform",
"VersionFilter",
"VersionSpec",
+ "Visibility",
"is_enabled",
]
diff --git a/src/fastmcp/server/transforms/enabled.py b/src/fastmcp/server/transforms/visibility.py
similarity index 89%
rename from src/fastmcp/server/transforms/enabled.py
rename to src/fastmcp/server/transforms/visibility.py
index faf9aeaaad..41061a6510 100644
--- a/src/fastmcp/server/transforms/enabled.py
+++ b/src/fastmcp/server/transforms/visibility.py
@@ -1,7 +1,7 @@
-"""Enabled transform for marking component enabled state.
+"""Visibility transform for marking component visibility state.
-Each Enabled instance marks components via internal metadata. Multiple
-enabled transforms can be stacked - later transforms override earlier ones.
+Each Visibility instance marks components via internal metadata. Multiple
+visibility transforms can be stacked - later transforms override earlier ones.
Final filtering happens at the Provider level.
"""
@@ -31,29 +31,29 @@
T = TypeVar("T", bound="FastMCPComponent")
-# Enabled state stored at meta["fastmcp"]["_internal"]["enabled"]
+# Visibility state stored at meta["fastmcp"]["_internal"]["visibility"]
_FASTMCP_KEY = "fastmcp"
_INTERNAL_KEY = "_internal"
-class Enabled(Transform):
- """Sets enabled state on matching components.
+class Visibility(Transform):
+ """Sets visibility state on matching components.
- Does NOT filter inline - just marks components with enabled state.
+ Does NOT filter inline - just marks components with visibility state.
Later transforms in the chain can override earlier marks.
Final filtering happens at the Provider level after all transforms run.
Example:
```python
# Disable components tagged "internal"
- Enabled(False, tags={"internal"})
+ Visibility(False, tags={"internal"})
# Re-enable specific tool (override earlier disable)
- Enabled(True, names={"safe_tool"})
+ Visibility(True, names={"safe_tool"})
# Allowlist via composition:
- Enabled(False, match_all=True) # disable everything
- Enabled(True, tags={"public"}) # enable public
+ Visibility(False, match_all=True) # disable everything
+ Visibility(True, tags={"public"}) # enable public
```
"""
@@ -69,7 +69,7 @@ def __init__(
| None = None,
match_all: bool = False,
) -> None:
- """Initialize an enabled marker.
+ """Initialize a visibility marker.
Args:
enabled: If True, mark matching as enabled; if False, mark as disabled.
@@ -92,7 +92,7 @@ def __init__(
def __repr__(self) -> str:
action = "enable" if self._enabled else "disable"
if self.match_all:
- return f"Enabled({self._enabled}, match_all=True)"
+ return f"Visibility({self._enabled}, match_all=True)"
parts = []
if self.names:
parts.append(f"names={set(self.names)}")
@@ -105,8 +105,8 @@ def __repr__(self) -> str:
if self.tags:
parts.append(f"tags={set(self.tags)}")
if parts:
- return f"Enabled({action}, {', '.join(parts)})"
- return f"Enabled({action})"
+ return f"Visibility({action}, {', '.join(parts)})"
+ return f"Visibility({action})"
def _matches(self, component: FastMCPComponent) -> bool:
"""Check if this transform applies to the component.
@@ -171,18 +171,20 @@ def _matches(self, component: FastMCPComponent) -> bool:
return self.tags is None or bool(component.tags & self.tags)
def _mark_component(self, component: T) -> T:
- """Set enabled state in component metadata if rule matches."""
+ """Set visibility state in component metadata if rule matches."""
if not self._matches(component):
return component
# Create new dicts to avoid mutating shared dicts
# (e.g., when Tool.from_tool shares the meta dict between tools)
if component.meta is None:
- component.meta = {_FASTMCP_KEY: {_INTERNAL_KEY: {"enabled": self._enabled}}}
+ component.meta = {
+ _FASTMCP_KEY: {_INTERNAL_KEY: {"visibility": self._enabled}}
+ }
else:
old_fastmcp = component.meta.get(_FASTMCP_KEY, {})
old_internal = old_fastmcp.get(_INTERNAL_KEY, {})
- new_internal = {**old_internal, "enabled": self._enabled}
+ new_internal = {**old_internal, "visibility": self._enabled}
new_fastmcp = {**old_fastmcp, _INTERNAL_KEY: new_internal}
component.meta = {**component.meta, _FASTMCP_KEY: new_fastmcp}
return component
@@ -192,7 +194,7 @@ def _mark_component(self, component: T) -> T:
# -------------------------------------------------------------------------
async def list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]:
- """Mark tools by enabled state."""
+ """Mark tools by visibility state."""
return [self._mark_component(t) for t in tools]
async def get_tool(
@@ -209,7 +211,7 @@ async def get_tool(
# -------------------------------------------------------------------------
async def list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]:
- """Mark resources by enabled state."""
+ """Mark resources by visibility state."""
return [self._mark_component(r) for r in resources]
async def get_resource(
@@ -232,7 +234,7 @@ async def get_resource(
async def list_resource_templates(
self, templates: Sequence[ResourceTemplate]
) -> Sequence[ResourceTemplate]:
- """Mark resource templates by enabled state."""
+ """Mark resource templates by visibility state."""
return [self._mark_component(t) for t in templates]
async def get_resource_template(
@@ -253,7 +255,7 @@ async def get_resource_template(
# -------------------------------------------------------------------------
async def list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]:
- """Mark prompts by enabled state."""
+ """Mark prompts by visibility state."""
return [self._mark_component(p) for p in prompts]
async def get_prompt(
@@ -270,10 +272,10 @@ def is_enabled(component: FastMCPComponent) -> bool:
"""Check if component is enabled.
Returns True if:
- - No enabled mark exists (default is enabled)
- - Enabled mark is True
+ - No visibility mark exists (default is enabled)
+ - Visibility mark is True
- Returns False if enabled mark is False.
+ Returns False if visibility mark is False.
Args:
component: Component to check.
@@ -284,7 +286,7 @@ def is_enabled(component: FastMCPComponent) -> bool:
meta = component.meta or {}
fastmcp = meta.get(_FASTMCP_KEY, {})
internal = fastmcp.get(_INTERNAL_KEY, {})
- return internal.get("enabled", True) # Default True if not set
+ return internal.get("visibility", True) # Default True if not set
# -------------------------------------------------------------------------
@@ -327,8 +329,8 @@ async def save_visibility_rules(
await context.send_notification(mcp.types.PromptListChangedNotification())
-def create_enabled_transforms(rules: list[dict[str, Any]]) -> list[Enabled]:
- """Convert rule dicts to Enabled transforms."""
+def create_visibility_transforms(rules: list[dict[str, Any]]) -> list[Visibility]:
+ """Convert rule dicts to Visibility transforms."""
transforms = []
for params in rules:
version = None
@@ -340,7 +342,7 @@ def create_enabled_transforms(rules: list[dict[str, Any]]) -> list[Enabled]:
eq=version_dict.get("eq"),
)
transforms.append(
- Enabled(
+ Visibility(
params["enabled"],
names=set(params["names"]) if params.get("names") else None,
keys=set(params["keys"]) if params.get("keys") else None,
@@ -355,8 +357,8 @@ def create_enabled_transforms(rules: list[dict[str, Any]]) -> list[Enabled]:
return transforms
-async def get_session_transforms(context: Context) -> list[Enabled]:
- """Get session-specific Enabled transforms from state store."""
+async def get_session_transforms(context: Context) -> list[Visibility]:
+ """Get session-specific Visibility transforms from state store."""
try:
# Will raise RuntimeError if no session available
_ = context.session_id
@@ -364,7 +366,7 @@ async def get_session_transforms(context: Context) -> list[Enabled]:
return []
rules = await get_visibility_rules(context)
- return create_enabled_transforms(rules)
+ return create_visibility_transforms(rules)
async def enable_components(
@@ -381,7 +383,7 @@ async def enable_components(
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
- (Enabled transform semantics).
+ (Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -435,7 +437,7 @@ async def disable_components(
Session rules override global transforms. Rules accumulate - each call
adds a new rule to the session. Later marks override earlier ones
- (Enabled transform semantics).
+ (Visibility transform semantics).
Sends notifications to this session only: ToolListChangedNotification,
ResourceListChangedNotification, and PromptListChangedNotification.
@@ -475,7 +477,7 @@ async def disable_components(
await save_visibility_rules(context, rules, components=components)
-async def reset_components(context: Context) -> None:
+async def reset_visibility(context: Context) -> None:
"""Clear all session visibility rules.
Use this to reset session visibility back to global defaults.
@@ -498,7 +500,7 @@ async def apply_session_transforms(
"""Apply session-specific visibility transforms to components.
This helper applies session-level enable/disable rules by marking
- components with their enabled state. Session transforms override
+ components with their visibility state. Session transforms override
global transforms due to mark-based semantics (later marks win).
Args:
diff --git a/tests/deprecated/server/test_include_exclude_tags.py b/tests/deprecated/server/test_include_exclude_tags.py
index 223f70048a..1bdf684324 100644
--- a/tests/deprecated/server/test_include_exclude_tags.py
+++ b/tests/deprecated/server/test_include_exclude_tags.py
@@ -3,7 +3,7 @@
import pytest
from fastmcp import FastMCP
-from fastmcp.server.transforms.enabled import Enabled
+from fastmcp.server.transforms.visibility import Visibility
class TestIncludeExcludeTagsDeprecation:
@@ -20,28 +20,28 @@ def test_include_tags_emits_warning(self):
FastMCP(include_tags={"public"})
def test_exclude_tags_still_works(self):
- """exclude_tags adds an Enabled transform that disables matching tags."""
+ """exclude_tags adds a Visibility transform that disables matching tags."""
with pytest.warns(DeprecationWarning):
mcp = FastMCP(exclude_tags={"internal"})
- # Should have added an Enabled transform that disables the tag
- enabled_transforms = [t for t in mcp._transforms if isinstance(t, Enabled)]
+ # Should have added a Visibility transform that disables the tag
+ enabled_transforms = [t for t in mcp._transforms if isinstance(t, Visibility)]
assert len(enabled_transforms) == 1
e = enabled_transforms[0]
assert e._enabled is False
assert e.tags == {"internal"}
def test_include_tags_still_works(self):
- """include_tags adds Enabled transforms for allowlist mode."""
+ """include_tags adds Visibility transforms for allowlist mode."""
with pytest.warns(DeprecationWarning):
mcp = FastMCP(include_tags={"public"})
- # Should have added Enabled transforms for allowlist mode
+ # Should have added Visibility transforms for allowlist mode
# (one to disable all, one to enable matching)
- enabled_transforms = [t for t in mcp._transforms if isinstance(t, Enabled)]
+ enabled_transforms = [t for t in mcp._transforms if isinstance(t, Visibility)]
assert len(enabled_transforms) == 2
- # First should disable all (Enabled.all(False))
+ # First should disable all (Visibility.all(False))
disable_all_transform = enabled_transforms[0]
assert disable_all_transform._enabled is False
assert disable_all_transform.match_all is True
@@ -59,7 +59,7 @@ def test_exclude_and_include_both_create_transforms(self):
# Should have added transforms for both
# include_tags creates 2 (disable all + enable matching)
# exclude_tags creates 1 (disable matching)
- enabled_transforms = [t for t in mcp._transforms if isinstance(t, Enabled)]
+ enabled_transforms = [t for t in mcp._transforms if isinstance(t, Visibility)]
assert len(enabled_transforms) == 3
# Check we have both tag rules
diff --git a/tests/server/providers/test_local_provider.py b/tests/server/providers/test_local_provider.py
index d920333933..2db664338c 100644
--- a/tests/server/providers/test_local_provider.py
+++ b/tests/server/providers/test_local_provider.py
@@ -336,7 +336,7 @@ def my_tool(x: int) -> int:
assert "tool:direct_tool@" in provider._components
def test_tool_enabled_false(self):
- """Tool with enabled=False should add an Enabled transform."""
+ """Tool with enabled=False should add a Visibility transform."""
provider = LocalProvider()
@provider.tool(enabled=False)
@@ -344,10 +344,12 @@ def disabled_tool() -> str:
return "should be disabled"
assert "tool:disabled_tool@" in provider._components
- # enabled=False adds an Enabled transform to disable the tool
- from fastmcp.server.transforms.enabled import Enabled
+ # enabled=False adds a Visibility transform to disable the tool
+ from fastmcp.server.transforms.visibility import Visibility
- enabled_transforms = [t for t in provider.transforms if isinstance(t, Enabled)]
+ enabled_transforms = [
+ t for t in provider.transforms if isinstance(t, Visibility)
+ ]
assert len(enabled_transforms) == 1
assert enabled_transforms[0]._enabled is False
assert enabled_transforms[0].keys == {"tool:disabled_tool@"}
@@ -425,7 +427,7 @@ def my_resource() -> str:
assert provider._components["resource:resource://test@"].name == "custom_name"
def test_resource_enabled_false(self):
- """Resource with enabled=False should add an Enabled transform."""
+ """Resource with enabled=False should add a Visibility transform."""
provider = LocalProvider()
@provider.resource("resource://test", enabled=False)
@@ -433,10 +435,12 @@ def disabled_resource() -> str:
return "should be disabled"
assert "resource:resource://test@" in provider._components
- # enabled=False adds an Enabled transform to disable the resource
- from fastmcp.server.transforms.enabled import Enabled
+ # enabled=False adds a Visibility transform to disable the resource
+ from fastmcp.server.transforms.visibility import Visibility
- enabled_transforms = [t for t in provider.transforms if isinstance(t, Enabled)]
+ enabled_transforms = [
+ t for t in provider.transforms if isinstance(t, Visibility)
+ ]
assert len(enabled_transforms) == 1
assert enabled_transforms[0]._enabled is False
assert enabled_transforms[0].keys == {"resource:resource://test@"}
@@ -461,7 +465,7 @@ def enabled_resource() -> str:
assert "resource://disabled" not in uris
def test_template_enabled_false(self):
- """Template with enabled=False should add an Enabled transform."""
+ """Template with enabled=False should add a Visibility transform."""
provider = LocalProvider()
@provider.resource("data://{id}", enabled=False)
@@ -469,10 +473,12 @@ def disabled_template(id: str) -> str:
return f"Data {id}"
assert "template:data://{id}@" in provider._components
- # enabled=False adds an Enabled transform to disable the template
- from fastmcp.server.transforms.enabled import Enabled
+ # enabled=False adds a Visibility transform to disable the template
+ from fastmcp.server.transforms.visibility import Visibility
- enabled_transforms = [t for t in provider.transforms if isinstance(t, Enabled)]
+ enabled_transforms = [
+ t for t in provider.transforms if isinstance(t, Visibility)
+ ]
assert len(enabled_transforms) == 1
assert enabled_transforms[0]._enabled is False
assert enabled_transforms[0].keys == {"template:data://{id}@"}
@@ -532,7 +538,7 @@ def my_prompt() -> str:
assert "prompt:my_prompt@" not in provider._components
def test_prompt_enabled_false(self):
- """Prompt with enabled=False should add an Enabled transform."""
+ """Prompt with enabled=False should add a Visibility transform."""
provider = LocalProvider()
@provider.prompt(enabled=False)
@@ -540,10 +546,12 @@ def disabled_prompt() -> str:
return "should be disabled"
assert "prompt:disabled_prompt@" in provider._components
- # enabled=False adds an Enabled transform to disable the prompt
- from fastmcp.server.transforms.enabled import Enabled
+ # enabled=False adds a Visibility transform to disable the prompt
+ from fastmcp.server.transforms.visibility import Visibility
- enabled_transforms = [t for t in provider.transforms if isinstance(t, Enabled)]
+ enabled_transforms = [
+ t for t in provider.transforms if isinstance(t, Visibility)
+ ]
assert len(enabled_transforms) == 1
assert enabled_transforms[0]._enabled is False
assert enabled_transforms[0].keys == {"prompt:disabled_prompt@"}
diff --git a/tests/server/test_session_visibility.py b/tests/server/test_session_visibility.py
index ca072c3f67..ae307dfc68 100644
--- a/tests/server/test_session_visibility.py
+++ b/tests/server/test_session_visibility.py
@@ -229,7 +229,7 @@ async def enable_v2_only(ctx: Context) -> str:
assert not any(t.name == "old_tool" for t in tools)
async def test_clear_visibility_rules(self):
- """Test that reset_components removes all session rules."""
+ """Test that reset_visibility removes all session rules."""
from fastmcp import Client
mcp = FastMCP("test")
@@ -245,7 +245,7 @@ async def activate_finance(ctx: Context) -> str:
@mcp.tool
async def clear_rules(ctx: Context) -> str:
- await ctx.reset_components()
+ await ctx.reset_visibility()
rules = await ctx._get_visibility_rules()
assert len(rules) == 0
return "cleared"
@@ -449,14 +449,14 @@ async def deactivate(ctx: Context) -> str:
)
async def test_clear_visibility_rules_sends_notifications(self):
- """Test that reset_components sends notifications."""
+ """Test that reset_visibility sends notifications."""
from fastmcp import Client
mcp = FastMCP("test")
@mcp.tool
async def clear(ctx: Context) -> str:
- await ctx.reset_components()
+ await ctx.reset_visibility()
return "cleared"
handler = RecordingMessageHandler()
diff --git a/tests/server/transforms/test_enabled.py b/tests/server/transforms/test_visibility.py
similarity index 78%
rename from tests/server/transforms/test_enabled.py
rename to tests/server/transforms/test_visibility.py
index fca9511d5c..cf7b9f1b7e 100644
--- a/tests/server/transforms/test_enabled.py
+++ b/tests/server/transforms/test_visibility.py
@@ -1,8 +1,8 @@
-"""Tests for Enabled transform."""
+"""Tests for Visibility transform."""
import pytest
-from fastmcp.server.transforms.enabled import Enabled, is_enabled
+from fastmcp.server.transforms.visibility import Visibility, is_enabled
from fastmcp.tools.tool import Tool
from fastmcp.utilities.versions import VersionSpec
@@ -12,43 +12,43 @@ class TestMatching:
def test_empty_criteria_matches_nothing(self):
"""Empty criteria is a safe default - matches nothing."""
- t = Enabled(False)
+ t = Visibility(False)
assert t._matches(Tool(name="anything", parameters={})) is False
def test_match_all_matches_everything(self):
"""match_all=True matches all components."""
- t = Enabled(False, match_all=True)
+ t = Visibility(False, match_all=True)
assert t._matches(Tool(name="anything", parameters={})) is True
def test_match_by_name(self):
"""Matches component by name."""
- t = Enabled(False, names={"foo"})
+ t = Visibility(False, names={"foo"})
assert t._matches(Tool(name="foo", parameters={})) is True
assert t._matches(Tool(name="bar", parameters={})) is False
def test_match_by_version(self):
"""Matches component by version."""
- t = Enabled(False, version=VersionSpec(eq="v1"))
+ t = Visibility(False, version=VersionSpec(eq="v1"))
assert t._matches(Tool(name="foo", version="v1", parameters={})) is True
assert t._matches(Tool(name="foo", version="v2", parameters={})) is False
def test_match_by_version_spec_exact(self):
"""VersionSpec(eq="v1") matches v1 only."""
- t = Enabled(False, version=VersionSpec(eq="v1"))
+ t = Visibility(False, version=VersionSpec(eq="v1"))
assert t._matches(Tool(name="foo", version="v1", parameters={})) is True
assert t._matches(Tool(name="foo", version="v2", parameters={})) is False
assert t._matches(Tool(name="foo", version="v0", parameters={})) is False
def test_match_by_version_spec_gte(self):
"""VersionSpec(gte="v2") matches v2, v3, but not v1."""
- t = Enabled(False, version=VersionSpec(gte="v2"))
+ t = Visibility(False, version=VersionSpec(gte="v2"))
assert t._matches(Tool(name="foo", version="v1", parameters={})) is False
assert t._matches(Tool(name="foo", version="v2", parameters={})) is True
assert t._matches(Tool(name="foo", version="v3", parameters={})) is True
def test_match_by_version_spec_range(self):
"""VersionSpec(gte="v1", lt="v3") matches v1, v2, but not v3."""
- t = Enabled(False, version=VersionSpec(gte="v1", lt="v3"))
+ t = Visibility(False, version=VersionSpec(gte="v1", lt="v3"))
assert t._matches(Tool(name="foo", version="v0", parameters={})) is False
assert t._matches(Tool(name="foo", version="v1", parameters={})) is True
assert t._matches(Tool(name="foo", version="v2", parameters={})) is True
@@ -57,27 +57,27 @@ def test_match_by_version_spec_range(self):
def test_unversioned_does_not_match_version_spec(self):
"""Unversioned components (version=None) don't match a VersionSpec."""
- t = Enabled(False, version=VersionSpec(eq="v1"))
+ t = Visibility(False, version=VersionSpec(eq="v1"))
assert t._matches(Tool(name="foo", parameters={})) is False
- t2 = Enabled(False, version=VersionSpec(gte="v1"))
+ t2 = Visibility(False, version=VersionSpec(gte="v1"))
assert t2._matches(Tool(name="foo", parameters={})) is False
def test_match_by_tag(self):
"""Matches if component has any of the specified tags."""
- t = Enabled(False, tags=set({"internal", "deprecated"}))
+ t = Visibility(False, tags=set({"internal", "deprecated"}))
assert t._matches(Tool(name="foo", parameters={}, tags={"internal"})) is True
assert t._matches(Tool(name="foo", parameters={}, tags={"public"})) is False
def test_match_by_component_type(self):
"""Only matches specified component types."""
- t = Enabled(False, names={"foo"}, components={"prompt"})
+ t = Visibility(False, names={"foo"}, components={"prompt"})
# Tool has key "tool:foo@", not "prompt:foo@"
assert t._matches(Tool(name="foo", parameters={})) is False
def test_all_criteria_must_match(self):
"""Multiple criteria use AND logic - all must match."""
- t = Enabled(
+ t = Visibility(
False,
names={"foo"},
version=VersionSpec(eq="v1"),
@@ -96,26 +96,26 @@ def test_all_criteria_must_match(self):
class TestMarking:
- """Test enabled state marking."""
+ """Test visibility state marking."""
def test_disable_marks_as_disabled(self):
- """Enabled(False, ...) marks matching components as disabled."""
+ """Visibility(False, ...) marks matching components as disabled."""
tool = Tool(name="foo", parameters={})
- Enabled(False, names={"foo"})._mark_component(tool)
+ Visibility(False, names={"foo"})._mark_component(tool)
assert is_enabled(tool) is False
def test_enable_marks_as_enabled(self):
- """Enabled(True, ...) marks matching components as enabled."""
+ """Visibility(True, ...) marks matching components as enabled."""
tool = Tool(name="foo", parameters={})
- Enabled(True, names={"foo"})._mark_component(tool)
+ Visibility(True, names={"foo"})._mark_component(tool)
assert is_enabled(tool) is True
assert tool.meta is not None
- assert tool.meta["fastmcp"]["_internal"]["enabled"] is True
+ assert tool.meta["fastmcp"]["_internal"]["visibility"] is True
def test_non_matching_unchanged(self):
"""Non-matching components are not modified."""
tool = Tool(name="bar", parameters={})
- Enabled(False, names={"foo"})._mark_component(tool)
+ Visibility(False, names={"foo"})._mark_component(tool)
# No _internal key added
assert tool.meta is None or "_internal" not in tool.meta.get("fastmcp", {})
assert is_enabled(tool) is True
@@ -123,13 +123,13 @@ def test_non_matching_unchanged(self):
def test_mutates_in_place(self):
"""Marking mutates the component in place."""
tool = Tool(name="foo", parameters={})
- result = Enabled(False, names={"foo"})._mark_component(tool)
+ result = Visibility(False, names={"foo"})._mark_component(tool)
assert result is tool
def test_disable_all(self):
"""match_all=True disables all components."""
tool = Tool(name="anything", parameters={})
- Enabled(False, match_all=True)._mark_component(tool)
+ Visibility(False, match_all=True)._mark_component(tool)
assert is_enabled(tool) is False
@@ -139,19 +139,19 @@ class TestOverride:
def test_enable_overrides_disable(self):
"""An enable after disable results in enabled."""
tool = Tool(name="foo", parameters={})
- Enabled(False, names={"foo"})._mark_component(tool)
+ Visibility(False, names={"foo"})._mark_component(tool)
assert is_enabled(tool) is False
- Enabled(True, names={"foo"})._mark_component(tool)
+ Visibility(True, names={"foo"})._mark_component(tool)
assert is_enabled(tool) is True
def test_disable_overrides_enable(self):
"""A disable after enable results in disabled."""
tool = Tool(name="foo", parameters={})
- Enabled(True, names={"foo"})._mark_component(tool)
+ Visibility(True, names={"foo"})._mark_component(tool)
assert is_enabled(tool) is True
- Enabled(False, names={"foo"})._mark_component(tool)
+ Visibility(False, names={"foo"})._mark_component(tool)
assert is_enabled(tool) is False
@@ -169,7 +169,7 @@ def test_filtering_pattern(self):
Tool(name="enabled", parameters={}),
Tool(name="disabled", parameters={}),
]
- Enabled(False, names={"disabled"})._mark_component(tools[1])
+ Visibility(False, names={"disabled"})._mark_component(tools[1])
visible = [t for t in tools if is_enabled(t)]
assert [t.name for t in visible] == ["enabled"]
@@ -181,7 +181,7 @@ class TestMetadata:
def test_internal_metadata_stripped_by_get_meta(self):
"""Internal metadata is stripped when calling get_meta()."""
tool = Tool(name="foo", parameters={})
- Enabled(True, names={"foo"})._mark_component(tool)
+ Visibility(True, names={"foo"})._mark_component(tool)
# Raw meta has _internal
assert tool.meta is not None
@@ -194,7 +194,7 @@ def test_internal_metadata_stripped_by_get_meta(self):
def test_user_metadata_preserved(self):
"""User-provided metadata is not affected."""
tool = Tool(name="foo", parameters={}, meta={"custom": "value"})
- marked = Enabled(False, names={"foo"})._mark_component(tool)
+ marked = Visibility(False, names={"foo"})._mark_component(tool)
assert marked.meta is not None
assert marked.meta["custom"] == "value"
@@ -205,24 +205,24 @@ class TestRepr:
def test_repr_disable(self):
"""Repr shows disable action and criteria."""
- t = Enabled(False, names={"foo"})
+ t = Visibility(False, names={"foo"})
r = repr(t)
assert "disable" in r
assert "foo" in r
def test_repr_enable(self):
"""Repr shows enable action."""
- t = Enabled(True, names={"foo"})
+ t = Visibility(True, names={"foo"})
assert "enable" in repr(t)
def test_repr_match_all(self):
"""Repr shows match_all."""
- t = Enabled(False, match_all=True)
+ t = Visibility(False, match_all=True)
assert "match_all=True" in repr(t)
class TestTransformChain:
- """Test Enabled in async transform chains."""
+ """Test Visibility in async transform chains."""
@pytest.fixture
def tools(self):
@@ -234,7 +234,7 @@ def tools(self):
async def test_list_tools_marks_matching(self, tools):
"""list_tools applies marks to matching components."""
- disable_internal = Enabled(False, tags=set({"internal"}))
+ disable_internal = Visibility(False, tags=set({"internal"}))
result = await disable_internal.list_tools(tools)
@@ -245,8 +245,8 @@ async def test_list_tools_marks_matching(self, tools):
async def test_later_transform_overrides(self, tools):
"""Later transforms in chain override earlier ones."""
- disable_internal = Enabled(False, tags=set({"internal"}))
- enable_safe = Enabled(True, tags=set({"safe"}))
+ disable_internal = Visibility(False, tags=set({"internal"}))
+ enable_safe = Visibility(True, tags=set({"safe"}))
# Apply transforms sequentially
after_disable = await disable_internal.list_tools(tools)
@@ -260,8 +260,8 @@ async def test_later_transform_overrides(self, tools):
async def test_allowlist_pattern(self, tools):
"""Disable all, then enable specific = allowlist."""
- disable_all = Enabled(False, match_all=True)
- enable_public = Enabled(True, tags=set({"public"}))
+ disable_all = Visibility(False, match_all=True)
+ enable_public = Visibility(True, tags=set({"public"}))
# Apply transforms sequentially
after_disable = await disable_all.list_tools(tools)