PrefectHQ/fastmcp · error

resource_uri cannot be set on resources — the resource itsel

Error message

resource_uri cannot be set on resources — the resource itself is the UI. Use resource_uri on tools to point to a UI resource.

What it means

The @mcp.resource decorator rejects an AppConfig that sets resource_uri, because a resource already IS the UI surface — resource_uri only makes sense on tools that point at a UI resource. This is a configuration-time validation error (ValueError).

Source

Thrown at fastmcp_slim/fastmcp/server/server.py:2055

                return f"Weather for {city}: {data}"
            ```
        """
        # Catch incorrect decorator usage early (before any processing)
        if not isinstance(uri, str):
            raise TypeError(
                "The @resource decorator was used incorrectly. "
                "It requires a URI as the first argument. "
                "Use @resource('uri') instead of @resource"
            )

        # Apply default MIME type for ui:// scheme resources
        mime_type = resolve_ui_mime_type(uri, mime_type)

        # Validate app config for resources — resource_uri and visibility
        # don't apply since the resource itself is the UI
        if isinstance(app, AppConfig):
            if app.resource_uri is not None:
                raise ValueError(
                    "resource_uri cannot be set on resources — "
                    "the resource itself is the UI. "
                    "Use resource_uri on tools to point to a UI resource."
                )
            if app.visibility is not None:
                raise ValueError(
                    "visibility cannot be set on resources — it only applies to tools."
                )

        # Merge app config into meta["ui"] (wire format) before passing to provider
        if app is not None and app is not False:
            meta = dict(meta) if meta else {}
            if app is True:
                meta["ui"] = True
            else:
                meta["ui"] = app_config_to_meta_dict(app)

        # Delegate to LocalProvider with server-level defaults

View on GitHub (pinned to 1f02114297)

Solutions

  1. Remove resource_uri from the AppConfig used on the resource decorator
  2. If you need a UI entry point, define a tool with resource_uri that points at the resource
  3. Use a separate AppConfig instance for tools vs resources

Example fix

// before
@mcp.resource("ui://panel", app=AppConfig(resource_uri="ui://panel"))
def panel(): ...
// after
@mcp.resource("ui://panel")
def panel(): ...
Defensive patterns

Strategy: validation

Validate before calling

if isinstance(app, AppConfig) and app.resource_uri is not None:
    raise ValueError("resource_uri is tool-only; remove it for resources")

Prevention

When it happens

Trigger: Calling mcp.resource(uri, app=AppConfig(resource_uri="ui://...")) or decorating a resource function with an app config carrying a non-None resource_uri.

Common situations: Copy-pasting an AppConfig from a @mcp.tool definition (where resource_uri is valid) onto a @mcp.resource decorator.

Related errors


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