PrefectHQ/fastmcp · error · ValueError

MethodBinding cannot bind spec method {self.method!r}; exten

Error message

MethodBinding cannot bind spec method {self.method!r}; extension methods are additive. Use ServerExtension.intercept_tool_call or FastMCP middleware to wrap core behaviour.

What it means

MethodBinding is for additive extension methods only. Its __post_init__ rejects any method name found in SPEC_CLIENT_METHODS (methods defined by the MCP specification, e.g. 'tools/call', 'sampling/createMessage') because rebinding spec methods would replace core protocol behavior rather than add to it. The error directs you to ServerExtension.intercept_tool_call or FastMCP middleware for wrapping core behavior.

Source

Thrown at fastmcp_slim/fastmcp/server/extensions.py:99

    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.
    """

    method: str
    params_type: type[BaseModel]
    handler: ExtensionRequestHandler
    protocol_versions: frozenset[str] | None = None

    def __post_init__(self) -> None:
        if self.method in SPEC_CLIENT_METHODS:
            raise ValueError(
                f"MethodBinding cannot bind spec method {self.method!r}; extension "
                "methods are additive. Use ServerExtension.intercept_tool_call or "
                "FastMCP middleware to wrap core behaviour."
            )
        if self.protocol_versions is not None and not self.protocol_versions:
            raise ValueError(
                f"MethodBinding for {self.method!r} has an empty protocol_versions "
                "set, so it could never be served; use None to admit every version."
            )


class 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

View on GitHub (pinned to 1f02114297)

Solutions

  1. Rename your extension method to a non-spec, additive method name.
  2. If the goal is to wrap core tool behavior, use ServerExtension.intercept_tool_call instead of MethodBinding.
  3. Use FastMCP middleware to intercept or modify core request handling.
  4. Check SPEC_CLIENT_METHODS to confirm your method name does not collide with the MCP spec.

Example fix

// before
binding = MethodBinding(method="tools/call", handler=my_handler, params_type=CallToolRequestParams)
// after
binding = MethodBinding(method="myextension/audit_tool", handler=my_handler, params_type=MyParams)  # or use ServerExtension.intercept_tool_call
Defensive patterns

Strategy: validation

Validate before calling

from fastmcp.server.extensions import SPEC_CLIENT_METHODS
assert binding.method not in SPEC_CLIENT_METHODS, f"{binding.method!r} is a spec method"

Type guard

def is_additive_method(name: str) -> bool:
    return name not in SPEC_CLIENT_METHODS

Try / catch

try:
    binding = MethodBinding(method=name, handler=h, params_type=P)
except ValueError:
    binding = None  # fall back to ServerExtension.intercept_tool_call

Prevention

When it happens

Trigger: Constructing MethodBinding(method=<a spec client method name>, handler=..., params_type=...) directly, or registering an extension whose handler method collides with a spec method name.

Common situations: Developers trying to override built-in MCP behavior (e.g. intercept tools/call) via the extension binding API; renaming/refactoring that accidentally reused a spec method string.

Related errors


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