PrefectHQ/fastmcp · error · TypeError

Expected Prompt or @prompt-decorated function, got {type(pro

Error message

Expected Prompt or @prompt-decorated function, got {type(prompt).__name__}. Use @prompt decorator or pass a Prompt instance.

What it means

`add_prompt` accepts either a `Prompt` instance or a function already decorated with `@prompt`. Anything else (a raw undecorated function, a coroutine, a string, a class) hits this TypeError naming the offending type.

Source

Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/decorators/prompts.py:60

            from fastmcp.decorators import get_fastmcp_meta
            from fastmcp.prompts.function_prompt import PromptMeta

            meta = get_fastmcp_meta(prompt)
            if meta is not None and isinstance(meta, PromptMeta):
                enabled = meta.enabled
                prompt = Prompt.from_function(
                    prompt,
                    name=meta.name,
                    version=meta.version,
                    title=meta.title,
                    description=meta.description,
                    icons=meta.icons,
                    tags=meta.tags,
                    meta=meta.meta,
                    auth=meta.auth,
                )
            else:
                raise TypeError(
                    f"Expected Prompt or @prompt-decorated function, got {type(prompt).__name__}. "
                    "Use @prompt decorator or pass a Prompt instance."
                )
        self._add_component(prompt)
        if not enabled:
            self.disable(keys={prompt.key})
        return prompt

    @overload
    def prompt(
        self: LocalProvider,
        name_or_fn: F,
        *,
        name: str | None = None,
        version: str | int | None = None,
        title: str | None = None,
        description: str | None = None,
        icons: list[mcp_types.Icon] | None = None,

View on GitHub (pinned to 1f02114297)

Solutions

  1. Decorate the function with `@prompt` before passing it: `add_prompt(prompt(my_fn))` or `mcp.prompt(my_fn)`
  2. Pass a `Prompt` instance (`Prompt(name=..., fn=...)`) instead of a raw callable
  3. Check you didn't call the decorator: use `@prompt`, not `@prompt()` above the def, or `prompt` not `prompt()` when wrapping manually

Example fix

// before
mcp.add_prompt(get_greeting)  # raw function
// after
from fastmcp.prompts import prompt
mcp.add_prompt(prompt(get_greeting))
Defensive patterns

Strategy: type-guard

Validate before calling

from fastmcp.prompts import Prompt
if not isinstance(obj, Prompt) and not callable(obj):
    raise ValueError('add_prompt needs a Prompt or @prompt-decorated function')

Type guard

def is_prompt_like(x) -> bool:
    from fastmcp.prompts import Prompt
    return isinstance(x, Prompt) or (callable(x) and getattr(x, '__fastmcp__', None) is not None)

Try / catch

try:
    mcp.add_prompt(obj)
except TypeError as e:
    if 'Expected Prompt' in str(e):
        mcp.add_prompt(prompt(obj))

Prevention

When it happens

Trigger: Calling `provider.add_prompt(my_fn)` on a plain function that was never wrapped by `@prompt`; passing the result of a called decorator (`@prompt()` misuse); passing a non-prompt object like a Tool.

Common situations: Migrating from older FastMCP APIs where raw functions were accepted; confusion between `@prompt` and `@prompt()`; copy-paste from tool examples into prompt registration.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/d319c70c7be84bd8. Report an issue: GitHub.