Skip to content

Commit 0dd649a

Browse files
refactor: move standard tool filters to dedicated tool_filters module
- Create tool_filters.py with all constants, config args, and public filter functions - Define constants for config names, env vars, HTTP headers, and annotation keys - Move STANDARD_CONFIG_ARGS and STANDARD_TOOL_FILTERS to tool_filters.py - Rename middleware.py to _middleware.py to hide from public API - Update __init__.py exports to include new public symbols - Remove ToolFilterMiddleware from public exports (implementation detail) - Update tests to import from correct modules Co-Authored-By: AJ Steers <aj@airbyte.io>
1 parent 2612978 commit 0dd649a

6 files changed

Lines changed: 425 additions & 288 deletions

File tree

src/fastmcp_extensions/__init__.py

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Prompt text retrieval helpers
1212
"""
1313

14+
from fastmcp_extensions._middleware import ToolFilterFn
1415
from fastmcp_extensions.annotations import (
1516
DESTRUCTIVE_HINT,
1617
IDEMPOTENT_HINT,
@@ -22,10 +23,6 @@
2223
mcp_resource,
2324
mcp_tool,
2425
)
25-
from fastmcp_extensions.middleware import (
26-
ToolFilterFn,
27-
ToolFilterMiddleware,
28-
)
2926
from fastmcp_extensions.registration import (
3027
PromptDef,
3128
ResourceDef,
@@ -34,23 +31,71 @@
3431
register_mcp_tools,
3532
)
3633
from fastmcp_extensions.server import (
34+
MCPServerConfig,
35+
MCPServerConfigArg,
36+
get_mcp_config,
37+
mcp_server,
38+
)
39+
from fastmcp_extensions.tool_filters import (
40+
# Constants - Annotation Keys
41+
ANNOTATION_DESTRUCTIVE_HINT,
42+
ANNOTATION_MCP_MODULE,
43+
ANNOTATION_READ_ONLY_HINT,
44+
# Constants - Config Names
45+
CONFIG_EXCLUDE_MODULES,
46+
CONFIG_EXCLUDE_TOOLS,
47+
CONFIG_INCLUDE_MODULES,
48+
CONFIG_NO_DESTRUCTIVE_TOOLS,
49+
CONFIG_READONLY_MODE,
50+
# Constants - Environment Variables
51+
ENV_EXCLUDE_MODULES,
52+
ENV_EXCLUDE_TOOLS,
53+
ENV_INCLUDE_MODULES,
54+
ENV_NO_DESTRUCTIVE_TOOLS,
55+
ENV_READONLY_MODE,
56+
# Config Args
3757
EXCLUDE_MODULES_CONFIG_ARG,
3858
EXCLUDE_TOOLS_CONFIG_ARG,
59+
# Constants - HTTP Headers
60+
HEADER_EXCLUDE_MODULES,
61+
HEADER_EXCLUDE_TOOLS,
62+
HEADER_INCLUDE_MODULES,
63+
HEADER_NO_DESTRUCTIVE_TOOLS,
64+
HEADER_READONLY_MODE,
3965
INCLUDE_MODULES_CONFIG_ARG,
4066
NO_DESTRUCTIVE_TOOLS_CONFIG_ARG,
4167
READONLY_MODE_CONFIG_ARG,
4268
STANDARD_CONFIG_ARGS,
4369
STANDARD_TOOL_FILTERS,
44-
MCPServerConfig,
45-
MCPServerConfigArg,
46-
get_mcp_config,
47-
mcp_server,
70+
# Filter Functions
71+
module_filter,
72+
no_destructive_tools_filter,
73+
readonly_mode_filter,
74+
tool_exclusion_filter,
4875
)
4976

5077
__all__ = [
78+
"ANNOTATION_DESTRUCTIVE_HINT",
79+
"ANNOTATION_MCP_MODULE",
80+
"ANNOTATION_READ_ONLY_HINT",
81+
"CONFIG_EXCLUDE_MODULES",
82+
"CONFIG_EXCLUDE_TOOLS",
83+
"CONFIG_INCLUDE_MODULES",
84+
"CONFIG_NO_DESTRUCTIVE_TOOLS",
85+
"CONFIG_READONLY_MODE",
5186
"DESTRUCTIVE_HINT",
87+
"ENV_EXCLUDE_MODULES",
88+
"ENV_EXCLUDE_TOOLS",
89+
"ENV_INCLUDE_MODULES",
90+
"ENV_NO_DESTRUCTIVE_TOOLS",
91+
"ENV_READONLY_MODE",
5292
"EXCLUDE_MODULES_CONFIG_ARG",
5393
"EXCLUDE_TOOLS_CONFIG_ARG",
94+
"HEADER_EXCLUDE_MODULES",
95+
"HEADER_EXCLUDE_TOOLS",
96+
"HEADER_INCLUDE_MODULES",
97+
"HEADER_NO_DESTRUCTIVE_TOOLS",
98+
"HEADER_READONLY_MODE",
5499
"IDEMPOTENT_HINT",
55100
"INCLUDE_MODULES_CONFIG_ARG",
56101
"NO_DESTRUCTIVE_TOOLS_CONFIG_ARG",
@@ -64,13 +109,16 @@
64109
"PromptDef",
65110
"ResourceDef",
66111
"ToolFilterFn",
67-
"ToolFilterMiddleware",
68112
"get_mcp_config",
69113
"mcp_prompt",
70114
"mcp_resource",
71115
"mcp_server",
72116
"mcp_tool",
117+
"module_filter",
118+
"no_destructive_tools_filter",
119+
"readonly_mode_filter",
73120
"register_mcp_prompts",
74121
"register_mcp_resources",
75122
"register_mcp_tools",
123+
"tool_exclusion_filter",
76124
]
Lines changed: 7 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,14 @@
11
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2-
"""MCP Middleware for dynamic tool filtering.
2+
"""Internal module for tool filtering implementation.
33
4-
This module provides middleware for filtering MCP tools on a per-request basis,
5-
allowing different clients to see different tools based on their HTTP headers
6-
or other request-specific context.
4+
This is a private module that provides the internal implementation for
5+
per-request tool filtering. Users should not import from this module directly.
76
8-
## Key Components
7+
For tool filtering, use the `mcp_server()` function with `tool_filters` or
8+
`include_standard_tool_filters` parameters instead.
99
10-
- `ToolFilterMiddleware`: Middleware that filters tools based on a callable
11-
- `ToolFilterFn`: Type alias for tool filter functions
12-
13-
## Basic Usage
14-
15-
The simplest way to use tool filtering is with the standard filters:
16-
17-
```py
18-
from fastmcp_extensions import mcp_server
19-
20-
app = mcp_server(
21-
name="my-server",
22-
include_standard_tool_filters=True,
23-
)
24-
```
25-
26-
This automatically adds:
27-
- `readonly_mode`: When MCP_READONLY_MODE=1 or X-MCP-Readonly-Mode: true,
28-
only tools with readOnlyHint=True are visible
29-
- `no_destructive_tools`: When MCP_NO_DESTRUCTIVE_TOOLS=1 or X-No-Destructive-Tools: true,
30-
tools with destructiveHint=True are hidden
31-
32-
## Custom Filters
33-
34-
For custom filtering logic, create your own filter functions:
35-
36-
```py
37-
from fastmcp_extensions import mcp_server, get_mcp_config, MCPServerConfigArg
38-
39-
40-
def my_custom_filter(tool, app):
41-
if get_mcp_config(app, "my_config") == "1":
42-
# Custom filtering logic
43-
return tool.name.startswith("allowed_")
44-
return True
45-
46-
47-
app = mcp_server(
48-
name="my-server",
49-
server_config_args=[
50-
MCPServerConfigArg(
51-
name="my_config",
52-
http_header_key="X-My-Config",
53-
env_var="MY_CONFIG",
54-
default="0",
55-
),
56-
],
57-
tool_filters=[my_custom_filter],
58-
)
59-
```
10+
See Also:
11+
- FastMCP middleware documentation: https://gofastmcp.com/servers/middleware
6012
"""
6113

6214
from __future__ import annotations

0 commit comments

Comments
 (0)