From d5f01dae157d5ddd06d51aed452a3f8fcfe85afd Mon Sep 17 00:00:00 2001 From: William Easton Date: Wed, 17 Sep 2025 19:46:15 -0500 Subject: [PATCH] Add docs --- docs/servers/middleware.mdx | 41 ++++++++++++++++++++++++ src/fastmcp/server/middleware/caching.py | 30 ++++++++++++++--- tests/server/middleware/test_caching.py | 2 +- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/docs/servers/middleware.mdx b/docs/servers/middleware.mdx index 5ef8d8fe1..fd9f88e4c 100644 --- a/docs/servers/middleware.mdx +++ b/docs/servers/middleware.mdx @@ -442,6 +442,47 @@ mcp.add_middleware(DetailedTimingMiddleware()) The built-in versions include custom logger support, proper formatting, and **DetailedTimingMiddleware** provides operation-specific hooks like `on_call_tool` and `on_read_resource` for granular timing. +### Caching Middleware + +Caching middleware is essential for improving performance and reducing server load. FastMCP provides caching middleware at `fastmcp.server.middleware.caching`. + +Here's how to use the full version: + +```python +from fastmcp.server.middleware.caching import ResponseCachingMiddleware + +mcp.add_middleware(ResponseCachingMiddleware()) +``` + +Out of the box, it caches call/list tool, resources, and prompts. Sending a notification of a tool/resource/prompt change will invalidate the cache for the affected method. + +Alternatively, it can be configured to only cache specific methods, for example, only caching list tools and only caching calls to `tool1`: + +```python +from fastmcp.server.middleware.caching import ResponseCachingMiddleware + +mcp.add_middleware(ResponseCachingMiddleware( + method_settings=MethodSettings( + call_tool=CallToolSettings( + included_tools=["tool1"], + ), + list_tools=ListToolsSettings( + ttl=30, + ) + ) +)) +``` + +It can also be configured to cache to disk: + +```python +from fastmcp.server.middleware.caching import ResponseCachingMiddleware, DiskCache + +mcp.add_middleware(ResponseCachingMiddleware( + cache_backend=DiskCache(path="cache"), +)) +``` + ### Logging Middleware Request and response logging is crucial for debugging, monitoring, and understanding usage patterns in your MCP server. FastMCP provides comprehensive logging middleware at `fastmcp.server.middleware.logging`. diff --git a/src/fastmcp/server/middleware/caching.py b/src/fastmcp/server/middleware/caching.py index 7cb285393..03626b7fc 100644 --- a/src/fastmcp/server/middleware/caching.py +++ b/src/fastmcp/server/middleware/caching.py @@ -314,6 +314,18 @@ class SharedMethodSettings(TypedDict): ttl: NotRequired[int] +class ListToolsSettings(SharedMethodSettings): + pass + + +class ListResourcesSettings(SharedMethodSettings): + pass + + +class ListPromptsSettings(SharedMethodSettings): + pass + + class CallToolSettings(SharedMethodSettings): """Extra configuration options for Tool-related caching.""" @@ -321,17 +333,25 @@ class CallToolSettings(SharedMethodSettings): excluded_tools: NotRequired[list[str]] +class ReadResourceSettings(SharedMethodSettings): + pass + + +class GetPromptSettings(SharedMethodSettings): + pass + + class MethodSettings(TypedDict): """Config for the response caching middleware methods.""" - list_tools: NotRequired[SharedMethodSettings] + list_tools: NotRequired[ListToolsSettings] call_tool: NotRequired[CallToolSettings] - list_resources: NotRequired[SharedMethodSettings] - read_resource: NotRequired[SharedMethodSettings] + list_resources: NotRequired[ListResourcesSettings] + read_resource: NotRequired[ReadResourceSettings] - list_prompts: NotRequired[SharedMethodSettings] - get_prompt: NotRequired[SharedMethodSettings] + list_prompts: NotRequired[ListPromptsSettings] + get_prompt: NotRequired[GetPromptSettings] MethodSettingsType = TypeVar("MethodSettingsType", bound=SharedMethodSettings) diff --git a/tests/server/middleware/test_caching.py b/tests/server/middleware/test_caching.py index 4da0067bc..346d9a061 100644 --- a/tests/server/middleware/test_caching.py +++ b/tests/server/middleware/test_caching.py @@ -493,7 +493,7 @@ class TestResponseCachingMiddleware: cache = InMemoryCache() middleware = ResponseCachingMiddleware(cache, max_item_size=100) - result = await middleware._store_in_cache_and_return( + await middleware._store_in_cache_and_return( context=MiddlewareContext( method="tools/call", message=mcp.types.CallToolRequestParams(name="test_tool"),