mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-20 04:24:17 +02:00
Add storage backend documentation (#2137)
* Add storage backend documentation * Add storage patterns documentation for wrapper caching strategies - Add PassthroughCacheWrapper section for multi-tier caching - Document TTL clamping strategy for optimized memory usage - Add example for wrapping custom storage implementations - Explain how to combine fast in-memory caches with persistent remote stores * Update docs
This commit is contained in:
parent
96aa150cf0
commit
b362444ddf
12 changed files with 322 additions and 18 deletions
|
|
@ -3,7 +3,6 @@ title: User Elicitation
|
|||
sidebarTitle: Elicitation
|
||||
description: Handle server-initiated user input requests with structured schemas.
|
||||
icon: message-question
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx";
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ title: Upgrade Guide
|
|||
sidebarTitle: Upgrade Guide
|
||||
description: Migration instructions for upgrading between FastMCP versions
|
||||
icon: up
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
This guide provides migration instructions for breaking changes and major updates when upgrading between FastMCP versions.
|
||||
|
|
|
|||
|
|
@ -107,15 +107,16 @@
|
|||
"group": "Advanced Features",
|
||||
"icon": "stars",
|
||||
"pages": [
|
||||
"servers/icons",
|
||||
"servers/context",
|
||||
"servers/proxy",
|
||||
"servers/composition",
|
||||
"servers/context",
|
||||
"servers/elicitation",
|
||||
"servers/icons",
|
||||
"servers/logging",
|
||||
"servers/middleware",
|
||||
"servers/progress",
|
||||
"servers/proxy",
|
||||
"servers/sampling",
|
||||
"servers/middleware"
|
||||
"servers/storage-backends"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ title: Authentication
|
|||
sidebarTitle: Overview
|
||||
description: Secure your FastMCP server with flexible authentication patterns, from simple API keys to full OAuth 2.1 integration with external identity providers.
|
||||
icon: user-shield
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ title: Full OAuth Server
|
|||
sidebarTitle: Full OAuth Server
|
||||
description: Build a self-contained authentication system where your FastMCP server manages users, issues tokens, and validates them.
|
||||
icon: users-between-lines
|
||||
tag: NEW
|
||||
|
||||
---
|
||||
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx"
|
||||
|
|
|
|||
|
|
@ -210,16 +210,34 @@ These parameters are included in all token requests to the upstream provider.
|
|||
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="client_storage" type="KVStorage | None">
|
||||
<ParamField body="client_storage" type="AsyncKeyValue | None">
|
||||
Storage backend for persisting OAuth client registrations and encrypted upstream tokens. By default, clients are automatically persisted to disk in `~/.config/fastmcp/oauth-proxy-clients/`, allowing them to survive server restarts as long as the filesystem remains accessible. This means MCP clients only need to register once and can reconnect seamlessly after your server restarts.
|
||||
|
||||
For production deployments with token persistence, use this with `jwt_signing_key` and `token_encryption_key` - all three work together to ensure tokens survive restarts. See [OAuth Token Security](/deployment/http#oauth-token-security).
|
||||
For production deployments with multiple servers or cloud deployments, see [Storage Backends](/servers/storage-backends) for options including Redis, DynamoDB, and custom implementations.
|
||||
|
||||
For production token persistence, use this with `jwt_signing_key` and `token_encryption_key` - all three work together to ensure tokens survive restarts. See [OAuth Token Security](/deployment/http#oauth-token-security).
|
||||
|
||||
Testing with in-memory storage:
|
||||
|
||||
```python
|
||||
from fastmcp.utilities.storage import InMemoryStorage
|
||||
from key_value.aio.stores.memory import MemoryStore
|
||||
|
||||
# Use in-memory storage for testing (clients lost on restart)
|
||||
auth = OAuthProxy(..., client_storage=InMemoryStorage())
|
||||
auth = OAuthProxy(..., client_storage=MemoryStore())
|
||||
```
|
||||
|
||||
Production with Redis for distributed deployments:
|
||||
|
||||
```python
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
import os
|
||||
|
||||
auth = OAuthProxy(
|
||||
...,
|
||||
jwt_signing_key=os.environ["JWT_SIGNING_KEY"],
|
||||
token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"],
|
||||
client_storage=RedisStore(host="redis.example.com", port=6379)
|
||||
)
|
||||
```
|
||||
|
||||
</ParamField>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ title: Token Verification
|
|||
sidebarTitle: Token Verification
|
||||
description: Protect your server by validating bearer tokens issued by external systems.
|
||||
icon: key
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Server Composition
|
||||
sidebarTitle: Server Composition
|
||||
sidebarTitle: Composition
|
||||
description: Combine multiple FastMCP servers into a single, larger application using mounting and importing.
|
||||
icon: puzzle-piece
|
||||
---
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ title: User Elicitation
|
|||
sidebarTitle: Elicitation
|
||||
description: Request structured input from users during tool execution through the MCP context.
|
||||
icon: message-question
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from '/snippets/version-badge.mdx'
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
title: Icons
|
||||
description: Add visual icons to your servers, tools, resources, and prompts
|
||||
icon: image
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from '/snippets/version-badge.mdx'
|
||||
|
|
|
|||
|
|
@ -461,9 +461,9 @@ from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
|||
mcp.add_middleware(ResponseCachingMiddleware())
|
||||
```
|
||||
|
||||
Out of the box, it caches call/list tool, resources, and prompts to an in-memory cache. Sending a notification of a tool/resource/prompt change will invalidate the cache for the affected method. List calls are stored under global keys, if you share a key_value backend across servers, keep this in mind and consider using the PrefixCollectionsWrapper in py-key-value-aio to namespace collections by server.
|
||||
Out of the box, it caches call/list tool, resources, and prompts to an in-memory cache with TTL-based expiration. Cache entries expire based on their TTL; there is no event-based cache invalidation. List calls are stored under global keys—when sharing a storage backend across multiple servers, consider namespacing collections to prevent conflicts. See [Storage Backends](/servers/storage-backends) for advanced configuration options.
|
||||
|
||||
Each method can be configured individually, for example, caching list tools for 30 seconds, skipping caching for tools other than `tool1` and not caching and requests to read resources:
|
||||
Each method can be configured individually, for example, caching list tools for 30 seconds, limiting caching to specific tools, and disabling caching for resource reads:
|
||||
|
||||
```python
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware, CallToolSettings, ListToolsSettings, ReadResourceSettings
|
||||
|
|
@ -481,7 +481,11 @@ mcp.add_middleware(ResponseCachingMiddleware(
|
|||
))
|
||||
```
|
||||
|
||||
It can also be configured to cache to disk:
|
||||
#### Storage Backends
|
||||
|
||||
By default, caching uses in-memory storage, which is fast but doesn't persist across restarts. For production or persistent caching across server restarts, configure a different storage backend. See [Storage Backends](/servers/storage-backends) for complete options including disk, Redis, DynamoDB, and custom implementations.
|
||||
|
||||
Disk-based caching example:
|
||||
|
||||
```python
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
|
|
@ -492,7 +496,31 @@ mcp.add_middleware(ResponseCachingMiddleware(
|
|||
))
|
||||
```
|
||||
|
||||
See the Contrib modules for caching middleware implementations that support additional features like distributed caching.
|
||||
Redis for distributed deployments:
|
||||
|
||||
```python
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
|
||||
mcp.add_middleware(ResponseCachingMiddleware(
|
||||
cache_storage=RedisStore(host="redis.example.com", port=6379),
|
||||
))
|
||||
```
|
||||
|
||||
#### Cache Statistics
|
||||
|
||||
The caching middleware collects operation statistics (hits, misses, etc.) through the underlying storage layer. Access statistics from the middleware instance:
|
||||
|
||||
```python
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
|
||||
middleware = ResponseCachingMiddleware()
|
||||
mcp.add_middleware(middleware)
|
||||
|
||||
# Later, retrieve statistics
|
||||
stats = middleware.statistics()
|
||||
print(f"Total cache operations: {stats}")
|
||||
```
|
||||
|
||||
### Logging Middleware
|
||||
|
||||
|
|
|
|||
259
docs/servers/storage-backends.mdx
Normal file
259
docs/servers/storage-backends.mdx
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
---
|
||||
title: Storage Backends
|
||||
sidebarTitle: Storage Backends
|
||||
description: Configure persistent and distributed storage for caching and OAuth state management
|
||||
icon: database
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx"
|
||||
|
||||
<VersionBadge version="2.13.0" />
|
||||
|
||||
FastMCP uses pluggable storage backends for caching responses and managing OAuth state. By default, all storage is in-memory, which is perfect for development but doesn't persist across restarts. FastMCP includes support for multiple storage backends, and you can easily extend it with custom implementations.
|
||||
|
||||
<Tip>
|
||||
The storage layer is powered by **[py-key-value-aio](https://github.com/strawgate/py-key-value)**, an async key-value library maintained by a core FastMCP maintainer. This library provides a unified interface for multiple backends, making it easy to swap implementations based on your deployment needs.
|
||||
</Tip>
|
||||
|
||||
## Available Backends
|
||||
|
||||
### In-Memory Storage
|
||||
|
||||
**Best for:** Development, testing, single-process deployments
|
||||
|
||||
In-memory storage is the default for all FastMCP storage needs. It's fast, requires no setup, and is perfect for getting started.
|
||||
|
||||
```python
|
||||
from key_value.aio.stores.memory import MemoryStore
|
||||
|
||||
# Used by default - no configuration needed
|
||||
# But you can also be explicit:
|
||||
cache_store = MemoryStore()
|
||||
```
|
||||
|
||||
**Characteristics:**
|
||||
- ✅ No setup required
|
||||
- ✅ Very fast
|
||||
- ❌ Data lost on restart
|
||||
- ❌ Not suitable for multi-process deployments
|
||||
|
||||
### Disk Storage
|
||||
|
||||
**Best for:** Single-server production deployments, persistent caching
|
||||
|
||||
Disk storage persists data to the filesystem, allowing it to survive server restarts.
|
||||
|
||||
```python
|
||||
from key_value.aio.stores.disk import DiskStore
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
|
||||
# Persistent response cache
|
||||
middleware = ResponseCachingMiddleware(
|
||||
cache_storage=DiskStore(directory="/var/cache/fastmcp")
|
||||
)
|
||||
```
|
||||
|
||||
Or with OAuth token storage:
|
||||
|
||||
```python
|
||||
from fastmcp.server.auth.providers.github import GitHubProvider
|
||||
from key_value.aio.stores.disk import DiskStore
|
||||
|
||||
auth = GitHubProvider(
|
||||
client_id="your-id",
|
||||
client_secret="your-secret",
|
||||
base_url="https://your-server.com",
|
||||
client_storage=DiskStore(directory="/var/lib/fastmcp/oauth")
|
||||
)
|
||||
```
|
||||
|
||||
**Characteristics:**
|
||||
- ✅ Data persists across restarts
|
||||
- ✅ Good performance for moderate load
|
||||
- ❌ Not suitable for distributed deployments
|
||||
- ❌ Filesystem access required
|
||||
|
||||
### Redis
|
||||
|
||||
**Best for:** Distributed production deployments, shared caching across multiple servers
|
||||
|
||||
<Note>
|
||||
Redis support requires an optional dependency: `pip install 'py-key-value-aio[redis]'`
|
||||
</Note>
|
||||
|
||||
Redis provides distributed caching and state management, ideal for production deployments with multiple server instances.
|
||||
|
||||
```python
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
|
||||
# Distributed response cache
|
||||
middleware = ResponseCachingMiddleware(
|
||||
cache_storage=RedisStore(host="redis.example.com", port=6379)
|
||||
)
|
||||
```
|
||||
|
||||
With authentication:
|
||||
|
||||
```python
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
|
||||
cache_store = RedisStore(
|
||||
host="redis.example.com",
|
||||
port=6379,
|
||||
password="your-redis-password"
|
||||
)
|
||||
```
|
||||
|
||||
For OAuth token storage:
|
||||
|
||||
```python
|
||||
import os
|
||||
from fastmcp.server.auth.providers.github import GitHubProvider
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
|
||||
auth = GitHubProvider(
|
||||
client_id=os.environ["GITHUB_CLIENT_ID"],
|
||||
client_secret=os.environ["GITHUB_CLIENT_SECRET"],
|
||||
base_url="https://your-server.com",
|
||||
jwt_signing_key=os.environ["JWT_SIGNING_KEY"],
|
||||
token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"],
|
||||
client_storage=RedisStore(host="redis.example.com", port=6379)
|
||||
)
|
||||
```
|
||||
|
||||
**Characteristics:**
|
||||
- ✅ Distributed and highly available
|
||||
- ✅ Fast in-memory performance
|
||||
- ✅ Works across multiple server instances
|
||||
- ✅ Built-in TTL support
|
||||
- ❌ Requires Redis infrastructure
|
||||
- ❌ Network latency vs local storage
|
||||
|
||||
### Other Backends from py-key-value-aio
|
||||
|
||||
The py-key-value-aio library includes additional implementations for various storage systems:
|
||||
|
||||
- **DynamoDB** - AWS distributed database
|
||||
- **MongoDB** - NoSQL document store
|
||||
- **Elasticsearch** - Distributed search and analytics
|
||||
- **Memcached** - Distributed memory caching
|
||||
- **RocksDB** - Embedded high-performance key-value store
|
||||
- **Valkey** - Redis-compatible server
|
||||
|
||||
For configuration details on these backends, consult the [py-key-value-aio documentation](https://github.com/strawgate/py-key-value-aio).
|
||||
|
||||
## Use Cases in FastMCP
|
||||
|
||||
### Server-Side OAuth Token Storage
|
||||
|
||||
The [OAuth Proxy](/servers/auth/oauth-proxy) and OAuth auth providers use storage for persisting OAuth client registrations and encrypted upstream tokens. By default, registrations are stored in memory:
|
||||
|
||||
```python
|
||||
# In-memory storage (default behavior - lost on restart)
|
||||
from fastmcp.server.auth.providers.github import GitHubProvider
|
||||
|
||||
auth = GitHubProvider(
|
||||
client_id="your-id",
|
||||
client_secret="your-secret",
|
||||
base_url="https://your-server.com"
|
||||
)
|
||||
```
|
||||
|
||||
For production with token persistence across restarts, configure persistent storage and encryption keys:
|
||||
|
||||
```python
|
||||
import os
|
||||
from fastmcp.server.auth.providers.github import GitHubProvider
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
|
||||
auth = GitHubProvider(
|
||||
client_id=os.environ["GITHUB_CLIENT_ID"],
|
||||
client_secret=os.environ["GITHUB_CLIENT_SECRET"],
|
||||
base_url="https://your-server.com",
|
||||
# Token encryption and signing keys
|
||||
jwt_signing_key=os.environ["JWT_SIGNING_KEY"],
|
||||
token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"],
|
||||
# Persistent distributed storage
|
||||
client_storage=RedisStore(host="redis.example.com", port=6379)
|
||||
)
|
||||
```
|
||||
|
||||
See [OAuth Token Security](/deployment/http#oauth-token-security) for complete production setup details.
|
||||
|
||||
### Response Caching Middleware
|
||||
|
||||
The [Response Caching Middleware](/servers/middleware#caching-middleware) caches tool calls, resource reads, and prompt requests. Storage configuration is passed via the `cache_storage` parameter:
|
||||
|
||||
```python
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
from key_value.aio.stores.disk import DiskStore
|
||||
|
||||
mcp = FastMCP("My Server")
|
||||
|
||||
# Cache to disk instead of memory
|
||||
mcp.add_middleware(ResponseCachingMiddleware(
|
||||
cache_storage=DiskStore(directory="cache")
|
||||
))
|
||||
```
|
||||
|
||||
For multi-server deployments sharing a Redis instance:
|
||||
|
||||
```python
|
||||
from fastmcp.server.middleware.caching import ResponseCachingMiddleware
|
||||
from key_value.aio.stores.redis import RedisStore
|
||||
from key_value.aio.wrappers.prefix_collections import PrefixCollectionsWrapper
|
||||
|
||||
base_store = RedisStore(host="redis.example.com")
|
||||
namespaced_store = PrefixCollectionsWrapper(
|
||||
key_value=base_store,
|
||||
prefix="my-server"
|
||||
)
|
||||
|
||||
middleware = ResponseCachingMiddleware(cache_storage=namespaced_store)
|
||||
```
|
||||
|
||||
### Client-Side OAuth Token Storage
|
||||
|
||||
The [FastMCP Client](/clients/client) uses storage for persisting OAuth tokens locally. By default, tokens are stored in memory:
|
||||
|
||||
```python
|
||||
from fastmcp.client.auth import OAuthClientProvider
|
||||
from key_value.aio.stores.disk import DiskStore
|
||||
|
||||
# Store tokens on disk for persistence across restarts
|
||||
token_storage = DiskStore(directory="~/.local/share/fastmcp/tokens")
|
||||
|
||||
oauth_provider = OAuthClientProvider(
|
||||
mcp_url="https://your-mcp-server.com/mcp/sse",
|
||||
token_storage=token_storage
|
||||
)
|
||||
```
|
||||
|
||||
This allows clients to reconnect without re-authenticating after restarts.
|
||||
|
||||
## Choosing a Backend
|
||||
|
||||
| Backend | Development | Single Server | Multi-Server | Cloud Native |
|
||||
|---------|-------------|---------------|--------------|--------------|
|
||||
| Memory | ✅ Best | ⚠️ Limited | ❌ | ❌ |
|
||||
| Disk | ✅ Good | ✅ Recommended | ❌ | ⚠️ |
|
||||
| Redis | ⚠️ Overkill | ✅ Good | ✅ Best | ✅ Best |
|
||||
| DynamoDB | ❌ | ⚠️ | ✅ | ✅ Best (AWS) |
|
||||
| MongoDB | ❌ | ⚠️ | ✅ | ✅ Good |
|
||||
|
||||
**Decision tree:**
|
||||
|
||||
1. **Just starting?** Use **Memory** (default) - no configuration needed
|
||||
2. **Single server, needs persistence?** Use **Disk**
|
||||
3. **Multiple servers or cloud deployment?** Use **Redis** or **DynamoDB**
|
||||
4. **Existing infrastructure?** Look for a matching py-key-value-aio backend
|
||||
|
||||
## More Resources
|
||||
|
||||
- [py-key-value-aio GitHub](https://github.com/strawgate/py-key-value-aio) - Full library documentation
|
||||
- [Response Caching Middleware](/servers/middleware#caching-middleware) - Using storage for caching
|
||||
- [OAuth Token Security](/deployment/http#oauth-token-security) - Production OAuth configuration
|
||||
- [HTTP Deployment](/deployment/http) - Complete deployment guide
|
||||
Loading…
Add table
Add a link
Reference in a new issue