The Context Object
How Do You Get a Context Object?
You add ctx, context, or any name you like to your tool function signature as a parameter with a default value. FastMCP uses dependency injection to provide it automatically:
from fastmcp import FastMCP
from fastmcp.dependencies import CurrentContext
from fastmcp.server.context import Context
mcp = FastMCP("my-server")
@mcp.tool()
async def my_tool(query: str, ctx: Context = CurrentContext()) -> str:
# ctx is injected by FastMCP — the client never passes it
await ctx.info(f"Searching for: {query}")
return f"Results for {query}"
The critical thing to understand: ctx is not a normal parameter. The client never passes it to the tool. It doesn't show up in the tool's schema. FastMCP injects it automatically at runtime, the same way a web framework injects a "request" object. From the client's point of view, my_tool takes one parameter: query.
Because
ctxmethods likeinfo(),set_state(), andreport_progress()areasync, you should declare your function withasync defwhen using context so you canawaitthem. That said, FastMCP does run synchronous tools in a thread pool with context propagation, so injecting and accessingContextfrom adeffunction is possible — but usingasync defgives you the most natural access pattern.
This same pattern works with tools, resources, and prompts. You are not limited to using context only inside tools:
from fastmcp import FastMCP
from fastmcp.dependenciesPractical MCP with FastMCP & LangChain
Engineering the Agentic ExperienceEnroll now to unlock current content and receive all future updates for free. Your purchase supports the author and fuels the creation of more exciting content. Act fast, as the price will rise as the course nears completion!
