Skip to main content

fastmcp.server.extensions

FastMCP-native server extension API (SEP-2133). An MCP extension is an opt-in, capability-negotiated bundle of protocol behaviour identified by a reverse-DNS string (e.g. io.modelcontextprotocol/tasks). Unlike the SDK’s mcp.server.extension.Extension, a FastMCP ServerExtension is bound to its FastMCP instance at registration, so its request handlers and its tools/call interceptor can reach the component registry, Context, and auth scope that the SDK’s model withholds. An extension contributes any subset of four things:
  • A negotiated capability. settings() is spliced into ServerCapabilities.extensions[identifier] (see LowLevelServer.get_capabilities).
  • New request methods. methods() returns MethodBindings, each wired onto the low-level server via add_request_handler when the extension is registered.
  • A tools/call interceptor. intercept_tool_call() is the last gate before a tool body runs — it composes after the FastMCP middleware chain and before component execution, so it can observe, short-circuit, or pass a call through.
  • A lifespan. lifespan() is entered with the server’s lifespan and exited on shutdown — the hook the SDK’s Extension lacks, needed to start backends/workers.
The base class follows the SDK’s httpx-style shape: every contribution method has a default, so a subclass overrides only what it needs.

Functions

read_client_extension_settings

Read a client’s per-request extension opt-in from the request _meta. SEP-2133 extensions negotiate per request: the client repeats its extension capabilities in each request’s _meta under io.modelcontextprotocol/clientCapabilitiesextensionsidentifier. Returns the declared settings dict (possibly empty) when the extension was opted in for this request, or None when it was not.

build_method_handler

Wrap a MethodBinding into a low-level request handler. The adapter enforces protocol_versions gating (rejecting other versions as METHOD_NOT_FOUND, since add_request_handler registers unconditionally) and binds the FastMCP request context so the handler can use get_context(), auth, and other request-scoped dependencies.

wrap_tool_call_interceptor

Fold one extension’s intercept_tool_call around a middleware call_next. The returned wrapper is a FastMCP CallNext: it hands the extension the validated tools/call params, the FastMCP Context, and a zero-arg continuation that runs the rest of the chain and, finally, the tool body.

Classes

MethodBinding

A new request method an extension serves, e.g. tasks/get. params_type validates incoming params before handler runs; it should subclass RequestParams so _meta parses uniformly. protocol_versions, when set, restricts the method to those wire versions — a request at any other version is rejected as METHOD_NOT_FOUND, mirroring the spec’s (method, version) boundary. None (the default) admits every version. Extension methods are additive: method must not name a spec-defined request method (tools/call, completion/complete, …). Binding one would silently shadow the server’s own handler. Both constraints are enforced at construction.

ServerExtension

Base class for an opt-in FastMCP server extension (SEP-2133). Subclass, set identifier, and override the contribution methods that apply. Every method has a default, so a minimal extension overrides only identifier and one contribution. identifier is validated at subclass-definition time when set as a class attribute, and again at registration (which covers per-instance identifiers assigned in __init__). Register an instance with FastMCP.add_extension(...), which binds the extension to the server so self.server, intercept_tool_call, and method handlers can reach FastMCP-level constructs. Methods:

server

The FastMCP server this extension is registered on. Handlers, interceptors, and lifespan code reach the component registry, Context, and auth scope through here. Raises if the extension has not been registered with FastMCP.add_extension().

settings

Per-extension settings advertised at capabilities.extensions[identifier]. An empty dict (the default) advertises the extension with no settings.

methods

New request methods this extension serves (additive).

lifespan

A context manager entered with the server’s lifespan, exited on shutdown. Default: a no-op. Override to start and stop resources an extension owns (a task-queue backend and worker, say). Entered once per runtime tree, at the root — a mounted child defers to the root, as the shared Docket does.

intercept_tool_call

Wrap tools/call. Default: pass through unchanged. Runs after the FastMCP middleware chain and before the tool body, so it is the last gate before execution. Override to observe the call, to short-circuit (return a result without awaiting call_next), or to pass it through (return await call_next()). params is the validated tools/call params; context is the FastMCP Context, from which the tool being called (context.fastmcp.get_tool(params.name)), auth scope, and the server are reachable. Multiple extensions nest with the first-registered outermost.

client_settings

This extension’s per-request opt-in settings declared by the client. Reads the request’s _meta client-capabilities block. Returns the declared settings dict (possibly empty) when the client opted this extension in for the request, or None when it did not. Convenience for read_client_extension_settings(ctx, self.identifier).