Feedback

Chat Icon

Practical MCP with FastMCP & LangChain

Engineering the Agentic Experience

The Context Object
51%

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 ctx methods like info(), set_state(), and report_progress() are async, you should declare your function with async def when using context so you can await them. That said, FastMCP does run synchronous tools in a thread pool with context propagation, so injecting and accessing Context from a def function is possible — but using async def gives 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.dependencies

Practical MCP with FastMCP & LangChain

Engineering the Agentic Experience

Enroll 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!