3.0.0
Components can be dynamically enabled or disabled at runtime. A disabled tool disappears from listings and cannot be called. This enables runtime access control, feature flags, and context-aware component exposure.
Component Visibility
Every FastMCP server providesenable() and disable() methods for controlling component availability.
Disabling Components
Thedisable() method marks components as disabled. Disabled components are filtered out from all client queries.
Enabling Components
Theenable() method re-enables previously disabled components.
Keys and Tags
Visibility filtering works with two identifiers: keys (for specific components) and tags (for groups).Component Keys
Every component has a unique key in the format{type}:{identifier}.
| Component | Key Format | Example |
|---|---|---|
| Tool | tool:{name} | tool:delete_everything |
| Resource | resource:{uri} | resource:data://config |
| Template | template:{uri} | template:file://{path} |
| Prompt | prompt:{name} | prompt:analyze |
Tags
Tags group components for bulk operations. Define tags when creating components, then filter by them.Combining Keys and Tags
You can specify both keys and tags in a single call. The filters combine additively.Allowlist Mode
By default, visibility filtering uses blocklist mode: everything is enabled unless explicitly disabled. Theonly=True parameter switches to allowlist mode, where only specified components are enabled.
Allowlist Behavior
When you callenable(only=True):
- Default visibility state switches to “disabled”
- Previous allowlists are cleared
- Only specified keys/tags become enabled
Ordering and Overrides
Laterenable() and disable() calls override earlier ones. This lets you create broad rules with specific exceptions.
enable() call after it.
Server vs Provider
Visibility state operates at two levels: the server and individual providers.Server-Level
Server-level visibility state applies to all components from all providers. When you callmcp.enable() or mcp.disable(), you’re filtering the final view that clients see.
Provider-Level
Each provider can add its own visibility transforms. These run before server-level transforms, so the server can override provider-level disables.Layered Transforms
Provider transforms run first, then server transforms. Later transforms override earlier ones, so the server has final say.Per-Session Visibility
Server-level visibility changes affect all connected clients simultaneously. When you need different clients to see different components, use per-session visibility instead. Session visibility lets individual sessions customize their view of available components. When a tool callsctx.enable_components() or ctx.disable_components(), those rules apply only to the current session. Other sessions continue to see the global defaults. This enables patterns like progressive disclosure, role-based access, and on-demand feature activation.
premium_analysis hidden. When a session calls unlock_premium, that session gains access to premium tools while other sessions remain unaffected. Calling reset_features returns the session to the global defaults.
How Session Rules Work
Session rules override global transforms. When listing components, FastMCP first applies global enable/disable rules, then applies session-specific rules on top. Rules within a session accumulate, and later rules override earlier ones for the same component.dangerous_admin_tool ends up disabled because its disable rule was added after the admin enable rule.
Filter Criteria
The session visibility methods accept the same filter criteria asserver.enable() and server.disable():
| Parameter | Description |
|---|---|
names | Component names or URIs to match |
keys | Component keys (e.g., {"tool:my_tool"}) |
tags | Tags to match (component must have at least one) |
version | Version specification to match |
components | Component types ({"tool"}, {"resource"}, {"prompt"}, {"template"}) |
match_all | If True, matches all components regardless of other criteria |
Automatic Notifications
When session visibility changes, FastMCP automatically sends notifications to that session. Clients receiveToolListChangedNotification, ResourceListChangedNotification, and PromptListChangedNotification so they can refresh their component lists. These notifications go only to the affected session.
When you specify the components parameter, FastMCP optimizes by sending only the relevant notifications:
Namespace Activation Pattern
A common pattern organizes tools into namespaces using tag prefixes, disables them globally, then provides activation tools that unlock namespaces on demand:activate_finance reveals finance tools for that session only. Multiple namespaces can be activated independently, and deactivate_all returns to the initial state.
Method Reference
await ctx.enable_components(...) -> None: Enable matching components for this sessionawait ctx.disable_components(...) -> None: Disable matching components for this sessionawait ctx.reset_visibility() -> None: Clear all session rules, returning to global defaults
Client Notifications
When visibility state changes, FastMCP automatically notifies connected clients. Clients supporting the MCP notification protocol receivelist_changed events and can refresh their component lists.
This happens automatically. You don’t need to trigger notifications manually.
Filtering Logic
Understanding the filtering logic helps when debugging visibility state issues. Theis_enabled() function checks a component’s internal metadata:
- If the component has
meta.fastmcp._internal.visibility = False, it’s disabled - If the component has
meta.fastmcp._internal.visibility = True, it’s enabled - If no visibility state is set, the component is enabled by default
enable() and disable() calls are made, transforms are applied in order. Later transforms override earlier ones, so the last matching transform wins.
The Visibility Transform
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.
enable() can re-enable it.
