mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-22 05:24:18 +02:00
Refactor visibility to mark-based enabled system
Rename Visibility to Enabled, collapse VisibilityRule into the transform, and move enabled filtering from Provider to Server level so server-level transforms can override provider-level disables.
This commit is contained in:
parent
2eac7ab1d1
commit
50ba6ea5a4
41 changed files with 1378 additions and 2043 deletions
160
docs/python-sdk/fastmcp-server-transforms-enabled.mdx
Normal file
160
docs/python-sdk/fastmcp-server-transforms-enabled.mdx
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
---
|
||||
title: enabled
|
||||
sidebarTitle: enabled
|
||||
---
|
||||
|
||||
# `fastmcp.server.transforms.enabled`
|
||||
|
||||
|
||||
Enabled transform for marking component enabled state.
|
||||
|
||||
This module provides the `Enabled` class which marks components with enabled/disabled
|
||||
state using metadata. Multiple Enabled transforms can be stacked - later transforms
|
||||
override earlier ones. Final filtering happens at the Provider level.
|
||||
|
||||
|
||||
## Classes
|
||||
|
||||
### `Enabled` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L40" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
|
||||
Sets enabled state on matching components.
|
||||
|
||||
Does NOT filter inline - just marks components with enabled state.
|
||||
Later transforms in the chain can override earlier marks.
|
||||
Final filtering happens at the Provider level after all transforms run.
|
||||
|
||||
Filtering logic (blocklist wins over allowlist):
|
||||
1. If component key is in _disabled_keys -> DISABLED
|
||||
2. If any component tag is in _disabled_tags -> DISABLED
|
||||
3. If _default_enabled is False and component not in allowlist -> DISABLED
|
||||
4. Otherwise -> ENABLED
|
||||
|
||||
Example usage:
|
||||
```python
|
||||
from fastmcp.server.transforms import Enabled
|
||||
|
||||
# Disable components tagged "internal"
|
||||
Enabled(False, tags=frozenset({"internal"}))
|
||||
|
||||
# Re-enable specific tool (override earlier disable)
|
||||
Enabled(True, name="safe_tool")
|
||||
|
||||
# Allowlist via composition:
|
||||
Enabled(False, match_all=True) # disable everything
|
||||
Enabled(True, tags=frozenset({"public"})) # enable public
|
||||
```
|
||||
|
||||
|
||||
**Methods:**
|
||||
|
||||
#### `__init__` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L61" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
__init__(self, enabled: bool, *, name: str | None = None, version: str | None = None, tags: frozenset[str] | None = None, components: frozenset[str] | None = None, match_all: bool = False) -> None
|
||||
```
|
||||
|
||||
Initialize an enabled marker.
|
||||
|
||||
**Args:**
|
||||
- `enabled`: If True, mark matching as enabled; if False, mark as disabled.
|
||||
- `name`: Component name to match.
|
||||
- `version`: Component version to match.
|
||||
- `tags`: Tags to match (component must have at least one).
|
||||
- `components`: Component types to match (e.g., frozenset({"tool", "prompt"})).
|
||||
- `match_all`: If True, matches all components regardless of other criteria.
|
||||
|
||||
|
||||
#### `list_tools` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L182" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
|
||||
```
|
||||
|
||||
Mark tools by enabled state.
|
||||
|
||||
|
||||
#### `get_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L187" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_tool(self, name: str, call_next: GetToolNext, *, version: VersionSpec | None = None) -> Tool | None
|
||||
```
|
||||
|
||||
Mark tool if found.
|
||||
|
||||
|
||||
#### `list_resources` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L200" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource]
|
||||
```
|
||||
|
||||
Mark resources by enabled state.
|
||||
|
||||
|
||||
#### `get_resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L205" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_resource(self, uri: str, call_next: GetResourceNext, *, version: VersionSpec | None = None) -> Resource | None
|
||||
```
|
||||
|
||||
Mark resource if found.
|
||||
|
||||
|
||||
#### `list_resource_templates` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L222" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate]
|
||||
```
|
||||
|
||||
Mark resource templates by enabled state.
|
||||
|
||||
|
||||
#### `get_resource_template` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L229" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext, *, version: VersionSpec | None = None) -> ResourceTemplate | None
|
||||
```
|
||||
|
||||
Mark resource template if found.
|
||||
|
||||
|
||||
#### `list_prompts` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L246" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt]
|
||||
```
|
||||
|
||||
Mark prompts by enabled state.
|
||||
|
||||
|
||||
#### `get_prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L251" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_prompt(self, name: str, call_next: GetPromptNext, *, version: VersionSpec | None = None) -> Prompt | None
|
||||
```
|
||||
|
||||
Mark prompt if found.
|
||||
|
||||
|
||||
## Functions
|
||||
|
||||
### `is_enabled` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/enabled.py#L261" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
is_enabled(component: FastMCPComponent) -> bool
|
||||
```
|
||||
|
||||
Check if component is enabled.
|
||||
|
||||
Returns True if:
|
||||
- No enabled mark exists (default is enabled)
|
||||
- Enabled mark is True
|
||||
|
||||
Returns False if enabled mark is False.
|
||||
|
||||
**Args:**
|
||||
- `component`: Component to check.
|
||||
|
||||
**Returns:**
|
||||
True if component should be enabled/visible to clients.
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
---
|
||||
title: visibility
|
||||
sidebarTitle: visibility
|
||||
---
|
||||
|
||||
# `fastmcp.server.transforms.visibility`
|
||||
|
||||
|
||||
Visibility transform for filtering components based on enable/disable settings.
|
||||
|
||||
This module provides the `Visibility` class which manages component visibility
|
||||
with blocklist and allowlist support. Components can be hidden by key or tag,
|
||||
and the visibility state is mutable - changes take effect on subsequent queries.
|
||||
|
||||
|
||||
## Classes
|
||||
|
||||
### `Visibility` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L43" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
|
||||
Filters components based on visibility settings.
|
||||
|
||||
Manages blocklist and allowlist logic for controlling component visibility.
|
||||
Both servers and providers use this class. Visibility is hierarchical: if a
|
||||
component is hidden at any level (provider or server), it's hidden to the client.
|
||||
|
||||
Filtering logic (blocklist wins over allowlist):
|
||||
1. If component key is in _disabled_keys → HIDDEN
|
||||
2. If any component tag is in _disabled_tags → HIDDEN
|
||||
3. If _default_enabled is False and component not in allowlist → HIDDEN
|
||||
4. Otherwise → VISIBLE
|
||||
|
||||
The `only=True` flag on enable() switches to allowlist mode:
|
||||
- Sets _default_enabled = False
|
||||
- Clears existing allowlists
|
||||
- Adds specified keys/tags to allowlist
|
||||
|
||||
|
||||
**Methods:**
|
||||
|
||||
#### `disable` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L120" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
disable(self) -> None
|
||||
```
|
||||
|
||||
Add to blocklist (hide components).
|
||||
|
||||
**Args:**
|
||||
- `keys`: Component keys to hide (e.g., "tool\:my_tool@", "resource\:file\://x@")
|
||||
- `tags`: Tags to hide - any component with these tags will be hidden
|
||||
|
||||
|
||||
#### `enable` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L148" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
enable(self) -> None
|
||||
```
|
||||
|
||||
Remove from blocklist, or set allowlist with only=True.
|
||||
|
||||
**Args:**
|
||||
- `keys`: Component keys to show
|
||||
- `tags`: Tags to show
|
||||
- `only`: If True, switches to allowlist mode - ONLY show these keys/tags.
|
||||
This sets default visibility to False, clears existing allowlists,
|
||||
and adds the specified keys/tags to the allowlist.
|
||||
|
||||
|
||||
#### `reset` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L202" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
reset(self) -> None
|
||||
```
|
||||
|
||||
Reset to default state (everything enabled, no filters).
|
||||
|
||||
|
||||
#### `is_enabled` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L221" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
is_enabled(self, component: FastMCPComponent) -> bool
|
||||
```
|
||||
|
||||
Check if component is enabled. Blocklist wins over allowlist.
|
||||
|
||||
|
||||
#### `list_tools` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L241" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
|
||||
```
|
||||
|
||||
Filter tools by visibility.
|
||||
|
||||
|
||||
#### `get_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L246" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
|
||||
```
|
||||
|
||||
Get tool if enabled, None otherwise.
|
||||
|
||||
|
||||
#### `list_resources` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L259" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource]
|
||||
```
|
||||
|
||||
Filter resources by visibility.
|
||||
|
||||
|
||||
#### `get_resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L264" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
|
||||
```
|
||||
|
||||
Get resource if enabled, None otherwise.
|
||||
|
||||
|
||||
#### `list_resource_templates` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L281" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate]
|
||||
```
|
||||
|
||||
Filter resource templates by visibility.
|
||||
|
||||
|
||||
#### `get_resource_template` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L288" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None
|
||||
```
|
||||
|
||||
Get resource template if enabled, None otherwise.
|
||||
|
||||
|
||||
#### `list_prompts` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L305" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt]
|
||||
```
|
||||
|
||||
Filter prompts by visibility.
|
||||
|
||||
|
||||
#### `get_prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/transforms/visibility.py#L310" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
||||
|
||||
```python
|
||||
get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None
|
||||
```
|
||||
|
||||
Get prompt if enabled, None otherwise.
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue