PrefectHQ/fastmcp · error · TypeError
To decorate a classmethod, use @classmethod above @prompt. S
Error message
To decorate a classmethod, use @classmethod above @prompt. See https://gofastmcp.com/servers/prompts#using-with-methods
What it means
The `@prompt` decorator does not support decorating a `classmethod` object directly. If `name_or_fn` is a `classmethod`, a TypeError is raised pointing at the documented method-registration pattern.
Source
Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/decorators/prompts.py:156
Returns:
The registered FunctionPrompt or a decorator function.
Example:
```python
provider = LocalProvider()
@provider.prompt
def analyze(topic: str) -> list:
return [{"role": "user", "content": f"Analyze: {topic}"}]
@provider.prompt("custom_name")
def my_prompt(data: str) -> list:
return [{"role": "user", "content": data}]
```
"""
if isinstance(name_or_fn, classmethod):
raise TypeError(
"To decorate a classmethod, use @classmethod above @prompt. "
"See https://gofastmcp.com/servers/prompts#using-with-methods"
)
def decorate_and_register(
fn: AnyFunction, prompt_name: str | None
) -> FunctionPrompt | AnyFunction:
# Check for unbound method
try:
params = list(inspect.signature(fn).parameters.keys())
except (ValueError, TypeError):
params = []
if params and params[0] in ("self", "cls"):
fn_name = getattr(fn, "__name__", "function")
raise TypeError(
f"The function '{fn_name}' has '{params[0]}' as its first parameter. "
f"Use the standalone @prompt decorator and register the bound method:\n\n"
f" from fastmcp.prompts import prompt\n\n"View on GitHub (pinned to 1f02114297)
Solutions
- Put `@classmethod` above `@prompt` (classmethod outermost) if using the standalone decorator
- Prefer the documented pattern: decorate with standalone `@prompt` inside the class, then register the bound method via `mcp.add_prompt(obj.my_prompt)`
- Make the method a regular method or staticmethod if class access isn't required
Example fix
// before
class C:
@provider.prompt
@classmethod
def p(cls, x): ...
// after
class C:
@classmethod
@prompt
def p(cls, x): ...
obj = C()
mcp.add_prompt(obj.p) Defensive patterns
Strategy: validation
Validate before calling
import inspect
if isinstance(fn, classmethod):
raise TypeError('reorder decorators: @classmethod above @prompt') Type guard
def decorable(fn) -> bool:
import inspect
return inspect.isroutine(fn) and not isinstance(fn, classmethod) Try / catch
try:
provider.prompt(fn)
except TypeError as e:
if 'classmethod' in str(e): use_bound_method_pattern() Prevention
- Order decorators outermost-first: @classmethod then @prompt
- Register bound methods after instantiation instead of decorating in the class body
- Prefer staticmethods or plain functions for prompts
When it happens
Trigger: Writing `@provider.prompt` above `@classmethod` (so the decorator receives the classmethod object), or calling `provider.prompt(classmethod(SomeClass.method))`.
Common situations: Decorating methods inside classes with the provider-scoped decorator; reordering decorators after refactoring; following old examples that stacked `@prompt` with `@classmethod`.
Related errors
- The function '{fn_name}' has '{params[0]}' as its first para
- Cannot specify both a name as first argument and as keyword
- Invalid first argument: {type(name_or_fn)}
- To decorate a classmethod, use @classmethod above @tool. See
- messages[{i}] must be Message, got {type(item).__name__}. Us
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/1dfeec910efd1605.
Report an issue: GitHub.