Inject runtime values like HTTP requests, access tokens, and custom dependencies into your MCP components.
FastMCP uses dependency injection to provide runtime values to your tools, resources, and prompts. Instead of passing context through every layer of your code, you declare what you need as parameter defaults—FastMCP resolves them automatically when your function runs.The dependency injection system is powered by Docket. Core DI features like Depends() and CurrentContext() work without installing Docket. For background tasks and advanced task-related dependencies, install fastmcp[tasks]. For comprehensive coverage of dependency patterns, see the Docket dependency documentation.
Dependency parameters are automatically excluded from the MCP schema—clients never see them as callable parameters. This separation keeps your function signatures clean while giving you access to the runtime context you need.
Dependency injection in FastMCP follows a simple pattern: declare a parameter with a recognized type annotation or a dependency default value, and FastMCP injects the resolved value at runtime.
When a client calls my_tool, they only see query as a parameter. The ctx parameter is injected automatically because it has a Context type annotation—FastMCP recognizes this and provides the active context for the request.This works identically for tools, resources, resource templates, and prompts.
Both approaches work identically. The type-annotation approach is more concise; the explicit CurrentContext() approach makes the dependency injection visible in the signature.
The MCP Context provides logging, progress reporting, resource access, and other request-scoped operations. See MCP Context for the full API.Dependency injection: Use a Context type annotation (FastMCP injects automatically) or CurrentContext():
New in version 2.2.11Access the Starlette Request when running over HTTP transports (SSE or Streamable HTTP).Dependency injection: Use CurrentRequest():
New in version 2.2.11Access HTTP headers with graceful fallback—returns an empty dictionary when no HTTP request is available, making it safe for code that might run over any transport.Dependency injection: Use CurrentHeaders():
New in version 2.11.0Access the authenticated user’s token when your server uses authentication.Dependency injection: Use CurrentAccessToken() (raises if not authenticated):
New in version 2.3.0For background task execution, FastMCP provides dependencies that integrate with Docket. These require installing fastmcp[tasks].
Copy
from fastmcp import FastMCPfrom fastmcp.dependencies import CurrentDocket, CurrentWorker, Progressmcp = FastMCP("Task Demo")@mcp.tool(task=True)async def long_running_task( data: str, docket=CurrentDocket(), worker=CurrentWorker(), progress=Progress(),) -> str: await progress.set_total(100) for i in range(100): # Process chunk... await progress.increment() await progress.set_message(f"Processing chunk {i + 1}") return "Complete"
CurrentDocket(): Access the Docket instance for scheduling additional background work
CurrentWorker(): Access the worker processing tasks (name, concurrency settings)
Progress(): Track task progress with atomic updates
Task dependencies require pip install 'fastmcp[tasks]'. They’re only available within task-enabled components (task=True). For comprehensive task patterns, see the Docket documentation.
Beyond the built-in dependencies, you can create your own to inject configuration, database connections, API clients, or any other values your functions need.
The Depends() function wraps any callable and injects its return value. This works with synchronous functions, async functions, and async context managers.
Copy
from fastmcp import FastMCPfrom fastmcp.dependencies import Dependsmcp = FastMCP("Custom Deps Demo")def get_config() -> dict: return {"api_url": "https://api.example.com", "timeout": 30}async def get_user_id() -> int: # Could fetch from database, external service, etc. return 42@mcp.toolasync def fetch_data( query: str, config: dict = Depends(get_config), user_id: int = Depends(get_user_id),) -> str: return f"User {user_id} fetching '{query}' from {config['api_url']}"
Dependencies are cached per-request. If multiple parameters use the same dependency, or if nested dependencies share a common dependency, it’s resolved once and the same instance is reused.
Copy
from fastmcp import FastMCPfrom fastmcp.dependencies import Dependsmcp = FastMCP("Caching Demo")def get_db_connection(): print("Connecting to database...") # Only printed once per request return {"connection": "active"}def get_user_repo(db=Depends(get_db_connection)): return {"db": db, "type": "user"}def get_order_repo(db=Depends(get_db_connection)): return {"db": db, "type": "order"}@mcp.toolasync def process_order( order_id: str, users=Depends(get_user_repo), orders=Depends(get_order_repo),) -> str: # Both repos share the same db connection return f"Processed order {order_id}"
For dependencies that need cleanup—database connections, file handles, HTTP clients—use an async context manager. The cleanup code runs after your function completes, even if an error occurs.
For advanced dependency patterns—like TaskArgument() for accessing task parameters, or custom Dependency subclasses—see the Docket dependency documentation.