{"record":{"id":"1dfeec910efd1605","repo":"PrefectHQ/fastmcp","slug":"to-decorate-a-classmethod-use-classmethod-above-1dfeec","errorCode":null,"errorMessage":"To decorate a classmethod, use @classmethod above @prompt. See https://gofastmcp.com/servers/prompts#using-with-methods","messagePattern":"To decorate a classmethod, use @classmethod above @prompt\\. See https://gofastmcp\\.com/servers/prompts#using-with-methods","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/providers/local_provider/decorators/prompts.py","lineNumber":156,"sourceCode":"\n        Returns:\n            The registered FunctionPrompt or a decorator function.\n\n        Example:\n            ```python\n            provider = LocalProvider()\n\n            @provider.prompt\n            def analyze(topic: str) -> list:\n                return [{\"role\": \"user\", \"content\": f\"Analyze: {topic}\"}]\n\n            @provider.prompt(\"custom_name\")\n            def my_prompt(data: str) -> list:\n                return [{\"role\": \"user\", \"content\": data}]\n            ```\n        \"\"\"\n        if isinstance(name_or_fn, classmethod):\n            raise TypeError(\n                \"To decorate a classmethod, use @classmethod above @prompt. \"\n                \"See https://gofastmcp.com/servers/prompts#using-with-methods\"\n            )\n\n        def decorate_and_register(\n            fn: AnyFunction, prompt_name: str | None\n        ) -> FunctionPrompt | AnyFunction:\n            # Check for unbound method\n            try:\n                params = list(inspect.signature(fn).parameters.keys())\n            except (ValueError, TypeError):\n                params = []\n            if params and params[0] in (\"self\", \"cls\"):\n                fn_name = getattr(fn, \"__name__\", \"function\")\n                raise TypeError(\n                    f\"The function '{fn_name}' has '{params[0]}' as its first parameter. \"\n                    f\"Use the standalone @prompt decorator and register the bound method:\\n\\n\"\n                    f\"    from fastmcp.prompts import prompt\\n\\n\"","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/providers/local_provider/decorators/prompts.py#L138-L174","documentation":"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.","triggerScenarios":"Writing `@provider.prompt` above `@classmethod` (so the decorator receives the classmethod object), or calling `provider.prompt(classmethod(SomeClass.method))`.","commonSituations":"Decorating methods inside classes with the provider-scoped decorator; reordering decorators after refactoring; following old examples that stacked `@prompt` with `@classmethod`.","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"],"exampleFix":"// before\nclass C:\n    @provider.prompt\n    @classmethod\n    def p(cls, x): ...\n// after\nclass C:\n    @classmethod\n    @prompt\n    def p(cls, x): ...\nobj = C()\nmcp.add_prompt(obj.p)","handlingStrategy":"validation","validationCode":"import inspect\nif isinstance(fn, classmethod):\n    raise TypeError('reorder decorators: @classmethod above @prompt')","typeGuard":"def decorable(fn) -> bool:\n    import inspect\n    return inspect.isroutine(fn) and not isinstance(fn, classmethod)","tryCatchPattern":"try:\n    provider.prompt(fn)\nexcept TypeError as e:\n    if 'classmethod' in str(e): use_bound_method_pattern()","preventionTips":["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"],"tags":["python","classmethod","decorators","prompts"],"backgroundTag":"decorator-order-unsupported","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}