@tool
, @resource
, and @prompt
).
Why Are Methods Hard?
When you apply a FastMCP decorator like@tool
, @resource
, or @prompt
to a method, the decorator captures the function at decoration time. For instance methods and class methods, this poses a challenge because:
- For instance methods: The decorator gets the unbound method before any instance exists
- For class methods: The decorator gets the function before it’s bound to the class
self
or cls
that it cannot provide values for.
Additionally, FastMCP decorators return objects (Tool, Resource, or Prompt instances) rather than the original function. This means that when you decorate a method directly, the method becomes the returned object and is no longer callable by your code:
Don’t do this!The method will no longer be callable from Python, and the tool won’t be callable by LLMs.
Recommended Patterns
Instance Methods
Don’t do this!
self
as a required parameter, but it won’t know what to provide for it, causing errors or unexpected behavior.
Do this instead:
- You first create an instance of the class (
obj
) - When you access the method through the instance (
obj.add
), Python creates a bound method whereself
is already set to that instance - When you register this bound method, the system sees a callable that only expects the appropriate parameters, not
self
Class Methods
The behavior of decorating class methods depends on the order of decorators:Don’t do this (decorator order matters):
- If
@classmethod
comes first, then@mcp.tool
: No error is raised, but it won’t work correctly - If
@mcp.tool
comes first, then@classmethod
: FastMCP will detect this and raise a helpfulValueError
with guidance
Do this instead:
- The
@classmethod
decorator is applied properly during class definition - When you access
MyClass.from_string
, Python provides a special method object that automatically binds the class to thecls
parameter - When registered, only the appropriate parameters are exposed to the LLM, hiding the implementation detail of the
cls
parameter
Static Methods
Static methods “work” with FastMCP decorators, but this is not recommended because the FastMCP decorator will not return a callable method. Therefore, you should register static methods the same way as other methods.This is not recommended, though it will work.
@staticmethod
converts the method to a regular function, which the FastMCP decorator can then properly process. However, this is not recommended because the FastMCP decorator will not return a callable staticmethod. Therefore, you should register static methods the same way as other methods.
Prefer this pattern:
Additional Patterns
Creating Components at Class Initialization
You can automatically register instance methods when creating an object:- You want to encapsulate registration logic within the class itself
- You have multiple related components that should be registered together
- You want to ensure that methods are always properly registered when creating an instance
Summary
The current behavior of FastMCP decorators with methods is:- Static methods: Can be decorated directly and work perfectly with all FastMCP decorators
- Class methods: Cannot be decorated directly and will raise a helpful
ValueError
with guidance - Instance methods: Should be registered after creating an instance using the decorator calls